javascript google-chrome dictionary proxy

javascript - ¿Por qué no funciona Proxy para un objeto Map en ES2015?



google-chrome dictionary (1)

La razón por la que obtiene el error es que el proxy no se involucra en la llamada p1.set (aparte de eso, la trampa set , no relacionada, a pesar del mismo nombre, se llama para recuperar la referencia de función). Entonces, una vez que se ha recuperado la referencia de función, se llama con this conjunto al proxy, no al Map , que Map no le gusta.

Si realmente está tratando de interceptar todas las llamadas de acceso a la propiedad en el Map , puede solucionarlo vinculando las referencias de funciones de las que está volviendo a get (vea las líneas *** ):

var loggingProxyHandler = { "get" : function(targetObj, propName, receiverProxy) { let ret = Reflect.get(targetObj, propName, receiverProxy); console.log("get("+propName.toString()+"="+ret+")"); if (typeof ret === "function") { // *** ret = ret.bind(targetObj); // *** } // *** return ret; }, "set" : function(targetObj, propName, propValue, receiverProxy) { console.log("set("+propName.toString()+"="+propValue+")"); return Reflect.set(targetObj, propName, propValue, receiverProxy); } }; function onRunTest() { let m1 = new Map(); let p1 = new Proxy(m1, loggingProxyHandler); p1.set("a", "aval"); console.log(p1.get("a")); // "aval" } onRunTest();

NOTE: Requires a browser supporting ES2015''s Proxy

Sin embargo, si su objetivo es interceptar Map#get y Map#set , no necesita un proxy en absoluto. Ya sea:

  1. Cree una subclase de Map y ejemplifique eso. Sin embargo, se supone que controla la creación de la instancia de Map .

  2. Cree un nuevo objeto que herede de la instancia de Map y anule get y set ; no tiene que tener el control de la creación del Map original.

  3. Reemplace el set y get métodos en la instancia de Map con sus propias versiones.

Aquí está el # 1:

class MyMap extends Map { set(...args) { console.log("set called"); return super.set(...args); } get(...args) { console.log("get called"); return super.get(...args); } } const m1 = new MyMap(); m1.set("a", "aval"); console.log(m1.get("a"));

# 2:

const m1 = new Map(); const p1 = Object.create(m1, { set: { value: function(...args) { console.log("set called"); return m1.set(...args); } }, get: { value: function(...args) { console.log("get called"); return m1.get(...args); } } }); p1.set("a", "aval"); console.log(p1.get("a"));

# 3:

const m1 = new Map(); const m1set = m1.set; // Yes, we know these are `Map.prototype.set` and const m1get = m1.get; // `get`, but in the generic case, we don''t necessarily m1.set = function(...args) { console.log("set called"); return m1set.apply(m1, args); }; m1.get = function(...args) { console.log("get called"); return m1get.apply(m1, args); } m1.set("a", "aval"); console.log(m1.get("a"));

Estoy ejecutando el siguiente script a través de la versión 57.0.2987.133 de Google Chrome:

var loggingProxyHandler = { "get" : function(targetObj, propName, receiverProxy) { let ret = Reflect.get(targetObj, propName, receiverProxy); console.log("get("+propName.toString()+"="+ret+")"); return ret; }, "set" : function(targetObj, propName, propValue, receiverProxy) { console.log("set("+propName.toString()+"="+propValue+")"); return Reflect.set(targetObj, propName, propValue, receiverProxy); } }; function onRunTest() { let m1 = new Map(); let p1 = new Proxy(m1, loggingProxyHandler); p1.set("a", "aval"); // Exception thrown from here } onRunTest();

NOTE: Requires a browser supporting ES2015''s Proxy

Cuando se ejecuta, veo que se llama a get trap del controlador para devolver la función de configuración del Mapa y luego recibo el siguiente error:

"Uncaught TypeError: Method Map.prototype.set called on incompatible receiver [object Object]" at Proxy.set (native) ...

Intenté eliminar las funciones trap del loggingProxyHandler (convirtiéndolo en un objeto vacío) pero aún recibo el mismo error.

Comprendí que se suponía que un objeto Proxy podía generarse para todos los objetos JavaScript ES5 y ES2015 nativos. La matriz parece funcionar bien bajo el mismo controlador proxy. ¿Entendí mal las especificaciones?
¿A mi código le falta algo? ¿Hay algún error conocido en Chrome? (Hice una búsqueda y no encontré defectos para Chrome en este tema).