在 MVVM 当中,数组被Observe类从新定义,当数组发生变化时,会将与数组相关联的VNode进行重新编译加载。这里提供两种实现思路:
第一种,使用自定义方法覆盖原型方法
const arr= new Observe() //此时arr为一个空数组
arr.push(1)
/*此时会调用Observe 中push方法,返回一个Array原型链上的push方法,
这里call(this)的作用是用于继承Array 指向,使得在Observe 内能够调用原型链方法*/
class Observe extends Array {
constructor() {
super();
}
push(...args) {
console.log('push');
return Array.prototype.push.call(this, ...args);
}
pop() {
console.log('pop');
return Array.prototype.pop.call(this);
}
shift() {
console.log('shift');
return Array.prototype.shift.call(this);
}
unshift(...arg) {
console.log('unshift');
return Array.prototype.unshift.call(this, ...arg);
}
splice(index, target, ...res) {
console.log('splice');
return Array.prototype.splice.call(this, index, target, ...res);
}
sort(cb) {
console.log('sort');
return Array.prototype.sort.call(this, cb);
}
reverse() {
console.log('reverse');
return Array.prototype.reverse.call(this);
}
}
第二种,在构造时使用defineProperty对数组函数进行劫持,返回原型链同名函数,这样做的好处是不需要再执行时再传入参数
class ObserverableArray extends Array {
constructor(){
super()
let arrMethodsName = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];
let that =this
arrMethodsName.forEach(function(method, index) {
Object.defineProperty(that,method,{
get(){
console.log(method)
//此处返回函数定义,由于只是劫持,没有执行,所以不需要再调用call
return Array.prototype[method]
}
})
})
}
}
网友评论