ES6 Proxy和Reflect是一个蛮有用的组合,这两个属性相辅相成。这篇文章是通过用这两个属性来写一个 简单的常用实例。也通过这个实例来说明Proxy和Reflect几个常用的方法。
Proxy用于修改某些操作的默认行为,等同于在语言层面作出修改,需要一种“元编程”,即对编程语言进行编程。可以理解为对目标对象设置“拦截”层,外界访问该对象必须先通过拦截层。因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy这个词翻译为代理。
let proto = {
set : function(key,value){
console.log(`setting ${key}=${value}`);
}
}
let demo = new Proxy({},proto);
demo.age = 100;//输出“setting age=100”
Reflect对象设计目的有以下几个。
1.将Object对象的一些明显属于语言层面的方法放到Reflect对象上。
Object.defineProperty
Reflect.defineProperty
2.修改某些Object方法的返回结果,让其变得更合理。比如Object.defineProperty(obj, name, desc)在无法定义属性时会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。
原来
try {
Object.defineProperty(obj, name, desc);
// property defined successfully
} catch (e) {
// possible failure (and might accidentally catch the wrong exception)
}
重构后:
if (Reflect.defineProperty(obj, name, desc)) {
// success
} else {
// failure
}
3.让Object操作都编程函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj,name)和Refect.deleteProperty(obj,name)让它们变成了函数行为。
4.Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象找到相应的方法。Proxy是修改对象的行为,而Reflect是获取对象默认行为。
let proto = {
get : function(target,key,receiver){//拦截获值
console.log('getting ${key}!');
return Reflect.get(target, key,receiver);
},
set : function(target, key,value,receiver){//拦截设值
console.log('setting ${key}!');
return Reflect.set(target,key,value,receiver);
},
apply:function(target,thisArg,args){//拦截调用方法
console.log('apply');
return Reflect.apply(target,thisArg,args);
},
construct:function(target,thisArg,proxy){//拦截new
console.log('construct');
return Relect.apply(target,thisArg,proxy);
},
deleteProperty:function(target,key){//拦截删除元素
console.log('delete '+${key});
return Relect.deleteProperty(target,key);
},
enumerate:function(target){//拦截for...in循环
console.log('enumerate')
return Relect.enumerate(target)
},
has(target,key){//隐藏某些属性,不被in操作符发现
if(key[0]==='_'){
console.log('has')
return false;
}
return Relect.has(target,key)
}
}
let demo = new Proxy({},proto);
/*触发方法*/
demo.name;//getting name!
demo.age = 100; //setting age!
demo()//apply
new demo()//construct
delete demo.age //delete age
var p = "asdf";
for(let x in p){}//enumerate;
var q = "_123";
for(let x in q){}//has;
http://blog.csdn.net/rth362147773/article/details/78275551