JavaScript Proxy Setter不进行第二个Proxy调用

hkmswyz6  于 2023-06-04  发布在  Java
关注(0)|答案(2)|浏览(204)

我有以下代码是使用代理类设置器。在我的例子中,我跟踪特定的变量来更新其他变量。My Setter正在将所有更改的日志写入Console。然而,如果我试图从setter本身修改一个变量,变量会被修改,但Proxy不会被调用。是否通过设计来避免循环?还是我错过了什么?

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)
cngwdvgl

cngwdvgl1#

问题是您的陷阱只运行obj[prop] = value,它在目标obj上设置了一个属性,而不是在代理上。您应该使用Reflect.set method,它为set trap提供了默认实现,并需要一个可选的receiver参数。这个接收者是setter将被评估的对象,您应该传递receiver argument of the set trap(它将引用您分配给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)
ctrmrzij

ctrmrzij2#

set方法中的obj引用了执行return new Proxy(this时的this,该对象 * 不是 * 代理,而是darthVader示例本身-正在由darthVader构造函数创建的示例。因此,当您分配给obj的属性时,您直接将属性放在darthVader示例上,而不是放在代理示例(即newHero)上。因此,不会调用代理方法。
如果你想递归地调用代理,你可以在从构造函数返回它之前定义它(比如说,作为变量名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)

相关问题