前端面试复习

1、defer && async

  • 都并行加载,不阻塞html解析渲染
  • defer下载完成之后,待html解析完成之后,DOMContentLoaded之前(读取完之前),按照顺序执行
  • async下载完之后立即执行,不能保证按照script标签顺序执行
  • 如何选择
    脚本之间有顺序依赖时采用defer,否则用async。实际生产中,第三方库打到vendor,pdd基础库打到common,页面打到一个js,是有顺序依赖的,采用defer。

2、原型的理解

  • 实例对象都存在隐式原型__proto__,函数方法存在原型对象prototype,函数作为构造函数来构造实例对象时,实例对象的__proto__会指向构造函数的prototype。
  • 读取对象属性和方法时,当自身不存在时会到prototype中去查找,实现原型对象属性和方法的继承。

3、作用域的理解 -> 变量、函数存储和读取的规则

  • 变量声明,编译器会在当前作用域声明一个变量,并为引擎生成运行时代码,便于引擎后续对该变量进行操作。
  • 作用域读取规则:引擎执行代码到对某一变量的操作时,会询问当前作用域中是否存在,存在则使用,否则到上层作用域查找,直到查找到为止,到全局作用域还未找到则抛错。

4、http协议
5、同源策略,跨域、跨站

  • 浏览器安全策略
  • access-control-allow-origin 告诉浏览器哪个域允许;access-control-allow-credential 告诉浏览器是否带上cookie

社招面筋一篇
1、typeof原理

  • js在底层存储变量的时候,会在变量的机器码的低位1-3位存储其类型信息,typeof就是通过机器码判断类型

2、浏览器缓存的位置及其区别

  • service worker cache 独立于js主线程之外,可自定义缓存规则
  • memory cache 存储、读取效率高、但空间限制,一般缓存一些小资源文件或内存利用较低时采用,在进程结束时会释放
  • disk cache 存储空间大,读取效率相对慢一些,不会释放
  • 1.对于大文件来说,大概率是不存储在内存中,反之优先 2.当系统内存使用率高的时候,文件优先存到硬盘
  • http/2.0 push cache

3、xss与csrf

  • xss(https://tech.meituan.com/2018...
  • 类型

    • 反射型 -> 将xss代码提交到一个变量,前端直接将变量插入到html;依赖用户输入,用户不输入恶意代码一般没问题,一般发生在搜索框
    • 存储型 -> 攻击者在留言板将恶意代码提交到服务器,服务器持久存储,被攻击者访问都会被注入攻击
    • dom型 -> 当前页面脚本修改dom树,在dom树中引入恶意xss。前端行为,不与服务器交互,服务端无法防御
  • 构造

    • script标签
    • a标签的javascript协议
    • img标签的加载错误回调
  • 防御

    • 输入过滤
    • 数据消毒【实体转义、黑白名单】
  • react底层对于xss的防御
  • csrf

4、axios库理解

  • axios和Axios关系

    • axios是Axios.prototype.request绑定context返回的函数方法,将Axios原型对象上的方法和实例属性都挂到该函数上,功能上实现了Axios实例化;
  • instance和axios

    • axios.create创建出一个axios,和默认axios一样,既可以当函数,又可以当对象去使用
  • 执行流程

    • request -> dispatchRequest -> xhrAdapter
  • 请求响应拦截器
  • axios可以通过new Axios实列的形式使用,原理是什么?

    • axios是一个Axios原型对象中的request方法绑定一个实例对象的函数,并且将Axios类的所有实例属性和方法绑定到了该函数对象上,axios调用本质及调用了Axios类的实例方法,只不过扩展了使用,axios既可以当做函数也可以当做对象使用
    • 直接new一个Axios对象也可以通过对象调用请求方法,只不过不能作为函数使用

5、防抖 && 节流

  • 防抖(返回新的函数,该函数一段时间内不再触发则执行原函数,否则刷新定时器)
  • 节流(返回新的函数,该函数在一段时间内连续触发只执行第一次)

      // 防抖实现:
      function debounce(fn, delay) {
          var timer = null;
    
          return function () {
              if (timer) {
                  clearTimeout(timer);
              }
    
              timer = setTimeout(() => {
                  fn.apply(this, arguments);
              }, delay)
          }
      }
    
      // 节流 - 时间戳实现
      function throttle(fn, interval) {
          var start = 0;
    
          return function() {
              if(Date.now() - start < interval) {
                  return;
              }
              
              var result = fn.apply(this, arguments);
              start = Date.now();
              return result;
          }
      }
    
      // 节流 - 定时器版本
      function throttle(fn, interval) {
          var timer = null;
    
          return function() {
              // 当前定时器不存在,重新触发时新起一个定时器
              if (!timer) {
                  timer = setTimeout(() => {
                      fn.apply(this, arguments);
                      timer = null;
                  }, interval);
              }
          }
      }
    

6、手写快排
7、手写event emitter

  • 实现思路:
    class EventEmitter {
    constructor() {

      this.eventBus = {};

    }

    subscribe(event, callback) {

      if(!this.eventBus[event]) {
          this.eventBus[event] = [];
      }
      this.eventBus[event].push(callback);

    }

    emit(event, ...rest) {

      this.eventBus[event].forEach(cb => {
          cb.apply(this, rest);
      });

    }
    }

8、http/1.1 与 http/2.0的区别

  • http/0.9 请求行 仅支持get
  • http/1.0 http版本 请求/响应头 connection:keep-alive需要手动设置实现连接复用
  • http/1.1 默认支持连接复用,支持管道机制同时发送多个请求,但只能逐个回应,存在“队头阻塞问题”,content-length,流传输transfer-encoding
  • http/2.0 多工通信(双向的、实时的通信)、数据流(响应ID,数据流id)、头信息压缩(压缩、索引表索引代替)、服务器推送

你可能感兴趣的:(javascript前端)