Proxy对象在ECMAScript 2015版本初次引入,在Js社区一直不瘟不火,直到Vue3响应式采用Proxy实现。既然这个玩意这么重要,必须要认真学习一下了。
这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
什么是Proxy
MDN给出了明确的解释:Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
说到代理,有三个部分:
- 被代理的对象,我们称为target
- 处理器对象
- 描述代理细节的对象,我们称为捕获器
我们看一下Proxy的语法:
//p:处理器对象
//target:target
//handler:捕获器
const p = new Proxy(target, handler)
一个简单的例子
var people = {
name:"",
age:12
}
var p = new Proxy(people,{
get: function(obj, prop) {
if(prop === "name" || prop === "age"){
return obj[prop]
}
},
set:function(obj,prop,value){
if(prop === "name"){
if(!isString(value)){
throw "Invalid Value"
}
obj[prop] = value
}else if(prop === 'age'){
if(!isNumber(value)){
throw "Invalid Value"
}
obj[prop] = value
}
}
})
上述代码对people对象作了代理,只能访问name或age属性(其他返回undefined)。对属性修改同样只能修改name或age属性,并且如何数据类型错误则抛出错误。
接下来,我们主要针对handler部分进行介绍说明
handler说明
handler.construct
用于拦截new操作符
function people(name) {
this.name = name;
}
const handler = {
construct(target, args) {
//target为people
console.log("proxy constructor run here")
return new target(...args);
}
};
const proxy = new Proxy(people, handler);
console.log(new proxy('Andrew').name);
上面代码代理了people的constructor的行为。
handler.apply
该方法用于拦截函数的调用。
function sum(a, b) {
return a + b;
}
const handler = {
apply: function(target, thisArg, argumentsList) {
console.log(`Calculate sum: ${argumentsList}`);
return target(argumentsList[0], argumentsList[1]) * 10;
}
};
//将函数的调用扩大十倍: * 10
const proxy = new Proxy(sum, handler);
console.log(sum(1, 2));
// expected output: 3
console.log(proxy(1, 2));
// expected output: 30
handler.set
设置属性值操作的捕获器。
const people = {}
const handler = {
set(target, prop, value) {
//prop为setter的属性
//value为setter的值
}
};
const proxy = new Proxy(people, handler);
proxy.name = "Andrew";//触发set捕获器
handler.get
拦截对象的读取属性操作。
var p = new Proxy(target, {
get: function(target, prop) {
}
});
handler.has
针对 in操作符的代理方法.
const handler = {
has(target, key) {
if (key[0] === '_') {
return false;
}
return key in target;
}
};
const monster = {
_secret: 'easily scared',
eyeCount: 4
};
const proxy = new Proxy(monster, handler);
console.log('eyeCount' in proxy);
// expected output: true
console.log('_secret' in monster);
// expected output: true
console.log('_secret' in proxy);
// expected output: false
先介绍几个最常用的,其他的可以查看MDN关于Proxy对象的介绍
最后
感谢阅读,如有任何问题,欢迎留言讨论