Using ES6 Proxies with ES6 Maps

1

I'm about a day and a half researching about Maps and Proxies to delve deeper into the issue of looking at arrays, objects, and so on. But I came across a problem, I can not use Proxy in Map. When it comes to an ordinary array, I can use Proxy without problems, but I do not 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 ran the code, you saw that it returned an error. I think it's because it's using the "get" part to return the "set" function of "Map", but how would I correctly return the function by passing the appropriate values to it?

    
asked by anonymous 01.01.2017 / 20:17

1 answer

3

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

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

It does these steps:

a): to know what is teste_proxy.set :

that is, it 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, that is: fn("foo", "bar") .

What is interesting, and perhaps confusing, is that we get this value, as in the example var fn = teste.set it triggers get of Proxy . That is, there is a step between a) and b) .

So, when Proxy runs get , because the value of a property was requested on the object it is observing, it returns function set() { [native code] } . That is,% w / w of% w / w% = > Prototype .

When you then 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 thing to do:

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

and this gives the same error as you received:

  

Uncaught TypeError: Method Map.prototype.set called on incompatible receiver #
          at Map.set (native)

So how can we set values through the proxy?

If you are using a Map you can force the execution context within Map.prototype.set to itself, so it runs its Prototype method on the specific instance to which Map is signed, ie using: .get . So when you assign a value with the method Proxy the return target[property].bind(target); no longer gives a bug when it tries 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"));
    
01.01.2017 / 21:41