observer/array.js
import { observe } from './index'
let oldArrayProtoMethods = Array.prototype;
export let newArrayProtoMethods = Object.create(oldArrayProtoMethods);
let methods = ['push','shift','unshift','pop','splice','sort','reverse'];
export function observeArray(insertedElement){
for(let i = 0; i < insertedElement.length;i++){
observe(insertedElement[i]);
}
}
methods.forEach(method =>{
newArrayProtoMethods[method] = function(...args){
let result = oldArrayProtoMethods[method].apply(this,args);
let insertedElement;
switch(method){
case 'push':
case 'unshift':
insertedElement = args;
break;
case 'splice' :
insertedElement = args.slice(2);
default:
break;
}
if(insertedElement){
observeArray(insertedElement);
}
console.log('调用了操作数组方法');
return result;
}
})
observer.js
import { observe } from "./index";
import {newArrayProtoMethods,observeArray} from './array';
export function defineReactive(data,key,value){
observe(value);
Object.defineProperty(data,key,{
get(){
console.log('getter执行');
return value;
},
set(newValue){
if(newValue === value) return;
observe(newValue);
console.log('setter执行');
value = newValue;
}
})
}
class Observer{
constructor(data){
if(Array.isArray(data)){
data.__proto__ = newArrayProtoMethods;
observeArray(data);
}else{
this.walk(data);
}
}
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);
}
}
}
export default Observer;
缺点:无法直接通过下标来操作数组