vm.$nextTick,Eventloop,setTimeout等

参考链接

https://segmentfault.com/a/1190000012861862
https://juejin.im/post/5ba34e54e51d450e5162789b#heading-20

1. 谈谈你对Vue.nextTick的认识

答:官方文档对此解释为:“在下次dom更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的dom。”这个其实很好理解,因为Vuedom是异步更新的,具体步骤如下:(1)当我们在model层修改了数据之后,watcher监听到数据变化,会将dom操作推入事件队列中;(2)等到主线程任务执行完毕之后Vue就会开始执行异步队列中的回调;(3)当dom更新完毕之后执行Vue.nextTick的回调函数,此时视图层已经是最新的dom
该方法一般用在createdmounted钩子函数中,因为mounted不能保证所有子组件已经挂载,所以如果想在上面两个钩子函数中操作dom最好使用Vue.nextTick。另外,可以在函数中修改数据后使用该方法对更新后的dom进行操作。

2.Eventloop

答:Eventloop其实就是JavaScript的运行机制,众所周知JavaScript是单线程语言,当引擎执行代码时,会产生一个执行栈,在执行代码过程中,如果有异步操作,引擎会开启一个队列用来存储异步操作,当执行栈清空之后引擎就会检查异步队列中异步操作的完成情况,如果有完成的就将已完成事件的回调移出队列,进入调用栈并开始执行,然后当调用栈清空之后又去检查异步队列,循环往复,因此被称为Eventloop(事件循环)
但是在ES 6规范中,任务源被分为microtask(微任务)macrotask(宏任务),所以一次正确的事件循环应当是:(1)执行同步代码(宏任务);(2)执行栈请控制后查询是否有微任务需要执行;(3)如果有微任务则执行微任务;(4)必要时需要渲染UI;(5)开始下一轮的事件循环,并开始执行宏任务。所以并不是微任务都比宏任务快,而是时延相等的微任务与宏任务根本不在一次事件循环中。

3. 用setTimeout做倒计时会有误差

答:因为JavaScript毕竟是一门单线程语言,所以有时候当我们用setTimeout设置的delay到了之后可能会受到其他的操作(微任务,UI渲染)等操作所阻滞,所以尽管时间到了回调可能并不会执行。

4. 防抖

答:防抖是为了当一个操作触发的事件回调需要比较大的开销,那么我们可能会将多次操作合为一次操作执行回调,或者只取最新的操作执行回调,当然现在很多第三方JavaScript库都有防抖api可以直接使用,但是如果我们只需要简单的功能,那么我们可以通过setTimeout来实现。
具体思路为:页面操作触发防抖函数,然后函数判断此时timer是否存在,如果已经存在就用setTimeout传入固定的delay(比如50ms),和回调函数返回一个新的timer覆盖掉之前的timer,这样就会使回调总在最后一次事件的delay后执行。

5. 对象深拷贝

答:深拷贝最简单的方法就是JSON.parse(JSON.stringfy(obj)),当然这样的方法有很多弊端,比如对象的属性不能为函数,不能为undefined,不能为symbol等,当然如果我们事先知道对象的内容,我们可以采用这种方法。有很多第三方库可以执行该操作,比如lodash_.cloneDeep()
另外,我说一下自己的想法,个人认为深拷贝就必须返回一个和被拷贝的对象尽可能一样的对象,我们可能需要考虑不仅要拷贝symbol等特殊属性,还要考虑不可枚举属性,另外还要拷贝对象的原型。针对深拷贝我专门写了一篇博客,当然主体思想也是循环遍历复制法,有兴趣的读者可以参考https://www.jianshu.com/p/aa969fa617b3

你可能感兴趣的:(vm.$nextTick,Eventloop,setTimeout等)