Using ES6 Proxies with ES6 Maps

Asked

Viewed 71 times

1

I’m about a day and a half researching about Maps and Proxies to go deeper into the issue of looking at arrays, objects and so on. But I came across a problem, I can’t use the Proxy in the Map. When it comes to a common array, I can use the Proxy without problems, but I don’t know how to do it correctly in the case of Maps.

let teste = new Map();

let teste_proxy = new Proxy(teste, {
  get: function(target, property, receiver) {  	
    // property is index in this case
   return target[property]
  },
  set: function(target, property, value, receiver) {    
    target[property] = value;
    // you have to return true to accept the changes
    return true;
  }
});

console.log(teste_proxy);
teste_proxy.set("foo", "bar");

If you executed the code, you saw that it returns an error. I believe it is because he is using the "get" part to return the "set" function of the "Map", but how to correctly return the function passing the appropriate values to it ?

1 answer

3


The problem is that .set is a method of Map.prototype, so when you do:

teste_proxy.set("foo", "bar");

he does these steps:

to): go find out what it is teste_proxy.set:

that is, goes to the object that was passed to the proxy and makes a get.
In practice the same as var fn = teste.set

b): use this value and invoke a function on top of it, i.e.: fn("foo", "bar").

What is interesting, and perhaps confusing, is to go for this value, as in the example var fn = teste.set triggers the get of Proxy. I mean, there’s a step between a) and b).

So when the Proxy runs the get, because it has been asked the value of a property on the object it is observing, it returns function set() { [native code] }. Namely the Prototype of Map => Map.prototype.set.

When then you call

var fn = function set() { [native code] }; // isto é sintaxe inválida mas é só para separar em passos
fn('foo', 'bar');

what happens is the same as doing:

Map.prototype.set('foo', 'bar')

and that’s the same mistake you got:

Uncaught Typeerror: Method Map.prototype.set called on incompatible receiver #
At Map.set (Activate)

So how can we settar values through Proxy?

If you’re gonna use a Map can force the execution context into the .get to himself, so he runs his method of Prototype on the specific body to which the Proxy is associated, that is to say using: return target[property].bind(target);. So when you assign a value with the method teste_proxy.set the Proxy no longer bug when trying to give back the value of teste_proxy.set that needs associated context to run.

Example:

let teste = new Map();

let teste_proxy = new Proxy(teste, {
  get: function(target, property, receiver) {  	
    // property is index in this case
   return target[property].bind(target);
  },
  set: function(target, property, value, receiver) {    
    target[property] = value;
    // you have to return true to accept the changes
    return true;
  }
});

teste_proxy.set("foo", "bar");
console.log(teste_proxy.get("foo"));

  • 1

    Thank you so much! You helped me so much.

  • @Joaoscheuermann great! It took me a while to realize what was missing there :) Good year!

  • 1

    For you too, I spent hours and hours trying to solve this, but I didn’t think it was about the context :P

Browser other questions tagged

You are not signed in. Login or sign up in order to post.