Proxy用于拦截对元素的行为。类似于class种的set和get,有多达13种方式。
简单例子:
监听取值行为
let a = new Proxy({},{
get:(t,p)=>{
return 35;
}
})
console.log(a.name);
// 35
如果里面什么都不写,会直接指向该对象。
let b = new Proxy({},{
// 如果里面什么都不写,等于直接指向该对象
})
b["a"] = "aaa"
console.log(b["a"]);
看到这里,你可能有点懵逼,我再把例子写简单点。
let a = new Proxy({},{
get:(t,p)=>{
// t 指a对象本身
// p 指访问的属性
if(p="name"){
console.log(123);
}
}
})
//当name被访问的时候 打出123
a.name
然后你此刻必定恍然大悟,卧槽!原来如此。
但是,如果只能实现一个get,那他跟class里面get和set就没区别了呀!
是的,这函数最牛逼的地方在于,他能监听13种操作。。比class里面的get和set牛逼太多了。。
再来一个,假定我们要删除某个属性值:
注意:我们是拦截删除操作,如果你真要删除,你还是得再方法里执行delete..
let obj = {
num:123,
brs:22222
};
let arrp = new Proxy(obj,{
deleteProperty(t,k) {
console.log(k);
if(k=="brs"){
console.log("你无法删除brs");
return false;
}
// 执行删除操作
delete t[k]
// 必须返回一个值
return true;
}
})
// 正常删除 因为返回true
console.log(arrp.num);
delete arrp.num
console.log(arrp.num);
console.log(arrp.brs);
delete arrp.brs // 如果你尝试删除brs就会报错
console.log(arrp.brs);
这是因为我们设置了阻挡删除 才报得错,这是正常的。
他总共可以拦截13种操作: 使用的方式都大同小异。
方法 | 作用 |
---|---|
get(target, propKey, receiver) | 拦截对象属性的读取,比如proxy.foo和proxy['foo'] |
set(target, propKey, value, receiver) | 拦截对象属性的设置,比如proxy.foo = v或proxy['foo'] = v,返回一个布尔值。 |
has(target, propKey) | 拦截propKey in proxy的操作,返回一个布尔值。 |
deleteProperty(target, propKey) | 拦截delete proxy[propKey]的操作,返回一个布尔值。 |
ownKeys(target) | 拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。 |
getOwnPropertyDescriptor(target, propKey) | 拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。 |
defineProperty(target, propKey, propDesc) | 拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。 |
preventExtensions(target) | 拦截Object.preventExtensions(proxy),返回一个布尔值。 |
getPrototypeOf(target) | 拦截Object.getPrototypeOf(proxy),返回一个对象。 |
isExtensible(target) | 拦截Object.isExtensible(proxy),返回一个布尔值。 |
setPrototypeOf(target, proto) | 拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。 |
apply(target, object, args) | 拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。 |
construct(target, args) | 拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。 |