es6 javascript ecmascript-6 javascript-objects es6-proxy

javascript - es6 - El objeto proxy no se puede agregar al DOM(las trampas tampoco se activan)



es6 proxy apply (2)

Estoy tratando de hacer que un objeto Proxy de la Image atrape propiedades, pero incluso con un controlador vacío recibo un mensaje de error.

TypeError: el argumento 1 de Node.appendChild no implementa el Nodo de interfaz.

Se supone que el objeto proxy actuará como el objeto objetivo, así que esto me desconcierta un poco. Por lo que yo entiendo, también deberías poder hacer esto con los nodos DOM (?).

Además : no puedo comenzar a cargar la imagen y tener el controlador de carga activado al configurar la propiedad src .

¿Cómo debo usar el Proxy para poder "tomar el control", por ejemplo, la propiedad "src" y hacer que actúe como un objeto de imagen normal?

Mi código

''use strict''; //--- normal image use --- var imgNormal = new Image(); imgNormal.onload = function(){ console.log(''Normal loaded OK''); document.body.appendChild(imgNormal); }; imgNormal.src = ''https://i.imgur.com/zn7O7QWb.jpg''; //--- proxy image --- var imgProxy = new Proxy(Image, { // I also tried with ''new Image()'' and HTMLImageElement set: function(a,b,c,d){ console.log(''set ''+b); return Reflect.set(a,b,c,d); } }); imgProxy.onload = function(){ console.log(''Proxy loaded OK''); document.body.appendChild(imgProxy); }; imgProxy.src = ''https://i.imgur.com/zn7O7QWb.jpg''; document.body.appendChild(imgProxy); // double-up to demo error

Actualización : ¡Gracias a @Harangue! usar " new " (bah ...) ciertamente hizo que el objeto proxy cobrara vida, pero ahora no puedo atrapar la configuración de las propiedades. Parece ignorar la trampa por completo, por ejemplo:

var proxy = new Proxy(Image, { set: function(a,b,c,d){ console.log(''set ''+b); // doesn''t show return Reflect.set(a,b,c,d); } }); var imgProxy = new proxy(); imgProxy.onload = function(){ console.log(''Proxy loaded OK''); document.body.appendChild(imgProxy); }; imgProxy.src = ''https://i.imgur.com/zn7O7QWb.jpg'';

¿Cómo puedo atrapar la configuración de propiedad usando un proxy válido?

Actualización 2 Por otro lado, el uso de new con el nuevo proxy solo parece usar el constructor original . Todos los ejemplos que puedo encontrar no usan nuevos:

var myProxy = new Proxy(.., ..); // should suffer

Usando entonces encima de eso, new myProxy() solo parece usar el constructor original, que no es lo que yo quiero, ya que ignora las trampas.

var proxy = new Proxy(Image, {}); //should be sufficent?? var proxy2 = new proxy(); console.log(proxy2); //-> says Image (not proxy..)

Las trampas parecen funcionar en mis primeros intentos, pero el proxy no se comporta como se esperaba. Esto es tan confuso y tan nuevo. Feliz por cualquier entrada, cómo ambos pueden ser resueltos (trampas y comportamiento).


Como alternativa a un proxy, también puede sobrescribir la propiedad en el objeto mismo y, por lo tanto, controlar su comportamiento:

function findDescriptor(obj, prop){ if(obj != null){ return Object.hasOwnProperty.call(obj, prop)? Object.getOwnPropertyDescriptor(obj, prop): findDescriptor(Object.getPrototypeOf(obj), prop); } } var img = new Image(); var {get, set} = findDescriptor(img, "src"); Object.defineProperty(img, "src", { configurable: true, enumerable: true, //get: get, //keep behaviour get(){ //overwrite getter var v = get.call(this); //call the original getter console.log("get src:", v, this); return v; }, //same for setter set(v){ console.log("set src:", v, this); //modify value before applying it to the default setter v = v.toLowerCase(); set.call(this, v); } }); img.src = "FileWithUppercaseLetters.jpg"; //setter img.src; //trigger getter

Y dado que esta propiedad se define en Image.prototype *, simplemente puede extender esta clase y modificar el comportamiento en el prototipo de la clase heredada.

* al menos en FF, tiene que comprobar los otros navegadores


Nunca subestimes la importancia de la new palabra clave. ;)

//--- proxy image --- var imgProxy = new Proxy(Image, { // I also tried with ''new Image()'' set: function(a,b,c,d){ console.log(''set ''+b); return Reflect.set(a,b,c,d); } }); imgProxy.src = ''https://i.imgur.com/zn7O7QWb.jpg''; document.body.appendChild(new imgProxy); // double-up to demo error

Con el proxy, extiendes efectivamente el objeto Imagen. Pero al enviar el constructor Image en sí mismo, en lugar del nodo DOM devuelto por él, de hecho le faltaría el appendChild necesario.