劫持方法的文件 observer/index.js
import { ArrayMethods } from './arr';
export function observer(data) {
if(typeof data != 'object' || data == null ) {
return data;
}
return new Observer(data);
}
class Observer {
constructor(value) {
if(Array.isArray(value)) {
value.__proto__ = ArrayMethods;
}else {
this.walk(value);
}
}
walk(data) {
let keys = Object.keys(data);
for(let i = 0; i < keys.length; i++) {
let key = keys[i];
let value = data[key];
defineReactive(data, key, value);
}
}
}
function defineReactive(data, key, value) {
observer(value);
Object.defineProperty(data, key, {
get() {
return value;
},
set(newValue) {
if(newValue === value) return value;
observer(value);
value = newValue;
}
})
}
数组劫持文件 observe/arr.js
let oldArrayProtoMethods = Array.prototype;
export let ArrayMethods = Object.create(oldArrayProtoMethods);
let methods = [
'push',
'pop',
'unshift',
'shift',
'splice',
'reverse',
'sort'
]
methods.forEach(item => {
ArrayMethods[item] = function(...args) {
let result = oldArrayProtoMethods[item].apply(this, args);
return result;
}
})