Q1. 如何判断一个东西是不是数组?
Array.isArray()
Object.prototype.toString.call()
Q2. 事件委托利用的是什么原理进行实现?
Q3. cors跨域原理,前后端需要做什么?
- 简单的跨域请求时
- 后端需要设置
Access-Control-Allow-Origin这个响应头, 指定允许访问服务端的源
- 复杂的跨域请求时
- 比如前端在请求头中带着一个
Content-Type的请求,后端需要设置响应头Access-Control-Allow-Headers为Content-Type
- 当跨域请求需要携带凭证信息时
- 前端需要设置
withCredentials为true
- 后端需要设置
Access-Control-Allow-Credentials为true
Q4. 浏览器缓存策略有哪些,通过什么字段控制的?
- 强制缓存,通过
Cache-Control控制的,Cache-Control支持多种指令来控制缓存行为,比如max-age来指定缓存的最大有效时间
- 协商缓存,通过
Last-Modified或者Etag控制的,Last-Modified:服务器在响应头中返回资源的最后修改时间。浏览器在后续请求中通过 If-Modified-Since 头字段将该时间发送给服务器,服务器可以判断资源是否有更新。如果资源没有更新,服务器会返回 304 Not Modified 状态码,浏览器会使用缓存。ETag:服务器在响应头中返回一个唯一的标识符来标识资源。浏览器在后续请求中通过 If-None-Match 头字段将该标识符发送给服务器。服务器根据标识符判断资源是否有更新,如果没有更新,会返回 304 Not Modified。
Q5. 手撕有重复数字的全排列(permutation)
var permuteUnique = function(nums) {
const res = [];
const backtrack = (dec_space, path) => {
if (dec_space.length === 0) {
res.push(path);
return;
}
for (let i=0; i<dec_space.length; i++) {
if (i > 0 && i !== dec_space.indexOf(dec_space[i]) continue
backtrack([...dec_space.slice(0, i), ...dec_space.slice(i+1)], [...path, dec_space[i]])
}
}
backtrack(nums, []);
return res;
}
Q6. new操作做了什么?
- 首先创建了一个新的空对象
- 然后将空对象的
__proto__指向构造函数的原型
- 然后改变
this的指向,指向这个新建的空对象
- 最后确定构造函数的返回值,一般是返回最开始创建的空对象,但是如果构造函数有返回一个对象时,将返回这个对象。
Q7. Promise.all()用来做什么?
- 是一个用于处理多个异步操作的方法,接受一个包含多个Promise对象的可迭代对象,等待多个异步操作全部完成,然后进行下一步的处理。他会返回一个新的Promise对象。