从ES6的Proxy代办看ES5的代办怎样完成
ES6的Proxy代办
Example
var person = {name:''};
var personCopy = new Proxy(person,{
get(target,key,receiver){
console.log('get要领被阻拦。。。');
return Reflect.get(target,key,receiver);
},
set(target,key,value,receiver){
console.log('set要领被阻拦。。。')
return Reflect.set(target,key,value,receiver);
}
})
person.name = 'arvin'; // 未有阻拦日记打出
personCopy.name = 'arvin'; // set要领被阻拦。。。
console.log(person.name); // 未有阻拦日记打出
console.log(personCopy.name); // get要领被阻拦。。。
代码解读:从上述的例子能够看出,被代办对象person的get和set不会经由代办阻拦器get,set,而只要代办对象personCopy在get和set要领挪用的时刻才会经由阻拦器,因而可知ES6的代办Proxy并非一个相似JAVA的AOP,而实在只是将person的援用赋值给了personCopy,让代办对象personCopy和被代办对象person指向了同一个内存空间,下面是我完成的一个用ES5写的Proxy阻拦,供人人参考明白Proxy完成道理供应思绪:
Example:
/**浅拷贝东西要领**/
function clone(myObj){
if(typeof(myObj) != 'object' || myObj == null) return myObj;
var newObj = new Object();
for(var i in myObj){
newObj[i] = clone(myObj[i]);
}
return newObj;
}
/*代办完成类*/
function ProxyCopy(target,handle){
var targetCopy = clone(target);
Object.keys(targetCopy).forEach(function(key){
Object.defineProperty(targetCopy, key, {
get: function() {
return handle.get && handle.get(target,key);
},
set: function(newVal) {
handle.set && handle.set();
target[key] = newVal;
}
});
})
return targetCopy;
}
var person = {name:''};
var personCopy = new ProxyCopy(person,{
get(target,key){
console.log('get要领被阻拦。。。');
return target[key];
},
set(target,key,value){
console.log('set要领被阻拦。。。')
// return true;
}
})
person.name = 'arvin'; // 未有阻拦日记打出
personCopy.name = 'arvin'; // set要领被阻拦。。。
console.log(person.name); // 未有阻拦日记打出
console.log(personCopy.name); // get要领被阻拦。。。
ES5对Proxy代办的完成
要说到ES5的代办完成,个中比较著名的就算是vue的双向绑定中到了get和set的代办阻拦完成了,下面是一个模仿该手艺的一个完成:
Example
// 阻拦器
function Observer(data) {
this.data = data;
this.walk(data);
}
(function($Observer){
$Observer.prototype = {
walk: function(data) {
var me = this;
Object.keys(data).forEach(function(key) {
me.convert(key, data[key]);
});
},
convert: function(key, val) {
this.defineReactive(this.data, key, val);
},
defineReactive: function(data, key, val) {
var childObj = observe(val);
Object.defineProperty(data, key, {
enumerable: true, // 可罗列
configurable: false, // 不能再define
get: function() {
return val;
},
set: function(newVal) {
if (newVal === val) {
return;
}
val = newVal;
console.log("新的值是object的话,举行监听");
console.log("关照定阅者");
dep.notify();
}
});
}
};
})(Observer);
// 阻拦器的出口
function observe(value) {
if (!value || typeof value !== 'object') {
return;
}
return new Observer(value);
};