Proxying Native Objects: Use case

François REMY francois.remy.dev at outlook.com
Thu Jan 31 07:10:50 PST 2013


Hi.

I must admit I didn't follow the whole thread about native element proxyfication but when I left the consensus was that the native element should not be proxied (ie: it would not work like Object.create(...) do not work for them).

I've however a compelling use case that may make some of us rethink the situation.


Let's say I want to implement a polyfill for MapEvent whose definition is as follows:

    interface MapEvent : Event {
        getter any item(DOMString name);
    }

In case of no-proxy-for-native-objects, I've no way to do it properly because implementing 'getter' requires me to use a Proxy but having a functional event will force me to use a natively-branded element (like document.createEvent("CustomEvent")) and changes its prototype chain to match my needs.


So, I would like to reiterate the need for a proxification of native objects: the proxification would be used in the case of polyfills and it doesn't matter if it's possible to extract information about the underlying element, the only goal of the prolyfill is to implement the getter anyway.

To solve the wrapping/unwrapping, the solution I already talked about would be a good fit:

    ProxiedCustomEvent implements CustomEvent
    - nativeEvent : CustomEvent
    - proxy : ECMAScriptObject

so that if the object has to be returned again later (ie: to a callback) the unwrapping works as expected.



The other option would be to allow to transform any native object into a proxy but I heard it wasn't an approach that did get a lot of love. Maybe we should reconsider it?

   ECMAScriptObject
   - object nativeBrand
   - ...

In this case, the wrapping/unwrapping would work exactly as usual, with the small difference that the ECMAScript wrapper of the CustomEvent would be a Proxy. Using symbols, this could be as easy as:

    function MapEvent() {
        var e = document.createEvent("CustomEvent");
        e.initCustomEvent(...);

        e[Object.__Prototype__] = MapEvent.prototype;
        e[Object.__Get__] = function getter(name) { ... }
        e[Object.__Has__] = function has(name) { ... }
        ...

        return e;
    }

    var e = new MapEvent();
    e instanceof MapEvent; // true
    document.body.dispatchEvent('map', e); // works


Any thought on this?
François 		 	   		  


More information about the es-discuss mailing list