【问题标题】:Why is my Proxy wrapping a Map's function calls throwing TypeError?为什么我的 Proxy 包装了 Map 的函数调用并抛出 TypeError?
【发布时间】:2017-02-22 01:23:34
【问题描述】:
var cache = new Proxy(new Map(), {
    apply: function(target, thisArg, argumentsList) {
        console.log('hello world!');
    }
});

cache.set('foo', 'bar');

据我所知,应该导致hello world! 被记录到控制台并且地图的foo 键未设置。但是,当我运行它时,它会抛出:

TypeError: Method Map.prototype.set called on incompatible receiver [object Object]
    at Proxy.set (native)
    at repl:1:7
    at ContextifyScript.Script.runInThisContext (vm.js:23:33)
    at REPLServer.defaultEval (repl.js:340:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.onLine (repl.js:537:10)
    at emitOne (events.js:101:20)
    at REPLServer.emit (events.js:189:7)
    at REPLServer.Interface._onLine (readline.js:238:10)

我已经在 Google 上搜索过所有 MDN 代理文档并浏览了好几次,但我无法理解为什么这不起作用。

有什么想法吗?我在 Node.js 7.5.0 上。

【问题讨论】:

  • 您实际上想要完成什么?你能创建一个Map 的子类吗?例如,您可以在子类中覆盖 .set()
  • @jfriend00 是的,覆盖.set 是我最初的想法。我使用 Proxy 的唯一原因是因为这个项目具有教育意义,我想尝试新的闪亮 :D
  • apply 陷阱用于被调用的函数对象,并且永远不会对 Map 对象(不可调用)起作用。

标签: javascript ecmascript-6


【解决方案1】:

apply 陷阱调用(如果您正在代理一个函数),而不是方法调用(这只是属性访问、调用和一些 this 恶作剧)。您可以提供 get 并返回一个函数:

var cache = new Proxy(new Map(), {
    get(target, property, receiver) {
        return function () {
            console.log('hello world!');
        };
    }
});

不过,我不认为您只是想覆盖 Map 的部分内容?在这种情况下,你可以从它的原型继承(如果它是一个选项,这比代理更好):

class Cache extends Map {
    set(key, value) {
        console.log('hello world!');
    }
}

const cache = new Cache();

【讨论】:

  • 噢噢噢噢。谢谢你!这真的让我很恼火。正如我在 OP 下面所说的,我只是想覆盖 .set - 我知道 Proxy 有点矫枉过正,但这是一个教育项目,所以我决定使用它“因为”:)
猜你喜欢
  • 2020-03-31
  • 2015-02-26
  • 1970-01-01
  • 2023-03-15
  • 2019-12-18
  • 1970-01-01
  • 2020-06-13
  • 1970-01-01
  • 2019-12-31
相关资源
最近更新 更多