共计 3191 个字符,预计需要花费 8 分钟才能阅读完成。
一、数据类型
根本数据类型
Number,string,Boolean,undefined,null,symbol
援用数据类型
Object(对象)
arr(数组)
function(函数)
Date(日期)
RegExp(正则)
二、事件捕捉,事件冒泡
事件捕捉:最外层的元素最先触发,顺次首次里层元素的事件
事件冒泡:从里层元素最先触发,顺次触发外层元素的事件
三、事件轮询
四、箭头函数指向
this 指向什么?
五、bind,call 的区别
六、数据存储,localstrorage,sessionstorage,cookie 的区别
会诘问登录的时候用户信息的存储问题,登录胜利后会缓存用户的 token+ 工夫戳,通过路由守卫,在路由跳转之前拦挡路由,如果 token+ 工夫戳超过大于以后工夫,阐明 token 还没有生效,能够跳转。否则跳转到登录页从新登录
七、防抖,节流
防抖
触发事件后,在 n 秒内只触发一次,如果在 n 秒内又触发了事件,则事件从新计算
办法一:定时器
const handel= ()=>{console.log(Math.random())
}
const debounce = (fn,wait)=>{
let timeout = null
return function(){clearTimeout(timeout)
timeout = setTimeout(fn,wait)
}
}
window.addEventListener('scroll',debounce(handel,100))
节流
间断触发事件,在 n 秒内只触发一次
const handel= ()=>{console.log(Math.random())
}
const throttle = (fn,delay) => {
let lastTime = 0;
return function (){let nowTime = Date.now();
if(nowTime - lastTime >delay){fn.apply(this)
lastTime = nowTime;
}
}
}
window.addEventListener('scroll',throttle(handel,1000))
八、深拷贝浅拷贝
浅拷贝
拷贝的是内存地址,如果其中一个对象扭转,就会影响其余的对象
实现:Object.assign(targetObj,cloneObje)
只有第一层属性实现了深拷贝,其余还是浅拷贝
扩大运算符,slice,concat 和 assign 一样,都是浅拷贝
深拷贝
在内存中开拓新的内存,存储复制的对象
实现深拷贝的办法:
办法一、循环 + 递归
function deepClone(targetObj,cloneObj){for(key in cloneObj){if((typeof cloneObj[key]) !='object'){targetObj[key] = cloneObj[key]
}
else{targetObj[key] = {};
deepClone(targetObj[key],cloneObj[key])
}
}
return targetObj
}
function isObject(obj){if(((typeof obj) === 'object') || ((typeof obj) === 'function') && obj !=null) {return true} else {return false}
}
function deepClone(obj){if(!isObject(obj)){throw new Error('不是对象')
}
let isArray = Array.isArray(obj)
let cloneObj = isArray?[]:{}
for(let key in obj){cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
}
return cloneObj
}
弊病:只实用于对象和数组
for in 无奈获取 symbol 属性值,Reflect.ownKeys 能够
办法二、JSON.stringify+JSON.parse
JSON.parse(JSON.stringify(obj1))
弊病:拷贝的键值中如果有 undefined,函数,会隐没
办法三、lodash 第三方库有 cloneDeep 办法
九、如何辨别对象和数组
Array.isArray
十、promise async await
promise
(1)三种状态 resolve,reject,pendding
(2)获取 resolve 返回的数据,用 promise.then, 获取 reject 返回的数据,用 promise.catch
Promise 的链式调用, 利用场景:申请逐级依赖
function fun1(){const promise = new Promise((resolve,reject)=>{setTimeout(()=>{resolve(1)
},1000)
})
return promise
}
function fun2(msg){const promise = new Promise((resolve,reject)=>{setTimeout(()=>{
msg++;
resolve(msg)
},1000)
})
return promise
}
function fun3(msg){const promise = new Promise((resolve,reject)=>{setTimeout(()=>{
msg++;
resolve(msg)
},1000)
})
return promise
}
fun1().then(res=>{return fun2(res)
}).then(res=>{return fun3(res)
}).then(res=>{console.log(res);
})
Promise 并发调用
function fun1(){const promise = new Promise((resolve,reject)=>{setTimeout(()=>{resolve(1)
},1000)
})
return promise
}
function fun2(msg){const promise = new Promise((resolve,reject)=>{setTimeout(()=>{
msg++;
console.log('fun2',msg);
resolve(msg)
},1000)
})
return promise
}
function fun3(msg){const promise = new Promise((resolve,reject)=>{setTimeout(()=>{
msg++;
console.log('fun3',msg);
resolve(msg)
},1000)
})
return promise
}
Promise.all([fun1(),fun2(1),fun3(1)]).then(res=>{console.log(res);
})
后果:
async await
await 须要用在带有要害 async 函数中,await 相当于 promise.then
function test(msg){const promise = new Promise ((resolve,reject)=>{setTimeout(()=>{resolve(msg)
},1000)
})
return promise
}
async function fun2(){const data = await test(111)
console.log(data)
console.log(222)
}
后果如下:
then、catch 如何扭转 promise 的状态
十一、宏工作微工作
宏工作:setTimeout setInterval dom 事件 ajax 申请
微工作:promise async awai
同步代码 > 微工作 >dom 渲染 > 宏工作
十二、event loop 事件轮询机制