自我介绍
大学专业、校园经历、学习途径与方式

学习中印象深刻知识

  1. react 中列表渲染性能优化.
    • 答:通过虚拟列表来实现渲染优化,因为如果都把dom渲染出来,会导致 diff 非常耗时。
    • 实现:将虚拟列表划分成三个部分,上下 缓冲区, 中间 视图区, 剩余部分 虚拟区
      • 试图区:用户能真实看到的部分,真实DOM
      • 缓冲区:防止用户下滑上滑,出现白屏效果
      • 虚拟区:对于用户看不见的区域(除了缓冲区),剩下的区域,不渲染真实DOM。
    • 问:如果用户连续滑动导致多次触发怎么办?如果通过节流函数,用户滑动很快的话会导致位置信息丢失怎么办?
      • 第一问,节流为 onScroll 的回调函数 做节流
      • 第二问(面试官的):通过回调函数内部记录偏移量,然后,当要执行的时候在讲偏移量加上去, 更优质的做法,就是通过scroll.scrollTop 动态计算偏量
  2. requestIdleCallback(react 里面的时间分片机制)、requestAnimationFrame
    • 问:setTimeout 和 setInterval 如果要每五秒执行一个函数,使用哪种实现更好。
      * 通过面试管引导得出,通过 setTimeout 实现会更好,因为,它一次只在宏任务队列添加一个函数,只有该任务执行完后,通过setTimout在设置宏任务。setInterval 每隔五秒就会添加一次,如果之前的任务没有执行完成,也会再次添加宏任务。这样会导致页面卡顿。

问答

  1. 说说你对事件循环的理解

    • 因为 js 是单线程执行,如果没有事件循环(也就是异步操作)。那么,当js执行到 想网络请求和setTimeout 等这样需要等待的操作时,js 就会等待该代码执行完后才继续执行。又因为 js 引擎 和 渲染引擎是互斥的。所以,此时就会导致,页面卡顿,或空白或无法响应用户操作等。因此,引入事件循环,把异步相关代码放到主代码执行完成后执行。
  2. 阐述new 具体执行过程

    • 首先,创建一个空对象,并设置该对象的原型为 prototype。然后 为构造函数绑定this并执行。然后,判断该构造函数的返回值,如果返回的是一个对象则返回这一个对象,如果是原始类型的值,则返回 创建的对象。
  3. 为什么箭头函数不能 new, (this 和 作用域链概念一定要区分, 箭头函数的this,其实是在执行上下文中寻找,并不是通过作用域链)。

    • 因为 箭头函数没有 prototype 属性, 且箭头函数没有this,new 创建对象的时候,会绑定 this。但是箭头函数中却没有this。
  4. 如何实现继承?什么是寄生组合式继承(注意create函数的内部实现)?还有哪些继承方式,它们的优缺点,以及为何最终选用寄生组合式继承。

    • 通过原型链实现继承,主要的方式就是 寄生组合式继承。首先,我们需要在子类中盗用构造函数,来设置属性方法。其次,我们需要通过寄生的方式。创建一个原型为 父类prototype属性的空对象。然后,子类的prototype对象的 constructor 设置为 当前方法。

反问

  1. 公司项目是 vue2.x, 为什么没有考虑迁移到vue3.x。
    • 重点之一,webassembly 只能操作原始对象。不能操作 Proxy 代理对象。
    • 技术选型:其实本应该用 react,因为,前端是从 webassembly 中拿数据,更符合单向数据流的过程。不过vue2.0 的双向绑定。可以让 webassembly js对象数据,进而直接触发画板内容的更新。