1.数据类型基本数据类型Number,string,Boolean,undefined,null,symbolreference数据类型Object(对象)arr(数组)function(函数)Date(日期)RegExp(正则)2.事件捕获,事件冒泡事件捕获:先触发最外层元素,后触发内层元素的第一个事件事件冒泡:先触发内层元素,依次触发外层元素的事件。3.事件轮询4.箭头函数指向this指向什么?5.bind和call的区别6.数据存储、localstorage、sessionstorage、cookie的区别登录时会询问用户信息的存储,登录成功后会缓存用户的token+时间戳,守护bytheroute,在路由跳转之前拦截路由。如果token+时间戳大于当前时间,说明token没有过期,可以跳转。否则,跳转到登录页面,重新登录。7、防抖、节流。防抖事件触发后,n秒内只会触发一次。如果在n秒内再次触发该事件,则重新计算该事件。方法一:定时器consthandel=()=>{console.log(Math.random())}constdebounce=(fn,wait)=>{lettimeout=nullreturnfunction(){clearTimeout(timeout)timeout=setTimeout(fn,wait)}}window.addEventListener('scroll',debounce(handel,100))节流连续触发事件,n秒只触发一次consthandel=()=>{console.log(Math.random())}constthrottle=(fn,delay)=>{让lastTime=0;返回函数(){让nowTime=Date.now();如果(现在时间-上次时间>delay){fn.apply(this)lastTime=nowTime;}}}window.addEventListener('scroll',throttle(handel,1000))八、深拷贝浅拷贝浅拷贝是内存地址,如果其中一个对象改变,会影响其他对象的实现:Object.assign(targetObj,cloneObje)只是对一级属性实现了深拷贝,其他都是浅拷贝扩展操作符,slice、concat、assign都是内存中的浅拷贝和深拷贝,是开辟新内存存储拷贝对象的方法实现深拷贝:方法一、循环+递归函数}else{targetObj[key]={};deepClone(targetObj[key],cloneObj[key])}}returntargetObj}functionisObject(obj){if(((typeofobj)==='object')||((typeofobj)==='function')&&obj!=null){returntrue}else{returnfalse}}functiondeepClone(obj){if(!isObject(obj)){thrownewError('notanobject')}letisArray=Array.isArray(obj)letcloneObj=isArray?[]:{}for(letkeyinobj){cloneObj[key]=isObject(obj[key])?deepClone(obj[key]):obj[key]}returncloneObj}缺点:只适用于对象和数组forin无法获取symbol属性值,Reflect.ownKeys可以方法2,JSON.stringify+JSON.parseJSON.parse(JSON.stringify(obj1))缺点:copied如果键值中有undefined,函数就会消失。方法3.lodash第三方库有cloneDeep方法9.如何区分对象和数组Array.isArray10.promiseasyncawaitpromise(1)三种状态resolve,reject,pending(2)获取resolve返回的数据,使用promise.then,获取reject返回的数据,使用promise.catchPromise的链式调用,应用场景:请求分步依赖函数fun1(){constpromise=newPromise((resolve,reject)=>{setTimeout(()=>{resolve(1)},1000)})returnpromise}functionfun2(msg){constpromise=newPromise((resolve,reject)=>{setTimeout(()=>{msg++;resolve(msg)},1000)})返回承诺}functionfun3(msg){constpromise=newPromise((resolve,reject)=>{setTimeout(()=>{msg++;resolve(msg)},1000)})returnpromise}fun1().then(res=>{returnfun2(res)}).then(res=>{returnfun3(res)}).then(res=>{console.log(res);})Promise并调用functionfun1(){constpromise=newPromise((resolve,reject)=>{setTimeout(()=>{resolve(1)},1000)})returnpromise}functionfun2(msg){constpromise=newPromise((resolve,reject)=>{setTimeout(()=>{msg++;console.log('fun2',msg);resolve(msg)},1000)})returnpromise}functionfun3(msg){constpromise=newPromise((resolve,reject)=>{setTimeout(()=>{消息++;console.log('fun3',msg);resolve(msg)},1000)})returnpromise}Promise.all([fun1(),fun2(1),fun3(1)]).then(res=>{console.log(res);})结果:asyncawaitait需要用在asyncfunctionswithkey,await相当于promise.thenfunctiontest(msg){constpromise=newPromise((resolve,reject)=>{setTimeout(()=>{resolve(msg)},1000)})returnpromise}asyncfunctionfun2(){constdata=awaittest(111)console.log(data)console.log(222)}结果如下:then,catch状态如何改变ofpromise11.宏任务微任务宏任务:setTimeoutsetIntervaldomeventajax请求微任务:promiseasyncawait同步代码>微任务>dom渲染>宏任务12、事件循环当主线程的任务为空后,它将轮询事件队列中的任务。如果它找到一个任务,它就会把这个任务放到主线程中去执行。__prototype__原型链:创建一个构造函数fun1,fun1的实例化对象有一个_proto_属性,指向fun1的原型(prototype)fun1.prtotype=newfun2()fun1的原型有一个原型指向fun2的原型,这样就形成了原型链函数Fun0(){this.a=0;}Fun0.prototype。A='hello'functionFun1(){this.b=1;}Fun1.prototype=newFun0();functionFun2(){this.c=2;}Fun2.prototype=newFun1();constfun2=newFun2();console.log(fun2);JavaScriptnew一个对象的过程14.数组去重,数组排序15.闭包16.普通函数和箭头函数的区别格式普通函数:functiona(){}arrow函数:()=>{}this指向普通函数:dynamic,this指向调用该函数的对象箭头函数:继承父对象的thisnew原型普通函数:可以调用new,有原型箭头函数:不能调用new,没有原型参数普通函数:带参数对象箭头函数:不带参数对象调用apllybind更改指向普通函数:你可以通过上面的方法改变这个指向箭头函数:不可以十七、header中设置跨域jsonp后端:Access-control-allow-origin:*vueproxy.server设置代理服务器十八、cookielocalStoragesessionStorage比较
