简体   繁体   English

JavaScript 代理设置器不会进行第二次代理调用

[英]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分配resistancenewHero代理)。

 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM