const obj = {
_name: 'deyang',
get name() {
console.log('元对象的get被调用了')
return this._name
},
set name(newName) {
this._name = newName
}
}
我们想要对obj 对象的get 和 set进行监听,通过创建 proxy代理对象的方式来监听 obj 上面属性的读取和设置值
const objProxy = new Proxy(obj, {
get(target, key) {
return Reflect.get(target, key)
},
set(target, key, newValue) {
Reflect.set(target, key, newValue)
}
})
console.log(objProxy.name)
当我们通过代理对象 objProxy读取name属性的时候,会进入到 get 的捕获器里面,然后又通过 Reflect.get() ,会去访问 obj 对象的 get 方法,在里面又通过 this 访问obj 的name属性。如果我们对obj内所有属性的访问和操作都想经过 proxy代理拦截的话,那么就有问题了,目前对于 this._name 的访问后续没有来到objProxy代理,那么拦截就失去了效果,因此要想办法让 obj中 get访问的属性 this指向为代理对象。
const objProxy = new Proxy(obj, {
get(target, key, receiver) {
// receiver 是创建出来的代理对象
console.log('get方法被调用----', key, receiver)
return Reflect.get(target, key, receiver)
},
set(target, key, newValue, receiver) {
console.log('set方法被调用----', key, receiver)
Reflect.set(target, key, newValue, receiver)
}
})
console.log(objProxy.name)
get捕获器可以传入第三个参数 receiver,这个 receiver 就是创建出来的代理对象。而Reflect.get()也可以传入第三个参数 receiver,传入这个参数后,可以改变target对象get方法的 this 为 receiver,此时就是代理对象。那么通过代理对象访问 name的时候会经过 obj 的 get 方法 ,此时返回的就是代理对象的name ,然后又回到代理对象的 get。最后在代理对象中的拦截操作就变得有意义。因此这里的代理对象get会调用两次。同样的 set也是可以传递 receiver 对象的