JS Proxy(代理)简单讲解
前言
Proxy 也就是代理,可以帮助我们完成很多事情,例如对数据的处理,对构造函数的处理,对数据的验证,说白了,就是在我们访问对象前添加了一层拦截,可以过滤很多操作,而这些过滤,由你来定义。
想了解更多请参考 官方文档
语法
let p = new Proxy(target, handler); //创建一个Proxy实例
参数
target:
需要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。handler
:一个对象,其属性是当执行一个操作时定义代理的行为的函数(可以理解为某种触发器)。具体的 handler 相关函数请查阅官网
下面是使用示例,一个简单的代理:
let test = {
name: "小红"
};
let proxyObj = new Proxy(test, {
get(target, key) {
console.log('获取了getter属性');
return target[key];
}
});
console.log(proxyObj.name); // 小红
console.log(proxyObj==test); // false (注意Proxy实例是另一个对象)
控制台显示结果:
上方的案例,我们首先创建了一个test对象,里面有name属性,然后我们使用 Proxy 将其包装起来,再返回给 proxyObj,此时的 proxyObj 已经成为了一个 Proxy 实例,我们对 proxyObj 的操作,都会被 Proxy 拦截。
Proxy 有两个参数,第一个是
咱们再来试试使用 set 来拦截一些操作,并将 get 返回值更改
Proxy 有两个参数,第一个是
target
,也就是我们传入的 test 对象,另一个则是 handler,也就是我们传入的第二个参数,一个匿名对象。在 handler 中定义了一个名叫 get 的函数,当我们获取 proxyObj 的属性时,则会触发此函数。咱们再来试试使用 set 来拦截一些操作,并将 get 返回值更改
let xiaohong = {
name: "小红",
age: 15
};
let proxyObj = new Proxy(xiaohong, {
get(target, key) {
let result = target[key];
//如果是获取 年龄 属性,则添加 岁字
if (key === "age") result += "岁";
return result;
},
set(target, key, value) {
if (key === "age" && typeof value !== "number") {
throw Error("age字段必须为Number类型");
}
return Reflect.set(target, key, value);
}
});
console.log(`我叫${proxyObj.name} 我今年${proxyObj.age}了`);
proxyObj.age = "aa";
控制台显示结果:
上方案例中定义了 proxyObj 对象,其中有 age 和 name 两个字段,我们在 Proxy 中的 get 拦截函数中添加了一个判断,如果是取 age 属性的值,则在后面添加 岁。在 set 拦截函数中判断了如果是更改 age 属性时,类型不是
关于
Number
则抛出错误。最后,正确的输出了我们想要的结果!关于
return Reflect.set(target, key, value);
这句代码,可以用其他方式替换,例如 :let xiaohong = {
name: "小红",
age: 15
};
let proxyObj = new Proxy(xiaohong, {
get(target, key) {
let result = target[key];
//如果是获取 年龄 属性,则添加 岁字
if (key === "age") result += "岁";
return result;
},
set(target, key, value) {
if (key === "age" && typeof value !== "number") {
throw Error("age字段必须为Number类型");
}
// return Reflect.set(target, key, value);
target[key] = value;
}
});
proxyObj.age = 12;
console.log(`我叫${proxyObj.name} 我今年${proxyObj.age}了`);
控制台显示结果:
但是,既然JS为我们提供了
这只是最基础的应用,其他的大家可以自行摸索,都是一样的用法!
Reflect
,那我们肯定是使用它啦,毕竟它和Proxy
本来就是一起玩的,Proxy
有的函数它都有!具体的参考 官方链接这只是最基础的应用,其他的大家可以自行摸索,都是一样的用法!
简单示例:
let xiaohong = {
name: "小红",
age: 15
};
let proxyObj = new Proxy(xiaohong, {});
console.log(proxyObj);
console.log(proxyObj.name);
console.log(proxyObj.age);
控制台显示结果:
其他高深一点的用法参考:https://www.jianshu.com/p/9d8f8782c02d