Proxy
介绍
Proxy 是 ES6 新增的一个对象,用于创建一个代理对象,从而控制对目标对象的操作。理解为在目标对象之前设置一个“拦截层”,外界对该对象的访问,都必须先通过这层拦截。
const proxy = new Proxy({}, {
get(target, prop, receiver) {
console.log(`Getting ${prop}`);
return Reflect.get(target, prop, receiver);
},
set(target, prop, value, receiver) {
console.log(`Setting ${prop} to ${value}`);
return Reflect.set(target, prop, value, receiver);
}
});上面的代码对一个空对象进行代理,重新定义了属性的读取(get)和设置(set)行为。当外界对属性进行访问和设置时,就会触发 get 和 set 这层拦截。
如果 handler 没有设置任何拦截,那就等同于直接通向原始对象。
var target = {};
var handler = {};
var proxy = new Proxy(target, handler);
proxy.a = 'b';
target.a // "b"Proxy 实例也可以作为其它对象的原型对象。
创建代理对象
target:目标对象(可以是任何类型的对象,包括原生数组、函数、甚至另一个代理)。handler:一个对象,其属性是当执行操作时定义代理的行为的函数。
ProxyUser 对象使用 user 对象来存储数据。proxyUser 可以访问 user 对象的所有属性。
通过 proxyUser 对象访问 user 对象的属性时,handler 对象的 get 方法会被调用。
如果修改原始对象 user,更改会反映在 proxyUser 对象上。
proxyUser 对象的更改也会反映在原始对象 user 上。
静态方法
this
虽然 Proxy 可以代理针对目标对象的访问,但它不是目标对象的透明代理,即在不做任何拦截的情况下,也无法保证与目标对象的行为一直。在 Proxy 代理的情况下,目标对象内部的 this 关键字会指向 Proxy 代理。
上面代码中, proxy 代理了 user.equals 方法,后者内部的 this 关键字指向的是 proxyUser 对象,而不是 user 对象。
下面是一个例子,由于 this 指向的变化,导致 Proxy 无法代理目标对象。
上面代码中,目标对象 jane 的 name 属性,实际保存在外部 WeakMap 对象 _name 上面,通过 this 键区分。由于通过 proxy.name 访问时,this 指向 proxy,导致无法取到值,所以返回 undefined。
此外,有些原生对象的内部属性,只有通过正确的 this 才能拿到,所以 Proxy 也无法代理这些原生对象的属性。
上面代码中,getDate()方法只能在 Date 对象实例上面拿到,如果 this 不是 Date 对象实例就会报错。这时,this 绑定原始对象,就可以解决这个问题。
最后更新于
这有帮助吗?