[[Invoke]] and implicit method calls

Allen Wirfs-Brock allen at wirfs-brock.com
Wed Sep 11 18:15:31 PDT 2013


On Sep 11, 2013, at 5:13 PM, Brendan Eich wrote:

>> Jason Orendorff <mailto:jason.orendorff at gmail.com>
>> September 11, 2013 3:38 PM
>> 
>> But as Allen said, [[Invoke]] is not a performance hack. It's a
>> correctness hack.
>> 
>> It permits proxies to customize their behavior around `this`, and even
>> naive .invoke trap users would definitely want those customizations to
>> apply for implicit .toString() and .then().
> 
> Sorry, how can this be correctness when ECMA-262 and implementations have used [[Get]] + [[Call]] (after some IsCallable conditioning) forever?

It has nothing to do with what has worked forever in the absence of Proxy.  The issue is consistent behavior in the presence of Proxies.

Consider an Proxy-based object the exposes a toJSON method.  The proxy might be implementing a virtual object or it might be implementing a caretaker or some hybrid of the two styles.  In does matter, other than it means that the proxy might be doing a translation of the this value (or even argument values) when its methods are invoked.

Let's assume p is such an object.

Presumably, p.toJSON() and JSON.stringify(p) should produce the same result because stringify internally (and conditionally) calls toJSON.  But if

p.toJSON()  is implements as:
      result = p.[[Invoke]]("toJSON",(), p)

and the internal call of toJSON within stringify is implemented as:
        func = p.[[Get]]("toJSON");
        if (func && isCallable(func) result = func.[[call]](p,());
        else result = undefined;

then the results may not be identical because in the second case P's handler has not had a change to intercede of the passing of the this value and arguments to the function.

Allen





More information about the es-discuss mailing list