1

I have created a simple Proxy example on a Map Object. I can't figure out why the Set handler is not being executed and Get is executed instead, for 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'))
4
  • It executes your get() because the proxy will be involved in accessing the "set" property of the target object (the Map instance). The set() and get() methods of the handler are about property access and update; they have nothing to do with the methods on the Map prototype. You'll see your set() called if you tried proxy.x = 1; or something. Commented Apr 10, 2018 at 19:57
  • Where did you find that code? It looks like an exact copy from the answer to the duplicate :-) Commented Apr 10, 2018 at 20:06
  • I believe it came from that post. The thing is, the code in that answer appears to work and mine does not, even though mine is nearly identical. Commented Apr 10, 2018 at 20:08
  • @Kainan The first paragraph of that answer explains why it doesn't work. And the code in the first snippet there is not claimed to work, it only does intercept property accesses and nothing else. For how to intercept .set() and .get() calls, see the second part of the answer. Commented Apr 10, 2018 at 20:11

2 Answers 2

1

If you want a proxy setup that lets you intercept attempted calls to the Map .set() method, you'd have to do something like this:

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];
  }
};

The "get" handler method is called for any property access is attempted. In the method call

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

the "set" property of the object has to be looked up before the method can actually be called. It's that lookup operation that results in the handler "get" method invocation.

Now if you make the proxy as in your code and then do

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

you'll see that the log message fires when that "interceptor" function you returned is invoked.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @Bergi yea that's what I meant :)
This makes sense. Thank you @Pointy
0

Set and get doesn't work like that.

You can use the proxy object like any normal object. For example:

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

Then, in your get/set handlers you can call the original get/set methods on the targetObj.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.