array.js:劫持7个方法(push shift unshift pop reverse sort splice),是因为这7个方法会影响视图变化,重写方法方便增加vue中的逻辑。
后续又对push、unshift 、splice这三个方法进行判断,因为这三个方法能够改变length的长度,能新增数据,
比如:在原有的的数组中,数值都被监听 ,新增进去的数字没有被监听,这时候就需要对新增数据进行observe监听。
//主要做的事就是拦截用户调用的push shift unshift pop reverse sort splice
//上述方法可改变原始数组
import { observe } from "./index";
//先获取老的数组方法 只改写这7个方法
let oldArrayProtoMethods = Array.prototype;
console.log(Array.prototype)
//拷贝的一个新的对象 可以查找到老的方法
//arrayMethods里包含的是Array里的所有方法
//export导出的是变量 export default导出的是一个具体的值
export let arrayMethods = Object.create(oldArrayProtoMethods);
let methods = [
'push',
'shift',
'pop',
'unshift',
'reverse',
'sort',
'splice'
]
export function observerArray(inserted){//循环数组一次,对数组中每一项进行观测
for(let i = 0;i<inserted.length;i++){
observe(inserted[i]);
}
}
//遇到methods里定义7个的方法
methods.forEach(method=>{
arrayMethods[method] = function(...args){// 函数劫持 切片编程 ...args把push的值变成数组
//oldArrayProtoMethods指的是Array.prototype
//Array.prototype.push(this) 当前this指的是arrayMethods 把args push到数组中
let r = oldArrayProtoMethods[method].apply(this,args);
let inserted;
switch (method){//只对新增的属性再次进行观察,其他方法没有新增属性
case 'push':
case 'unshift':
inserted = args;
break;
case 'splice':
inserted = args.slice(2);//获取splice新增的内容
default:
break;
}
if(inserted) observerArray(inserted)
console.log('调用了数组更新的方法',r)
this.__ob__.dep.notify();//通知视图更新
return r;
}
})