Invoke trap

Brandon Benvie bbenvie at
Fri Jun 7 13:15:05 PDT 2013

On 6/7/2013 12:53 PM, David Bruant wrote:
> Le 02/06/2013 09:46, Rick Waldron a écrit :
>> 4.4 Proxies
>> Proxy Invoke Trap and wrong |this|-binding on built-in methods
>> AWB: with current default behavior of “get”, “Caretaker” will break 
>> on built-ins such as Date, because the |this| binding is by default 
>> set to the proxy, so the Date built-in method will not find the 
>> correct private state.
>> ARB: Same issue with binary methods
>> ...
>> STH: We should add invoke trap but not change the object model
>> MM: Pleasant to have. Separate from private state.
>> AWB: used to think this was an issue with proxies, but convinced that 
>> it’s an API issue: we need to provide default handlers that do the 
>> right thing, and which users can subclass. In particular, want a 
>> handler that, on forwarding, rebinds |this| to the target.
>> STH: If you want to proxy a Date method the underlying `this` needs 
>> to be a non wrapped Date object.
> Doesn't this break encapsulation?
> var d = new Date();
> var pd = new Proxy(d, {
> invoke: function(target, name, thisArg, args){
> return target[name].apply(thisArg, args)
> }
> })
> var pt = pd.getTime(); // calls the invoke trap
> // in a mixed-trusted context with access to pd:
> var ppd = new Proxy(pd, {
> invoke: function(target, name, thisArg, args){
> // does the actual unwrapped date object leak through thisArg?
> }
> });
> var ppt = ppd.getTime();
> In any case, what is the following supposed to do:
> new Proxy(new Date(), handler) )
> I imagine we would want this to work too. Is this going through the 
> invoke trap as well? The question stands for all new "class-specific" 
> (Map, Set, etc.) methods that would be dot-called with a proxy as 
> first argument.
> If the problem being solved is making Date (and Map, Set, etc) 
> built-in methods works on wrapped objects, I feel the invoke trap is 
> only a partial solution.
> I intuit (but have no proof) that for to 
> work on proxies, there is a need for class-specific traps.
> * Object properties have specific traps to intermediate access 
> (has/get/set/defineProperty/keys, etc.),
> * [[Prototype]] has specific traps to intermediate access 
> (get/setPrototypeOf)
> * [[Extensible]] has a specific trap to intermediate access 
> (preventExtensions)
> * [[Call]] has a specific trap to intermediate access (apply)
> * [[Construct]] has a specific trap to intermediate access (construct)
> * Some other things that are somewhat internal (@@iterator, @@class, 
> etc.) are exposed as symbols and are mediated via object 
> properties-related trap
> The pattern I see is that a good share of object internal properties 
> (ES5.1 - 8.6.2 - Table 8 and Table 9) have traps dedicated to mediate 
> access.
> The case of functions is interesting. There are traps that are only 
> relevant when the target is a function. In that regard, adding traps 
> that are specific to accessing the Date internal [[Time]] value or 
> specific traps to mediate access to [[MapData]] isn't any different 
> than the current specific traps that mediate [[Call]] or [[Construct]]
> David
> _______________________________________________
> es-discuss mailing list
> es-discuss at

I believe the purpose of adding multiple types of handlers [1] was to 
address this and similar issues.

    In the case of the |get|, |set| and |invoke| traps, there is a
    choice to be made when forwarding the property get/set or the
    invoked method: should the value of |this| in a target’s accessor or
    method be set to the proxy object or to the target object? Either
    choice can be sensible, depending on your application. 

    The |DelegatingHandler| implements |get|, |set| and |invoke| in such
    a way that |this| inside forwarded accessors or method invocations
    remains bound to the |receiver| argument. Proxies using the
    |DelegatingHandler| can thus be used as prototypes for other
    objects: they leave the |this|-binding intact upon forwarding.


    |ForwardingHandler| is itself a subclass of |DelegatingHandler| (so
    it comes with an appropriate default implementation for all Proxy
    traps). It overrides the |get|, |set| and |invoke| traps so that
    forwarded accessors or method calls get run with |this| set to the
    target object.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list