-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Proxy 的 get trap 中的 receiver 是什么?
在 Reflect.get 的场景下,receiver 可以改变计算属性中 this 的指向。
var target = {
get a() { return this.c }
}
Reflect.get(target, 'a', { c: 4 }) // 4
在 Proxy trap 的场景下,这个 receiver 永远指向 Proxy 本身或者继承它的对象。
var proxy = new Proxy({}, {
get: function(target, property, receiver) {
console.log(this)
return receiver;
}
});
proxy.getReceiver; // proxy
var inherits = Object.create(proxy);
inherits.getReceiver; // inherits
注意 get 函数里的 this 指向的是 Proxy 的第二个参数 handler 也就是 { get() { ... } }
这个对象。
在对象的计算属性里访问 this 的时候,会有用,这种情况好像没法用 call 改变指向吧。
var target = {
get a() {
return this.b
}
}
Reflect.get(target, 'a', { b: 3} )
还有就是比较复杂的逻辑
var target = {
get a() {
return this.b
}
}
var p = new Proxy(target, {
get(raw, key, receiver) {
if (key === 'b') { return 3 }
return Reflect.get(raw, key)
}
})
p.a // undefined
由于 target 本身没有 b 这个属性,所以访问到的是 undefined
换一个写法
var p = new Proxy(target, {
get(raw, key, receiver) {
if (key === 'b') { return 3 }
// receiver就是 proxy 对象,这下应该能访问到 'b' 了吧
return Reflect.get(receiver, key)
}
})
p.a
VM6758:2 Uncaught RangeError: Maximum call stack size exceeded
直接死循环了,因为访问 p.a 进入 get 函数后又继续访问 p.a 无限循环。
正确写法:
var p = new Proxy(target, {
get(raw, key, receiver) {
if (key === 'b') { return 3 }
return Reflect.get(raw, key, receiver)
}
})
p.a // 3
对于 Proxy 的拦截,还是老老实实的把 receiver 传递给 Reflect.get 比较好。
zephyrJS, ahabhgk, hurong1214, Luz-Liu, Binbiubiubiu and 6 moreQiuShuiBai
Metadata
Metadata
Assignees
Labels
No labels