Reflect对象和Proxy对象一样,也是ES6为了操作对象而提供的API
Reflect对象的设计目的有以下几个:
1.将Object对象的一些明显属于语言内部的方法 (比如:Object.defineProperty)放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只在Reflect对象上部署,也就是说:从Reflect对象上可以 获得语言内部的方法
2.修改某些Object方法的返回结果,让其变得更合理。(比如:Object.defineProperty(obj,name,desc)在无法定义属性时会抛出一个错误,而Reflect.defineProperty(obj,name,desc)则会返回false)
3.让Object操作都变成函数行为。某些Object操作是命令式。(比如name in obj和delete obj[name],而Reflect.has(obj,name)和Reflect.deleteProperty(obj,name)让他们变成了函数行为)
4.Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法, 、就能在Reflect对象上找到对应的方法。这就使Proxy对象可以方便地调用对应的Reflect方法来完成默认行为,作为修改行为的基础。也就是说,无论Proxy怎么修改默认行为,我们总可以在Reflect上获取默认行为
1和2条的例子
// 旧写法
try{
Object.defineProperty(target,property,attributes);
// success
} catch(e){
// failure
}
// 新写法
if(Reflect.defineProperty(target,property,attributes)){
// success
}else{
// failure
}
3条的例子
// 旧写法
console.log('assign' in Object);
// 新写法
console.log(Reflect.has(Object,'assign'));
4条的例子
const {
set ,
get ,
deleteProperty ,
has
} = Reflect;
Proxy(target,{
set : function(target,name,value,receiver){
let success = set(target,name,value,receiver);
if(success){
log('property ' + name + ' on ' + target + ' set to ' + value);
}
return success;
}
})
代码中,Proxy方法拦截target对象的属性赋值行为。
它采用Reflect.set方法将值赋给对象的属性,确保完成原有的行为,然后再部署额外的功能
let loggedObj = new Proxy(obj,{
get(target,name){
console.log('get',target,name);
return get(target,name);
},
deleteProperty(target,name){
console.log('delete',name);
return deleteProperty(target,name);
},
has(target,name){
console.log('has',name);
return has(target,name);
}
})
上面的代码中,m每一个Proxy对象的拦截操作(get,delete,has)内部都调用对应的Reflect方法,保证原生行为能正常运行,添加的工作就是将每一个操作输出一个日志
有了Reflect对象,很多操作更易读
// 旧写法
console.log(Function.prototype.apply.call(Math.floor,undefined,[1,75]));
// 新写法
console.log(Reflect.apply(Math.floor,undefined,[1,75]));