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