mvvm test3
by keminu
JavaScript
/*
* Object 原型
*/
const OP = Object.prototype;
/*
* 需要重写的数组方法 OAR 是 overrideArrayMethod 的缩写
*/
const OAM = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];
class Mvvm{
constructor(obj, callback){
if(OP.toString.call(obj) !== '[object Object]'){
console.error('This parameter must be an object:' + obj);
}
this.$callback = callback;
this.observe(obj);
}
observe(obj){
// 如果发现 监测的对象是数组的话就要调用 overrideArrayProto 方法
if(OP.toString.call(obj) === '[object Array]'){
this.overrideArrayProto(obj);
}
Object.keys(obj).forEach(function(key, index, keyArray){
var oldVal = obj[key];
Object.defineProperty(obj, key, {
get: function(){
return oldVal;
},
set: (function(newVal){
if(oldVal !== newVal){
if(OP.toString.call(newVal) === '[object Object]' || OP.toString.call(newVal) === '[object Array]'){
this.observe(newVal);
}
this.$callback(newVal, oldVal);
oldVal = newVal;
}
}).bind(this)
});
if(OP.toString.call(obj[key]) === '[object Object]' || OP.toString.call(obj[key]) === '[object Array]'){
this.observe(obj[key]);
}
}, this);
}
overrideArrayProto(array){
// 保存原始 Array 原型
var originalProto = Array.prototype,
// 通过 Object.create 方法创建一个对象,该对象的原型就是Array.prototype
overrideProto = Object.create(Array.prototype),
self = this,
result;
// 遍历要重写的数组方法
Object.keys(OAM).forEach(function(key, index, array){
var method = OAM[index],
oldArray = [];
// 使用...