【问题标题】:Why is Set not executed when using Proxy on Map Object? [duplicate]为什么在 Map Object 上使用代理时 Set 不执行? [复制]
【发布时间】:2018-04-10 19:52:00
【问题描述】:

我在地图对象上创建了一个简单的代理示例。我无法弄清楚为什么 Set 处理程序没有被执行,而是执行 Get,对于 Sets。

const handler = {
  get: (targetObj, propName, receiverProxy) => {
    console.log('PROXY: From get.')
    let ret = Reflect.get(targetObj, propName, receiverProxy)
    if (typeof ret === 'function') {
      ret = ret.bind(targetObj)
    }
    return ret
  },
  set: (targetObj, propName, propValue, receiverProxy) => {
    console.log('PROXY: From set.')
    return Reflect.set(targetObj, propName, propValue, receiverProxy)
  },
}

const targetMap = new Map([
  ['iron', 'man'],
])
const targetObj = {}
const proxy = new Proxy(targetMap, handler)
console.log(proxy.set('super', 'man'))
console.log(proxy.get('super'))

【问题讨论】:

  • 它会执行您的get(),因为代理将参与访问目标对象(Map 实例)的“set”属性。处理程序的set()get() 方法是关于属性访问和更新的;它们与 Map 原型上的方法无关。如果您尝试 proxy.x = 1; 或其他方式,您会看到您的 set() 被调用。
  • 您在哪里找到该代码?它看起来像是从答案到副本的精确副本:-)
  • 我相信它来自那个帖子。问题是,该答案中的代码似乎有效,而我的却没有,即使我的几乎相同。
  • @Kainan 该答案的第一段解释了为什么它不起作用。并且第一个 sn-p 中的代码没有声称可以工作,它只拦截 property accesses 而没有别的。如何拦截.set().get()调用,请看答案第二部分。

标签: javascript


【解决方案1】:

如果您想要一个代理设置来拦截对 Map .set() 方法的尝试调用,您必须执行以下操作:

let handler = {
  get: (target, property, proxy) {
    if (property === "set") {
      console.log("intercepted a '.set' access on the proxied map");
      return (key, value) => {
        console.log("intercepted a 'set()' call on the proxied map");
        return target.set(key, value);
      };
    }
    return target[property];
  }
};

尝试任何属性访问时都会调用“get”处理程序方法。在方法调用中

proxy.set("some key", "some value");

在实际调用方法之前,必须查找对象的“set”属性。正是该查找操作导致处理程序“get”方法调用。

现在,如果您在代码中创建代理,然后执行

proxy.set("some key", "some value");

当调用返回的“拦截器”函数时,您会看到日志消息触发。

【讨论】:

  • 谢谢@Bergi 是的,这就是我的意思:)
  • 这是有道理的。谢谢@Pointy
【解决方案2】:

Set 和 get 不是这样工作的。

您可以像使用任何普通对象一样使用代理对象。例如:

proxy.super = 'man';     // fires the setter
const x = proxy.super;   // fires the getter

然后,在您的 get/set 处理程序中,您可以在 targetObj 上调用原始的 get/set 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 2016-06-16
    • 2019-12-18
    相关资源
    最近更新 更多