ES6 Proxy和Reflect
Proxy 与 Reflect 是 ES6 为了操作对象引入的 API 。Proxy 可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作,在进行这些操作时,可以添加一些需要的额外操作。
Proxy基本用法
proxy,代理,使用代理,我们可以操作对象时,需要先经过代理,才能到达对象,这样就可以起到‘拦截’的作用。
一个例子:
let person = {
name : "Cherry",
age : 18
}
const handler = {
get : (obj,prop) => {
console.log("触发了此方法1");
return obj[prop];
},
set : (obj,prop,value) => {
console.log("触发了此方法2");
obj[prop] = value;
}
}
const proxy = new Proxy(person,handler);
console.log(proxy.name);//Cherry
proxy.age = 20;
console.log(person.age);//20
使用new Proxy方法可以创建代理,该方法接收两个参数,分别是目标对象和代理中间对象。我们可以通过代理的实例对象再对目标对象操作时进行拦截。
has(target, prop) 用于拦截 HasProperty 操作,即在判断 target 对象是否存在 prop 属性时,会被这个方法拦截。此方法不判断一个属性是对象自身的属性,还是继承的属性。此方法不拦截 for ... in 循环。
let person = {
name : "Cherry",
age : 18
}
let handler = {
has : function(obj,prop){
console.log("触发了此方法");
return prop in obj;
}
}
let proxy = new Proxy(person,handler);
console.log('name' in proxy);//true
construct(target, args) 用于拦截 new 命令。返回值必须为对象。
let handler = {
construct : function(obj,args,newTarget){
console.log("触发了此方法");
return Reflect.construct(obj, args, newTarget);
}
}
class Person {
constructor (name) {
this.name = name;
}
}
let PerProxy = new Proxy(Person,handler);
let objProxy = new PerProxy("Cherry");
console.log(objProxy);//{name:"Cherry"}
deleteProperty(target, prop)
拦截 delete 操作,如果这个方法抛出错误或者返回 false ,prop 属性就无法被 delete 命令删除。
defineProperty(target, prop, propDes) 拦截 Object.definePro若目标对象不可扩展,增加目标对象上不存在的属性会报错;若属性不可写或不可配置,则不能改变这些属性。
let handler = {
defineProperty : function(obj,prop,propDes){
obj[prop] = propDes.value;
console.log("触发了此方法");
return true;
}
}
let person = {}
let proxy = new Proxy(person,handler);
proxy.name = "Cherry";
console.log(person.name);//Cherry
Reflect
Reflect 可以用于获取目标对象的行为,它与 Object 类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与 Proxy 是对应的。
Reflect.get(target, name, receiver)方法
let person = {
name : "Cherry",
age : 18
}
console.log(Reflect.get(person,'name'));//Cherry
receiver对象
let person = {
name : "Cherry",
age : 18
}
let receiver = {
name : ""
}
console.log(Reflect.get(person, 'name', receiver)); //Cherry
Reflect.set(target,name,value)
let person = {
name : "Cherry",
age : 18
}
let receiver = {
name : ""
}
Reflect.set(person, 'age', 20); //true
console.log(person.age);//20
Reflect.has(obj, name)
let person = {
name : "Cherry",
age : 18
}
Reflect.has(person, 'name'); // true