发现 j > prevEnd 并且 j <= nextEnd,这说明当新旧 children 中相同的前缀和后缀被更新之后,旧 children 中的节点已经被更新完毕了,而新 children 中仍然有剩余节点,通过上图可以发现,新 children 中的 li-d 节点,就是这个剩余的节点。实际上新 children 中位于 j 到 nextEnd 之间的所有节点都应该是新插入的节点:
const prevStart = j
const nextStart = j
let moved =falselet pos =0// 构建索引表const keyIndex ={}for(let i = nextStart; i <= nextEnd; i++){
keyIndex[nextChildren[i].key]= i
}// 遍历旧 children 的剩余未处理节点for(let i = prevStart; i <= prevEnd; i++){
prevVNode = prevChildren[i]// 通过索引表快速找到新 children 中具有相同 key 的节点的位置const k = keyIndex[prevVNode.key]if(typeof k !=='undefined'){
nextVNode = nextChildren[k]// patch 更新patch(prevVNode, nextVNode, container)// 更新 source 数组
source[k - nextStart]= i
// 判断是否需要移动if(k < pos){
moved =true}else{
pos = k
}}else{// 没找到}}
删除节点
删除未查找到的节点
拿旧 children 中的节点尝试去新 children 中寻找具有相同 key 值的节点,但并非总是能够找得到,当 k === ‘undefined’ 时,说明该节点在新 children 中已经不存在了,这时我们应该将其移除
// 遍历旧 children 的剩余未处理节点for(let i = prevStart; i <= prevEnd; i++){
prevVNode = prevChildren[i]// 通过索引表快速找到新 children 中具有相同 key 的节点的位置const k = keyIndex[prevVNode.key]if(typeof k !=='undefined'){// 省略...}else{// 没找到,说明旧节点在新 children 中已经不存在了,应该移除
container.removeChild(prevVNode.el)}}
删除多余节点
旧 children 中已经更新过的节点数量应该小于新 children 中需要更新的节点数量,一旦更新过的节点数量超过了新 children 中需要更新的节点数量,则说明该节点是多余的节点,我们也应该将其移除
const nextLeft = nextEnd - j +1// 新 children 中剩余未处理节点的数量let patched =0// 遍历旧 children 的剩余未处理节点for(let i = prevStart; i <= prevEnd; i++){
prevVNode = prevChildren[i]if(patched < nextLeft){// 通过索引表快速找到新 children 中具有相同 key 的节点的位置const k = keyIndex[prevVNode.key]if(typeof k !=='undefined'){
nextVNode = nextChildren[k]// patch 更新patch(prevVNode, nextVNode, container)
patched++// 更新 source 数组
source[k - nextStart]= i
// 判断是否需要移动if(k < pos){
moved =true}else{
pos = k
}}else{// 没找到,说明旧节点在新 children 中已经不存在了,应该移除
container.removeChild(prevVNode.el)}}else{// 多余的节点,应该移除
container.removeChild(prevVNode.el)}}
一、final C中增加了final关键字,作用如下:
① 限制某个类不能被继承② 或者某个虚函数不能被重写
① 限制某个类不能被继承
// ① 限制某个类不能被继承,也就是说这个类不能有派生类
class Base{
public:virtual void print() {cout<<"Ba…