前端工程师面试题总结
不断学习,持续更新,希望有大佬来指点提携一波,望共勉,一起进步~~
目录
2. 说一说JS数据类型有哪些,有什么区别?
3. 说一说你对闭包的理解?
4. 说一说promise是什么与使用方法?
5. 说一说跨域是什么?如何解决跨域问题?
1. 说一说cookie、sessionStorage、localStorage区别?
首先,cookie、sessionStorage、localStorage都是浏览器存储,都存储在浏览器本地。区别在于:
- Cookie是由服务端写入的,而SessionStorage、LocalStorage都是由前端写入的;
- Cookie的生命周期是由服务器端在写入的时候就设置好的,LocalStorage是写入就一直存在,除非手动清除,SessionStorage是在页面关闭的时候就会自动清除;
- Cookie的存储空间比较小,大概4KB,SessionStorage、LocalStorage存储空间比较大,大概5M;
而且Cookie、SessionStorage、LocalStorage数据共享都遵循同源原则,SessionStorage还限制必须是同一个页面,在前端给后端发送请求的时候会自动携带Cookie中的数据,但是SessionStorage、LocalStorage不会。
加分项:
由于他们的以上区别,所以他们的应用场景也不同,Cookie一般用于存储登录验证信息如SessionID或者token,LocalStorage常用语存储不一变动的数据,减轻服务器的压力,SessionStorage可以用来检测用户是否是属性进入页面,如音乐播放器恢复进度条的功能。
2. 说一说JS数据类型有哪些,有什么区别?
JS数据类型分为两类:
- 一类是基本数据类型,也叫简单数据类型,包含7种类型,分别是Number、String、Boolean、BigInt、Symbol、Null、Undefinrd。
- 另一类是应用数据类型,也叫复杂数据类型,通常用Object代表,普通对象,数组,正则,日期,Math数学函数都属于Object。
数据分为两大类的本质区别:基本数据类型和引用数据类型他们在内存的存储方式不同。
- 基本数据类型是直接存储在栈中的简单数据段,占据空间小,属于被频繁使用的数据;
- 引用数据类型时存储在堆内存中,占据空间打。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址,当解释器寻找引用值时,会检索其在栈中的地址,取得地址后从堆中获得实体。
加分项:
- Symbol是ES6新出的一种数据类型,这种数据类型的特点就是没有重复的数据,可以作为object的key。
- 数据的创建方法Symbol(),因为它的构造函数不够完整,所以不能使用new Symbol()创建数据。
- 由于Symbol()创建数据具有唯一性,所以Symbol()!==Symbol(),同时使用Symbol数据作为key不能使用for获得到这个key,需要使用Object.getOwnPropertySymbols(obj)获得这个obj对象中key类型时Symbol的可以值。
let key = Symbol('key'); let obj = { [key]: 'symbol'}; let keyArray = Object.getOwnPropertySymbols(obj); // 返回一个数组[Symbol('key')] obj[keyArray[0]] // 'symbol'
- BigInt也是ES6新出的一种数据类型,这种数据类型的特点就是数据涵盖的范围大,能够解决超出普通数据类型范围报错的问题。
- 使用方法:整数末尾直接+n:1n;或者调用BigInt()构造函数:BigInt("1")
- 注意BigInt和Number之间不能进行混合操作;
3. 说一说你对闭包的理解?
闭包一个函数和词法环境的引用捆绑在一起,这样的组合就是闭包(closure)。一般就是一个函数A,如return其内部的函数B,被return出去的B函数能够在外部访问A函数内部的变量,这时候就形成了一个B函数的变量背包,A函数执行结束后这个变量背包也就不会被销毁,并且这个变量背包在A函数外部只能通过B函数访问。
- 闭包形成原理:作用域链,当前作用域可以访问上级作用域中的变量;
- 闭包解决的问题:能够让函数作用域中的变量在函数执行结束后不被销毁,同时也能在函数外部可以访问函数内部的局部变量。
- 闭包带来的问题:由于垃圾回收器不会将比保重变量销毁,于是就造成了北村泄露,内存泄露积累多了就容易导致内存溢出。
加分回答:
- 闭包的应用:模块化的导出引入、防抖节流,能够模仿块级作用域,在构造函数中定义特权方法,Vue中数据响应式Observer中使用闭包等。
4. 说一说promise是什么与使用方法?
- Promise的概念:异步编程的一种解决方案,解决了地狱回调的问题;
- Promise的使用场景:异步请求、可读性高的场景、处理多并发 。
- Promise的使用方法:用来进行异步编程,通过.then进行链式调用,总共三个状态:pendding:等待响应:,resolved:成功的放回,rejected:失败的返回,书写错误时的返回。无论什么情况都会返回个状态要么成功要么失败。
- Promise的作用:Promise是异步微任务,解决了异步多层嵌套回调的问题,让代码的可读性更高,更容易维护;
- Promise的使用:Promise是ES6提供的一个构造函数,可以使用Promise构造函数new一个实例,Promise构造函数接受一个函数作为参数,这个函数有两个参数,分别是两个函数“resolve”和“reject”,“resolve”将Promise的状态有等待变为成功,将异步操作的结果作为参数传递过去。“reject”则将状态有等待转变为失败,在异步操作失败时调用,将异步操作报出的错误作为参数传递过去。实例穿件完成后,可以使用“then”方法分别指定成功或失败的回调函数,也可以使用catch捕获失败,then和catch最终返回的也是一个Promise,所以可以链式使用;
- Promise的特点:
- 对象的状态不受外界影响(Promise对象代表一个异步操作,有三种状态):-pending(执行中)-Resolved(成功,又称Fulfilled)-rejected(拒绝),其中pending为初始状态,fildilled和rejected为结束状态(结束状态标识promise的生命周期已结束);
- 一旦状态改变,就不会在变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能(状态凝固了,就不会在变了,会一直保持这个结果):从Pending变为Resolved,从Pending变为Rejected;
- resolve方法的参数是then中回调函数的参数,reject方法中的参数是catch中的参数;
- then方法和catch方法只有不报错,返回的都是一个fullfilled状态的promise;
- 加分项:Promise的其他方法:
- Promise.resolve():返回的Promise对象状态为fullfilled,并且将改value传递给对应的then方法;
- Promise.reject():返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法;
- Promise.all():返回一个新的promise对象,该promise对象在参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发改promise对象的失败;
- Promise.any():接受一个Promise对象的集合,当其中的一个promise成功,则返回那个成功的promise的值;
- Promise.race():当参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参考调用父promise绑定的相应句柄,并返回该promise对象;
5. 说一说跨域是什么?如何解决跨域问题?
- 跨域:当前页面中的某个接口请求的地址和当前页面的地址如果协议、域名、端口其中有一项不同,就说改接口跨域了;
- 跨域限制的原因:浏览器为了保证网页的安全,出的同源同源协议策略;
- 跨域报错信息:
- 跨域解决方案: 跨域一般的解决方法时Jsonp,script标签不受同源策略影响;前端还可以设置代理proxy;后端也可以设置CROS,Access-Control-Allow-Origin;此外还有nginx的反向代理。
- cors:目前最常用的一种解决方法,通过设置后端允许跨域实现。res.setHeader('Access-Control-Allow-Origin','*');res.setHeader("Access-Control-Allow-Methods","GET,PUT,OPTIONS,POST");
- node中间件、nginx反向代理:跨域限制的时候浏览器不能跨域访问服务器,node中间件和nginx反向代理,都是让请求发给代理服务器,静态页面和代理服务器是同源的,然后代理服务器再向后端服务器发请求,服务器和服务器之间不存在同源限制;
- JSONP:利用的原理是script标签跨域跨域请求资源,将回调函数作为参数拼接在url中。后端收到请求,调用该回调函数,并将数据作为参数返回去,注意设置响应头返回文件类型,应该设置成javascript;
- postmessage:H5新增API,通过发送和接受API实现跨域通信;