1.什么是diff算法?
https://www.bilibili.com/video/BV1JR4y1R7Ln/?spm_id_from=333.337.search-card.all.click&vd_source=0406fa5cf8203ba41f1c8aec5f967e9d
我们修改了文本内容后会生成新的虚拟dom,新旧俩个虚拟dom之间是存在一定差异的,如果能快速找到这俩个对象之间的差异,就可以最小化的更新视图,"diff算法"就是专门用来比对这两个虚拟dom对象的。
diff算法的目的(本质):找出差异,最小化的更新视图。
流程:
当数据改变时,就会触发内部的setter方法,进一步触发dep.notify方法,通知到各数据使用方,执行patch方法,patch方法接收俩个参数(新旧虚拟节点),首先在内部判断一下是不是同类标签,如果不是同类标签那就没有比对的必要了,直接替换就行,如果是同类标签那就执行pacthvnode方法,在这个方法内部也是需要判断一下新旧虚拟节点是否相等,相等的话就直接return,如果不相等那就需要分情况来比对,比对的原则是以新虚拟节点的结果为准;
情况1:
新、旧节点都有文本节点,那直接用新的文本节点来替换就行。
情况2:
旧的没有子节点,新的有子节点,那就直接添加新的子节点就行了。
情况3:
旧的有子节点,新的没有子节点,那就直接删除旧的子节点就行了。
情况4:
新旧都有字节点,那就需要比对他们的子节点(updateChildren)。
updateChildren方法
在该方法中规定了只在同级比对方法,这样可以减少比对次数,最大化的提高比对性能。而且在同级比对中采用的是首尾指针法。
首先旧虚拟节点的oldS和新虚拟节点的newS做比对,如果没有比对成功,那oldS会和newE做比对。如果依旧没有比对成功,就oldE和newS做比对,如果依旧没有比对成功,oldE会和newE做比对。
比对的原则是依照以上顺序依次做比对,当比对成功的,就退出当前比对,渲染结果会以新虚拟节点的结果为准。每次比对成功后,比对成功的start会向右侧移动,end会向左侧移动。在移动的过程中当start跑到end的右侧时九会终止比对。
如果首尾指针法以上4种情况都没有匹配成功的话,则会看新旧虚拟节点的key值,key相同的话就会复用。
2.闭包(closure)
https://www.bilibili.com/video/BV1gM4y1y7bt/?spm_id_from=333.788&vd_source=0406fa5cf8203ba41f1c8aec5f967e9d
将函数内部和外部连接起来的一个桥梁
闭包有2个特点:
1.函数嵌套函数,内部函数引用外部函数变量
2.内部函数可以访问外部函数的变量和参数
闭包有2个作用:
1.防止变量和参数被垃圾回收机制回收(变量持久化)
2.防止变量和参数被外部污染(变量只在闭包内部可访问)
3.实现数据的私有化 ,外面可以用,但没法修改。
闭包风险:
滥用可能会造成内存泄漏
闭包的应用:
1.实现js的模块化
2.封装私有变量
3.防抖和节流
防抖:用户频繁触发某个动作,但是我只想让它最后一次生效(比如用户输入)
节流:比如监听滚动条,控制多久执行一次方法,有固定的一个频率。
闭包一定有return吗?,闭包一定会造成内存泄漏吗?
no
什么时候用到return?
3.什么是原型和原型链?
https://www.bilibili.com/video/BV1LY411d7Yt/?spm_id_from=333.788&vd_source=0406fa5cf8203ba41f1c8aec5f967e9d
原型:
每个函数都有一个prototype属性,称之为原型。
因为这个属性的值是个对象,所以我们也称之为原型对象。
作用:
1.里面存放了一些属性和方法,也就是把我们的属性和方法挂载到原型身上。
2.在js中可以通过原型来实现继承
__proto__:
每个对象都有__proto__属性,这个属性指向它的原型对象。