[英]JavaScript Proxy Setter doesn't make a second Proxy call
I have the following code that is using Proxy for Class setter.我有以下代码使用 Proxy for Class setter。 In my example I am tracking specific variable to update some other variables.
在我的示例中,我正在跟踪特定变量以更新其他一些变量。 My Setter is writing a log of all changes to Console.
我的 Setter 正在将所有更改的日志写入控制台。 However if I try to modify a variable from a setter itself, variable gas modified, but the Proxy isn't called.
但是,如果我尝试从 setter 本身修改变量,则会修改变量气体,但不会调用代理。 Is it by design to avoid looping?
是为了避免循环而设计的吗? Or am I missing something?
或者我错过了什么?
class darthVader { constructor() { return new Proxy(this, { set(obj, prop, value) { console.log(`Setting ${prop} to ${value}`) obj[prop] = value return true } }) } set resistance(val) { this._resistance= val this.darkSide = false } get resistance() { return this._R2D2 } } let newHero = new darthVader() newHero.resistance = 11 console.log(newHero.darkSide)
The problem is that your trap just runs obj[prop] = value
, which sets a property on the target obj
not on the proxy.问题是你的陷阱只运行
obj[prop] = value
,它在目标obj
上设置一个属性,而不是在代理上。 What you should do instead is to use the Reflect.set
method that provides the default implementation for the set trap, and expects an optional receiver
argument.您应该做的是使用
Reflect.set
方法,该方法为设置陷阱提供默认实现,并需要一个可选的receiver
参数。 This receiver is the object that setters will be evaluated against, and you should pass the receiver
argument of the set
trap (which will refer to the newHero
proxy that you assigned resistance
to).这个接收器是设置器将对其进行评估的对象,您应该传递
set
陷阱的receiver
参数(它将指代您newHero
分配resistance
的newHero
代理)。
class DarthVader { set resistance(val) { this._resistance= val this.darkSide = false } get resistance() { return this._R2D2 } } let newHero = new Proxy(new DarthVader, { set(target, prop, value, receiver) { console.log(`Setting ${prop} to ${value}`) return Reflect.set(target, prop, value, receiver) // ^^^^^^^^^^^ // obj[prop] = value } }); newHero.resistance = 11 console.log(newHero.darkSide)
The obj
inside the set
method refers to what this
is when you do return new Proxy(this
, and that object is not a proxy, but the darthVader
instance itself - the one that's in the process of being created by the darthVader
constructor. So, when you assign to a property of obj
, you're putting a property directly on the darthVader
instance, rather than on the proxy instance (which is the newHero
). So, the proxy method doesn't get called.该
obj
内部set
方法指的是什么this
是当你return new Proxy(this
,那对象不是代理,但darthVader
实例本身-一个最在被创建的过程darthVader
。构造函数,因此,当您分配给obj
的属性时,您将属性直接放在darthVader
实例上,而不是放在代理实例(即newHero
)上。因此,不会调用代理方法。
If you wanted to recursively invoke the proxy, you could define it (let's say, as the variable name proxy
) before returning it from the constructor, and then reference proxy
inside the set
method, but given the current logic, this results in a stack overflow because you'd be continually calling the proxy's setter:如果你想递归调用代理,你可以在从构造函数返回它之前定义它(假设,作为变量名
proxy
),然后在set
方法中引用proxy
,但鉴于当前的逻辑,这会导致一个堆栈溢出,因为您会不断调用代理的 setter:
class darthVader { constructor() { const proxy = new Proxy(this, { set(obj, prop, value) { console.log(`Setting ${prop} to ${value}`) proxy[prop] = value return true } }) return proxy; } set resistance(val) { this._resistance = val this.darkSide = false } get resistance() { return this._R2D2 } } let newHero = new darthVader() newHero.resistance = 11 console.log(newHero.darkSide)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.