On __proto__ as a magical data property

Jason Orendorff jason.orendorff at gmail.com
Wed Jul 18 14:45:56 PDT 2012


On Wed, Jul 18, 2012 at 3:28 PM, Brendan Eich <brendan at mozilla.org> wrote:
> Your suggestion of the setter checking that the receiving object inherit the
> built-in __proto__ before actually doing the "set" is interesting, but it
> seems to me that it means every set does a proxy-observable "has" operation.
> That's not something we do today -- maybe it's ok to add it -- but it is
> also overhead and opportunity for mischief. Or did you have a thought on how
> to silently probe for the property descriptor?

Yes, there's actually a nice answer for this. Consider:

    // Applying __proto__ setter directly to a proxy
    var proto_prop =
      Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
    proto_prop.set.call(proxy, {});

    // Applying a DOM getter directly to a proxy
    var nodeType_prop =
      Object.getOwnPropertyDescriptor(Node.prototype, "nodeType");
    nodeType_prop.get.call(proxy);

The nodeType getter is non-generic; it only works on Nodes. The
__proto__ setter should be "non-generic" too: namely, it should only
work on non-Proxy objects.

As the proxies spec stands, non-generic methods applied to proxies will
just throw TypeError.  This is safe.

However, SpiderMonkey C++ proxies already have a mechanism that makes
such calls work transparently by default: the nativeCall hook Jeff
mentioned.  ES proxies might or might not gain a similar mechanism.  If
they do, the setter call here would be transparently applied to the
target by default.  The hypothetical __proto__ property check would
still occur -- on the target, not the proxy.

-j


More information about the es-discuss mailing list