JS
this
全局:this指向window
函数:this指向window
对象:this指向调用它的
get、post的区别
1、写的地方不同:get在地址栏里 地址栏有多长就只能写多少、post在请求体里 没有上限
2、关于回退和刷新:get回退和刷新没问题 post 会弹窗-是都要重新提交表单
3、get有缓存 post没有
cookie、localstorage、sessionStorage的区别
相同点:都是用来在客户端存储数据的
不同点:
cookie:发一次请求就会携带一次,身上没有方法可以用 要是想用就得自己封装,可以设置过期时间(xss攻击了解一下)
localstorage:持久化存储、只要不手动清除 就一直在
sessionstorage:会话级别的存储 窗口关掉就没有了
localstorage、sessionstorage有一些共有的方法:setItem、getItem、removeItem、clear
深拷贝、浅拷贝的区别
深拷贝:拷贝的是真正的值 会为值开辟地址 一个改变另一个不受影响(JSON.parse(JSON.stringify()))
浅拷贝:拷贝的是地址引用 一个改变 另一个也会变(object.assign)
new都做了什么事情
1、肯定是创建一个新对象
2、把构造函数的原型赋值给新对象
3、把构造函数的this赋值给新对象
4、对return出来的东西做判断处理 如果是简单数据类型 不做处理,如果是复杂数据类型 就直接把return 里的东西返回出来 就表示 new没用啦
call、apply、bind的区别
相同点:都是来改变this指向的
不同点:
1.执行问题
call 和 apply 都是立即执行的 bind的返回值是一个函数 他需要()调用
2.传参问题:
call 、bind 的参数都是一个一个的传进去,apply的第二个参数是个数组 (都放在数组里)
原型和原型链介绍一下
因为在js中是用构造函数来创建对象的,每一个构造函数身上都有一个属性prototype 他的值是一个对象 里面包含了所有可以共享的属性啊 方法啊 这个就叫原型对象
原型链:实例化对象想用某个方法 会先从自身去找 自身没有会去原型上找 原型没有会去原型的原型上 一直找 找到object身上 它的值是个null 从他自身一直到object 连接起来 就是原型链
闭包
内层函数+外层变量(函数套函数)
优点:私有变量、私有函数
px、em、rem
px:绝对像素
em:相对于父元素
rem:相对于根元素
ajax二次封装
一些基本配置、响应拦截器、请求拦截器
数组身上的方法
push:末尾添加
pop:末尾删除
shift:头部删除
unshift:头部添加
reverse:翻转
slice:截取
slice[起始,结尾) 左包右不包
不写参数全部截
-2 从右往左数 左不包右包 截完
0,2:从0到2 从右往左 左不包右包
-3,-1:从右往左 下标从3到1 左不包右包
从下标为3 截完
从下标为1 截完
slice 不改变原数组
splice:两个参数当删除用 三个参数当添加和替换用
splice(开始,结尾) 删除 从下标为1删到3,左包右包 返回删除的东西 改变原数组
splice(开始,结尾,添加的值)
可以多个添加:值依次传入
多个添加:值也可传入数组
toString():数组转字符串
sort():排序(他是按照Unicode码排序的 它的参数是个函数)
concat():合并
join():数组转字符串
valueOf():查数组的所有值
indexOf():查值存在不 存在就返回值对应的下标 不存在就返回-1
查的是值第一次存在的下标
lastIndexOf():查值最后一次出现的位置 有就返回下标 没有就返回-1
forEach():循环 对每一项的值进行操作
map():对每一项的值进行操作
forEach 和 map 区别:
forEach 通过抛出异常的方式跳出循环 通过return跳过当次循环 return 为undefined
map:需要return 对每一项的值进行操作 返回数组中的所有值
filter():过滤器 过滤出来符合条件的
every():每一项都匹配才返回true(不改变原数组)
some():只要有一个匹配就返回true
reduce(上一个的值,和的值,从哪开始):
reduceRight()
includes():判断一个数组是否包含一个指定的值,如果是返回 true,否则false。
Array.from()
find():找符合条件的第一个 找到就返回具体的值 没找到就返回undefined 它的参数是个函数
findIndex()找符合条件的第一个 找到就返回具体的值的下标 没找到就返回-1 它的参数是个函数
字符串身上的方法
split:字符串转数组(不改变原来的)
toUpperCase():字符串小写转大写(不改变原来的)
toLowcase():字符串转小写(不改变原来的)
includes():判断一个字符串是否包含一个指定的值,如果是返回 true,否则false。
startsWith():以某个字符串开头
endsWith():以某个字符串结尾
concat():合并
slice()
substring(start,stop):截取
repeat():字符串复制 2指复制两次。
valueOf()
trim():从一个字符串的两端删除空白字符
对象身上的方法
js中的栈和堆有什么区别?
存储方式:
栈:简单数据类型存在栈里面(基本数据类型变量大小固定,并且操作简单容易,所以把它们放入栈中存储 后进先出原则)
堆:复杂类型的数据存在堆里面(引用类型变量大小不固定,所以把它们分配给堆中,让他们申请空间的时候自己确定大小,这样把它们分开存储能够使得程序运行起来占用的内存最小 无序的键值对。堆的存取方式跟顺序没有关系,不局限出入口。使用key取出value。)
栈内存由于它的特点,所以它的系统效率较高。 堆内存需要分配空间和地址,还要把地址存到栈中,所以效率低于栈。
js和ts的区别
为什么!{}返回false
!遇到非布尔值 他会去做类型转换
{}做类型转换 任何非空对象在转换布尔值时都是true
undefined、null、false、0、''这几个是false
所以!{}是false
正则表达式
es6
新的基本类型
symbol
作用:解决命名冲突的问题(对象的属性名都是字符串 容易造成命名冲突进行覆盖)
他是一个新的数据类型
表示独一无二的值
使用:
Symbol
Symbol.for()
区别:
Symbol.for() 代表如果之前有abc 代表独一无二 要是再来一个表示他们是一样的 因为在此之前已经注册过了
取值:object.getOwnProtypeSymbols(返回的是数组 但他只能拿symbol)
Reflect(可以拿到全部的值 有symbol 有不是symbol的 他也是数组)以后了解一下
Reflect.ownKeys
bigint
let、const、var的区别
相同点:都是用来声明变量的
不同:
var:全局作用域、存在变量提升(等号左边提上去)、可重复声明
let:块级作用域、不存在变量提升、不可重复声明
const:块级作用域、不存在变量提升、不可重复声明、const 声明的变量地址不可以被修改所以相当于是常量、一旦声明必须赋值
解构赋值
模版字符串
箭头函数
箭头函数和普通函数的区别:
没有自己的this 取的是上层作用域的this
没有argument
不可以被当做构造函数用(就是不能用new)
数组新增的方法
filter
foreach
map
array.from:将类数组的对象转成真正的对象
array.of:将一组值转化成数组(Array.of(3, 11, 8) // [3,11,8] )
find()
findIndex()
对象新增的方法
assign:合并
is:严格判断两个值是否相等 判断+0 -0)
keys:拿object的键名
value:拿object的值
class
module
promise 与 async await
相同点:都是用来处理异步请求的
promise:他有三种状态 padding、resolve、reject 他一旦发出 只能等返回结果 不可以干涉结果
他有一些可以用的方法resolve() reject() .then() .catch .finallly .error
Promise.all() ⽅法⽤于将多个Promise 实例,包装成⼀个新的Promise 实例
const p = Promise.all([p1, p2, p3]);
async await 他其实是Generator 的语法糖 返回的就是一个promise
他两的区别就是 async await 同步代码做异步处理 起到一个阻断的作用 等返回出来结果再走后面的 promise 会出现没有返回结果就走后面的东西
原理:
generator
他是个函数 用来解决异步编程的
格式:let a = function* (){
yield
}
next():下一步 相当于promise中的then
WeakMap和Map
WeakMap:
weakmap的值只能是对象
不可遍历
方法不同(只有四个方法能用)
get、set、has、delete
Map:
本质上是键值对的集合 它的key可以是任意内容(数组、数值、对象)
方法:
长度:size
删除:delete、clear
增:set()
查:get()
还可以遍历:
keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回所有成员的遍历器
foreach():遍历map所有的成员
WeakSet和Set
WeakSet
weakset的值只能是对象
不可遍历
方法不同(只有三个方法能用)
add、has、delete
Set
是一种新的数据结构 类似于数组 它的值都是唯一的
是个构造函数 需要new Set()
方法:
长度:size
删除:delete、clear(全删)
增:add()
查:has()
需要注意的一点 set去重是做=== 加类型判断的
还可以遍历:
keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回所有成员的遍历器
foreach():遍历set所有的成员
Vue2
介绍一下生命周期
生命周期指的是组件从创建到销毁的整个过程,分别是创建、挂载、更新、销毁,他们对应了8个钩子函数
beforeCreate:创建之前、页面啥也没干呢 啥也不能干
created:创建之后、data可以用、dom不能动(如果想在这个阶段操作dom可以卸载定时器、promise、异步里)
beforeMount:挂载之前、data可以用、dom不能动(如果想在这个阶段操作dom可以卸载定时器、promise、异步里)
mounted:挂载之后 很成熟 啥都能干
beforeupdate:更新之前 数据是新的 页面是旧的
updated:更新之后 数据和页面都是新的
beforedestory:销毁之前
destory:销毁之后(组件和绑定的东西断开连接了 不能用了)
介绍一下vue2和vue3里面的双向绑定
vue2:object.defineproperty
他是通过把组件里data return 出来的东西赋值给object大对象,object通过object.defineproperty 劫持它的get和set,一旦发生变动 会立即通知vue执行update方法,进行dom节点的更新 从而实现双向绑定。因为他是对属性进行监听 所以它的弊端就是后续添加进来的属性 不可以被监听到($set)
vue3:proxy
他是通过proxy劫持它的get 和set ,他监听的是整个组件大对象 后续添加进来的属性可以劫持到
data为什么要用return?
因为vue讲究的是组件的可复用性 组件每被复用一次 data就会被复制一次,写成函数是为了每复用一次组件就会返回一个新的data 让各个组件独立维护 互不影响。
如果不写成函数 那就相当于不管复用多少次 都用一个data 复用的其中一个组件的data变动就会影响别的组件。
vue组件通信
父 -> 子:props
子-> 父: 父亲传给孩子一个自定义函数,孩子$emit
兄弟:$bus (on 和emit)
vuex:集中式状态管理
vuex包含五部分:
state:用来存储数据的action:做异步处理的
mutation:唯一一个可以改变数据状态的(只能同步 要是不是同步你就不知道这个值他是什么时候修改的)
getter:给数据做加工处理(应该是可以做异步的)
module:模块化
ref是什么
来获取dom的
computed、watch、methods的区别
computed 和 methods区别
相同点:都可以返回东西
不同点:
computed 计算属性 调用一下就会打印返回的结果 但是不管调用几次 只要值不变他就只会打印一次 其他会在缓存里面拿数据
methods 没有缓存 调用几次 执行几次
watch 和 computed 的区别
相同点:都可以用来监听数据
不同点:
watch:值发生变动了才会执行
computed:只要调用就会执行
vuex刷新后数据会丢失吗?怎么解决
vuex是放在运行内存中的 他只要刷新页面肯定是会重新获取数据 页面也会丢失数据
解决:
1.把数据直接保存在爱浏览器缓存里(sessionStorage、cookie、localstorage)
2.页面刷新的时候 再次请求数据 达到可以动态更新的方法
监听浏览器的刷新事件 再刷新之前把数据保存到sessionStorage,刷新成功之后再异步的请求,如果请求到了用vuex 如果没有就去sessionStorage中拿
elementui如何做表单验证的
他有一些方法
1、在表单中加rules属性 然后在data中写校验规则 用props连接
2、内部添加规则 页面里直接rules="[]"
3、自定义函数校验(正则表达式)
Vue3
vue3常用的响应式数据类型
ref:基础类型
reactive:复杂类型
toRef: 解构单一的值 let name = toRef(obj,'name')
toRefs:解构所有的值 let {name age} = toRefs(obj)
vue3常用的api
createApp() :创建一个应用实例
等同于vue2的 new Vue() 写插件封装全局组件会使用
provide/inject :依赖注入
其实就是传值 父组件传后代
directive:自定义指令
像后台管理系统中的按钮权限控制(一个用户拥有某些权限 但是也只能是查看和修改 不能删除)
mixin:混入(可以了解一下hooks )
app.config.globalProperties:获取vue 这个全局对象的属性和方法
自己封装插件的时候需要把方法插入到对象中
nextTick:可以获取到更新后的dom(等下次刷新dom的工具 他返回的是一个promise 回调函数是放在promise中的 所以是异步执行的)
computed:计算属性 有缓存
reactive、ref:做响应式的 类似于vue2中的data
watch:监听
markRaw():不能被new Proxy代理 说白了就是静态数据
defineProps():当前组件使用setup的形式,需要用defineProps接收
defineEmits:当前组件使用setup的形式,需要用defineEmits提交
slot:插槽(匿名、有名 、作用域)
如何用Vue3中setup写法 获取vue2里面的this
因为 setup() 是在解析其它组件选项之前被调用的,所以 setup() 内部的 this 的行为与其它选项中的 this 完全不同。这在和其它选项式 API 一起使用 setup() 时可能会导致混淆。
因此setup函数中不能使用this。所以Vue为了避免我们错误的使用,直接将setup函数中的this修改成了 undefined
所以如果想要在Vue3中使用this, Vue为我们提供了getCurrentInstance()方法,这个方法返回了ctx和proxy。
全局封装了某个方法 需要在某个组建中使用这个属性或者方法就这样整 去获取他
import {getCurrentInstance} from '@vue'
let app = getCurrentInstance()
console.log(app .appContext.app.config.globalProperties.$loading)
vue3用setup写组织代码
mixin:写了一些属性、方法 可以再全局或者某个组件中使用 他是没有template
hooks:他是函数式编程 主要解决的问题是分割代码(模块功能细分 项目维护性更高)
vue2和vue3的区别
双向绑定方法不同:
vue2:object.defineproperty()
vue:new proxy()
$set在vue3没有 因为new proxy()不需要
v-if v-for优先级不同了
v-for与v-if在vue2中优先级高的是v-for指令,而且不建议一起使用
vue3中v-for与v-if,只会把当前v-if当做v-for中的一个判断语句,不会相互冲突
关于写法
vue2选项是api
vue3可以是选项式也可以是setup语法糖
ref与reactive
生命周期
解构 toRef与toRefs
开放性问题
对模块化开发的理解
如何封装和重用代码?有什么考虑?
组件封装
mixin混入
好好想想吧!
描述一下最近完成的项目 以及遇到的难点
项目描述
技术实现
遇到的问题+解决
结果和收获(学会了。。。)
总的来说 哈哈哈
其他
什么是xss攻击? 怎么防止?
xss:黑客会通过在网站注入script脚本 当用户浏览网站的时候 脚本会在它的浏览器中执行 会去获取用户的信息 篡改页面
防止:
输入验证和过滤(只接受正规的输入)
HTTP-only Cookie:禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!再看看
移动端布局的几种方式
- 流式布局(百分比布局)
- flex布局(弹性布局)
- Less+rem+媒体查询布局(实际用flexible.js+rem居多)
- 响应式布局(利用Bootstrap)
- 混合布局,可以根据不同的组件需求,混用不同布局方式,例如全局使用rem适配,部分盒子使用flex布局。
前端接口如何防止重复提交
可以使用token
后端传过来的token前端通过本地存储保存下来 放在http请求的请求头里 后端去判断
再看看!!
跨域
axios二次封装
基础
请求拦截器
响应拦截器
git常用的命令
移动端兼容性的问题
1、当设置样式overflow:scroll / auto ios会卡顿
-webkit-overflow-scrolling:touch
2、在安卓环境下placeholder设置行高时会偏上
input有placeholder 属性的时候不要设置行高
3、移动端字体小于12px时 异常显示
应该先把整体放大一倍 然后再用transform进行缩小
4、ios下input按钮设置了disabled属性为true显示异常
input[type=button]{ opcity:1}
5、安卓手机下取消语音输入按钮
input::-webkit-input-speech-button{
display:none
}
6、ios取消input输入框在输入引文首字母默认大写
<input autocapitalize="off" autocorrect="off">
7、禁用ios和安卓用户选中文字
需要添加全局样式:-webkit-user-select:none
8、禁止ios弹出各种窗口
-webkit-touch-callout:none
9、禁止ios识别长串数字为电话
需要添加meta属性 :<meta conten=‘telephone=no’ name='format-detection'>
10.去掉ios被触摸时产生的半透明灰色遮罩层
-webkit-tap-heighlight-color:rgbaa(0,0,0,0)
js为什么要用事件循环
首先js是单线程的 单线程有一个阻塞的一个问题 浏览器他是通过异步来解决阻塞的问题(settimeout、网络请求)异步是放在队列里面的 异步有一个问题是 他没有优先级 所以为了更灵活一点 增加了事件循环机制
事件循环他有同步任务和异步任务 一般先同步后异步 异步任务有微任务和宏任务 先微任务后宏任务 每执行完一个宏任务 他会去看看微任务队列中有没有微任务 如果有先执行微任务再去执行下一个宏任务
TS
什么是ts
为什么要使用ts? ts相对于js的优势是?
ts中const 和 readonly 的区别?枚举和常量枚举的区别?
ts中any类型的作用是?
ts中的 this 和js 中的this有什么差异?
ts中any、never、 unknow 、null 、undefined 和void有什么区别?
ts中interface1可以给function / array / class做声明吗?
ts可以使用string 、number、 boolean、 symbol、 object等给类型做声明吗?
ts中使用union type时有那些注意事项?
ts如何设计class的声明?
ts如何联合枚举类型的key?
ts中的type 和 interface 的区别?
ts中 ?. 、 ?? 、! 、!. 、_ 、**等符号的含义
介绍一下ts中的模块的加载机制
聊聊你对ts类型兼容性的理解
ts中的对象展开会有什么副作用吗?
类型的全局声明和局部声明
ts中有遇到什么问题吗
React
说说对react的理解
react是用于构建界面的js库 提供了ui层面的解决方案
特性:
单向数据流
组件式开发 可以组合嵌套 复用
高效:对Dom虚拟 不直接操作dom
灵活性:对一直的库或者框架很好的配合
state和props有什么区别?
state: setState修改数据
props:
react创建工程环境(js、ts)
npm create-react-app ReactText 创建js项目
npm create-react-app ReactText --template typescript 创建ts项目
react组件的声明方式
函数式:
import React ,{useState} from 'react'
function A(){
const [num,setNum] = useState(0)
return (
<div>
<span>{num}</span>
<button onClick={()=>setNum(num=>num+1)}></button>
</div>)
}
类组件:
import React ,{Component} from 'react'
class A extend Component{
state={num:0}
handleClick=()=>{
this.setState({
num:this.state.num+1
})
}
render(){
return (<div>{this.state.num} </div>)
}
}
组件传值
父传子:props
子传父:调用一下父亲传过来的自定义函数
兄弟:通过传给父亲 父亲传给兄弟的方法
爷孙:用createContext创建上下文c,c.provider()提供数据 用useContext()拿值
redux:
Redux
状态管理库
跨层级组件数据共享与通信
需要持久化的全局数据:用户登录信息
包含三部分:
store:一个全局的状态管理对象
reducer:一个纯函数 根据旧的state 和props 更新新state
action:改变状态的唯一方法 dispatch action
生命周期
初始化挂载阶段:
constructor :初始化state、截取路由参数 、防抖节流的绑定
getDerivedStateFromProps:静态函数(传入props和state 返回值会合并之前的state作为一个新的state)
render:用于渲染dom结构
compontentDidMount:挂载真实dom到界面上 一般在这个里发请求、开启定时器、订阅消息
更新阶段:
getDerivedStateFromProps:静态方法 不能访问到组件实例(创建或者更新阶段props或者state render方法前调用 )只要state或者props发生变化就调用一下看看是否执行render方法
shouldComponentUpdate:用于告知组件本身对于当前的props和state是否要重新渲染(默认是true)在这里不能深层比较会影响效率 不可以调用setState会死循环
render:
getSnapBeforeUpdate:获取更新之前的信息 (执行的时候dom还没更新)
compontDidUpdate:获取组件更新之后的信息(在组件更新结束后触发 可以获取数据 修改dom样式)
销毁阶段:
componentwillunmount:组件被移除前调用 清理一些注册监听时间 、取消订阅 避免消耗内存
hooks
useState:修改数据状态(更新界面上的数据,它的返回值为状态数据和修改状态的方法)
useContext:组件传值(爷孙) 拿数据
useEffect:处理组件的副作用(模拟一些生命周期、处理一些状态的副作用、请求接口、定时器)
useLayoutEffect:比useEffect时机更提前一些
useReducer:用于管理组件状态(让状态变更更可控)
useCallback:用于缓存函数(返回一个可缓存的函数)
useMemo:用于缓存计算结果(返回一个缓存的值 作为优化的手段)
useRef:用于创建可变的 ref 对象(在组建的生命周期中保持全局不变 一般用来定位一个具体的元素)
useImperativeHandle
useState要使用数组而非对象?
如果 useState 返回数组,那么可以顺便对数组中的变量命名,代码看起来也比较干净
而如果是对象的话返回的值必须和 useState 内部实现返回的对象同名,
这样只能在 function component 中使用一次,想要多次使用 useState 必须得重命名返回值。
Canvas
canvas 是一个标签 他有两个属性width 和 height 可以通过这两个属性去控制大小
<canvas id="canvas "></canvas >
- 2D 拿取上下文(拿到画笔)var canvas = document.getElementById("canvas "); var ctx = canvas.getContext("2d");
- 如果拿不到上下文可以通过getContext 这个方法来判断 :if(canvas.getContext){}else{不支持的兼容处理}
如何画??(坐标系)
- 可以通过beginPath()新建一个画笔 :ctx.beginPath()
- 把画笔移动到起点:ctx.moveTo(100,100)
- 画条直线:ctx.lineTo(200,200)
- 让lineto画的印子有个轮廓:ctx.stroke()
- 画折线:多次lineTo
- 画矩形:ctx.rect(0,0,100,200) 前两个参数是矩形的坐标 后两个参数是矩形的宽高 通过stroke对矩形描边 如果想要实心可以通过fill():ctx.fill() 有个简化的方法:ctx.strokeRect(0,0,100,200)
- ctx.clearRect(50,50,10,100)就相当于画布的一个橡皮擦
- 画圆形:ctx.arc(x,y,r,startAngle,endAngle,anticlockwise) x、y是圆心 r是半径 然后是开始的角度和终止的角度 最后一个是顺时针 默认是false顺时针(角度是弧度制的)
- 添加文本:ctx.fillText(text,x,y[maxWidth]) ctx.strokeText(text,x,y[maxWidth]) 可以设置最大宽度 如果超过最大宽度会被压缩
- fillStyle:设置填充颜色 strokeStyle:轮廓颜色
等等等...................
Grid布局
display:grid
grid-template-columns:1fr 1fr lfr;(也可以是固定宽度 fr是grid 的单位 代表剩余空间)
column-gap:20px(列间距)
row-gap:20px;(行间距)
gap:24;(统一设置行、列间距)
align-item:center;(垂直方向上对齐 end靠下对齐)
justify-item:center;(水平方向上对齐 end靠右对齐 space-between两端对齐)