2
var cache = new Proxy(new Map(), {
    apply: function(target, thisArg, argumentsList) {
        console.log('hello world!');
    }
});

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

As far as I can tell this should result in hello world! being logged to the console and the Map's foo key not being set. However, when I run this, it throws:

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)

I've Googled and gone over all the MDN Proxy docs several times, and I can't wrap my head around why this isn't working.

Any ideas? I'm on Node.js 7.5.0.

strugee
  • 2,752
  • 4
  • 19
  • 30
  • What are you actually trying to accomplish? Can you just create a subclass of `Map`? For example, you could just override `.set()` in a subclass. – jfriend00 Feb 22 '17 at 01:45
  • @jfriend00 yeah, overriding `.set` was my original idea. the only reason I'm using Proxy is because this project is educational and I wanted to try out the new shiny :D – strugee Feb 22 '17 at 01:49
  • The `apply` trap is for function objects being called, and won't ever work on a `Map` object (which is not callable). – Bergi Feb 22 '17 at 02:05

1 Answers1

3

apply traps calling (if you were proxying a function), not method calls (which are just property access, a call, and some this shenanigans). You could supply get and return a function instead:

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

I don’t suppose you’re just trying to override parts of Map, though? You can inherit from its prototype in that case (this is a much better option than the proxy if it’s an option at all):

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

const cache = new Cache();
Ry-
  • 218,210
  • 55
  • 464
  • 476
  • ooooohhhh. thank you! this was really irking me. as I said below OP I'm just trying to override `.set` - I know Proxy is overkill but it's an educational project so I decided to use it "because" :) – strugee Feb 22 '17 at 01:51