D3【问答格式】【精简版】每日一练前端

62 阅读2分钟

Q1. 如何判断一个东西是不是数组?

  • Array.isArray()
  • Object.prototype.toString.call()

Q2. 事件委托利用的是什么原理进行实现?

  • 利用的是事件冒泡原理进行实现

Q3. cors跨域原理,前后端需要做什么?

  • 简单的跨域请求时
    • 后端需要设置Access-Control-Allow-Origin这个响应头, 指定允许访问服务端的源
  • 复杂的跨域请求时
    • 比如前端在请求头中带着一个Content-Type的请求,后端需要设置响应头Access-Control-Allow-HeadersContent-Type
  • 当跨域请求需要携带凭证信息时
    • 前端需要设置withCredentials为true
    • 后端需要设置Access-Control-Allow-Credentials为true

Q4. 浏览器缓存策略有哪些,通过什么字段控制的?

  1. 强制缓存,通过Cache-Control控制的,Cache-Control支持多种指令来控制缓存行为,比如max-age来指定缓存的最大有效时间
  2. 协商缓存,通过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对象。