Proxy如其名, 它的作用是在对象和和对象的属性值之间设置一个代理,获取该对象的值或者设置该对象的值, 以及实例化等等多种操作, 都会被拦截住, 经过这一层我们可以统一处理,我们可以认为它就是“代理器” 。
let obj = new Proxy(target, handler);
Proxy是一个构造函数, 使用new Proxy创建代理器, 它的第一个参数target
是要包装的目标对象Proxy。它可以是任何类型的对象,包括本机数组,函数或甚至另一个代理,第二个参数handler
也为一个对象, 返回被包裹后的代理器。举个例子:
//被代理的对象
let item = {
userName:'don',
age:18
}
//代理对象
let proxyItem = new Proxy(item, {
get : function( target , prop ) {
console.log("我要获取值了");
return target[prop];
},
set : function( target, prop, value) {
console.log("我要设置值了");
target[prop] = value;
return true
}
});
obj.userName = 'alice'; // 我要设置值了
console.log(obj.age) ; // 我要获取值了
属性检验
let product = {
productPrice: 200
};
let obj = new Proxy(product, {
set: function (target, key, value) {
if(value<100){
throw new RangeError('价格太低了');
}else if(value>300){
throw new RangeError('价格太高了');
}
target[key] = value;
return true
}
});
obj.productPrice = 301; // RangeError 价格太高了
obj.productPrice = 99; // RangeError 价格太低了
obj.productPrice = 120;
要修改item
的时候会进入代理对象的get
或者set
进行检验,来控制是否可以读取属性,如果不满足条件就抛出错误,只有验证通过了才设置到对象上。
let product = {
productPrice:200
};
let obj = new Proxy(product, {});
obj.productPrice = 300;
console.log(obj) // { productPrice:300 }
console.log(product) // { productPrice:300 }
如果没有给Proxy
设置get
或者set
,这就相当于没有设置过这个代理。
设置多个proxy
let product = {
productPrice:200
};
let productProxy1 = new Proxy(product, {
set:function(target,key,value){
if(value < 100){
throw new RangeError("价格太低了")
}
target[key] = value;
return true;
}
});
let productProxy2 = new Proxy(product,{
set:function(target,key,value){
if(value>300){
throw new RangeError("价格太高了")
}
target[key] = value;
return true;
}
})
productProxy1.productPrice = 102;
productProxy2.productPrice = 14;
console.log(product) //{ productPrice:14 }
一个对象支持同时设置多个proxy
,不同的proxy
只对自己的验证条件有效。比如上例中的productProxy1
,它会检验修改的productPrice
是否小于100,修改完进入productProxy2
验证,productProxy2
只验证是否大于300,这时传入的14,满足productProxy2
,验证通过。但是productProxy1
之前的检验就失效了,所以多个proxy
验证的时候要注意这个问题。
第二个参数
Proxy
的第二个参数为一个对象, 对象的参数为以下的列表, Proxy
提供了更多的接口 , 通过不同的参数, 我们可以截获代码的运行并重新处理。参考链接
- handler.getPrototypeOf()
- handler.setPrototypeOf()
- handler.isExtensible()
- handler.preventExtensions()
- handler.getOwnPropertyDescriptor()
- handler.defineProperty()
- handler.has()
- handler.get()
- handler.set()
- handler.deleteProperty()
- handler.ownKeys()
- handler.apply()
- handler.construct()
网友评论