let ar = [];
let p = new Proxy(new Map(), {
get: (o, k) => {
ar.push(1)
return Reflect.get(o, k).bind(o)
},
set: (o, k, v) => {
ar.push(2)
return Reflect.set(o, k, v)
}
});
p.set(1, 2)
p.get(1)
console.log(ar) //Outputs [1,1]
I am trying to intercept both set and get operations on a Map object. I am in no way trying to extend/subclass a Map. In the process of proxying said Map object, I came across this weird unexpected behavior, the set trap isn't being fired in the above code, but instead the get trap gets fired twice!
I further proceeded to log the k(key) values from the get trap in the following way;
//same code above
get: (o, k) => {
console.log(k) //Logs set and then get!
return Reflect.get(o, k).bind(o)
}
//same code below
The behavior I expect is for the array to be [2,1]
and console.log(k)
at the get trap to actually output the value of the key.
I wish to know why this happens as so, I've gone through a couple problems like this in here related to proxyifying maps, none of them lead to any sensible reasoning as to why this is happening.
My end goal is to fire an event at the set trap. Am I using Proxy for something it is meant to be used? If not, what approach should I take? Should I abandon using a Map to an Object Literal even though it will bring all the cons of using one? ex: no length property, string-only properties, no forced-unique keys etc.
UPDATE: The more and more I dig into this proxified Map, the more issues I keep coming across. It now seems to me as if the ES6 Proxy API treats Maps the same way as it does an ordinary object. The answer by Vill and my digging backs this up. Why do I say this? Read the following;
//same code above
get: (o, k) => {
if(k === 'tray') return ']'
return Reflect.get(o, k).bind(o)
}
//same code below
p.tray //returns ]
The above code shouldn't theoretically succeed, right? It is as if Proxy is using the same logic to intercept object operations when intercepting Maps as well! As;
///--While the following---//
let m = new Map();
m.set('tray', ']')
m.tray //undefined
Vill's answer says that the Proxy identifies Map.prototype.set
as first reading set and invoking it as a function next.
Doesn't that mean in the set trap I've written in the original code(on the very top) doesn't intercept the modification/setting a property of the Map and in fact the implicit/native to Map-Map.prototype.set
is used instead of the Reflect.set
which we grant through the Proxy?
Doesn't all this further enforce the fact that Proxy and Maps don't mix together well? Am I heading down the wrong way? What am I misunderstanding if so? Are Proxies supposed to treat Maps like just any other object?