Short summary:
The current (rev18) [[Invoke]] design allows this code to work (use case A):
js```
var p = new Proxy(new Map, {});
// Map.prototype.get is not generic, requires proper Map instance
p.get(key);
```
But it does not allow to use (use case B):
js```
var p = new Proxy(new Map, {});
Map.prototype.get.call(p, key);
```
To make sure use case B works as well, [[InvokeFunction]] and changing
Function.prototype.{call, apply} has been proposed. Proxies will also
receive a new trap for [[InvokeFunction]]. Function.prototype.call will
need to be changed as follows:
Change last step (step 4) from:
4. Return result of func.[[Call]] (thisArg, argList).
To:
4. If Type(thisArg) is Object then
4.a Return result of thisArg.[[InvokeFunction]] (func, argList).
5. Else
5.a Return result of func.[[Call]] (thisArg, argList).
(Note: The condition in step 4 may explicitly test for Proxies and only
dispatch [[InvokeFunction]] if that's the case -- but this is not too
important for now.)
The following objections have been raised so far:
(1) Calling Function.prototype.call on a function object no longer
ensures the function object will be called.
(2) Calling Function.prototype.call on a function object let's the
function object escape to the proxy object.
Example for (1):
js```
function thrower() { throw new Error }
var p = new Proxy({}, {invokeFunction(f, args) { /* do nothing */ }});
// no exception will be thrown here
thrower.call(p);
```
Example for (2):
See Kevin's example below.
In response to these objections, it was said that `Reflect.call()` will
need to be used to ensure the original [[Call]] behaviour takes place.
- André
Ok, I've only been skimming the thread but I obviously missed something
crucial. How would
f.call(obj)
cause obj's handler to be invoked at all, much less be given access to f?
And why?
On Mon, Sep 23, 2013 at 7:14 PM, Allen Wirfs-Brock <allen at wirfs-brock.com
<https://mail.mozilla.org/listinfo/es-discuss>>wrote:
>/ Sorry, I meant obj's handler
/>/
/>/
/>/ "Mark S. Miller" <erights at google.com
<https://mail.mozilla.org/listinfo/es-discuss>> wrote:
/>/
/>/ What does "f's handler" refer to? If obj is a proxy and f is not, then obj
/>/ has a proxy and f does not.
/>/
/>/
/>/ On Mon, Sep 23, 2013 at 6:32 PM, Allen Wirfs-Brock <allen at wirfs-brock.com
<https://mail.mozilla.org/listinfo/es-discuss>>wrote:
/>/
/>>/
/>>/ On Sep 23, 2013, at 6:14 PM, Kevin Smith wrote:
/>>/
/>>/ > Hi Allen,
/>>/ >
/>>/ > Your line of thinking has convinced me that `invoke` as it currently
/>>/ stands doesn't really fly. However, I have an issue with your proposal.
/>>/ Take this fragment:
/>>/ >
/>>/ > (1) function f() { doSomethingWith(this); }
/>>/ > (2) f.call(obj);
/>>/ >
/>>/ > Presently, the expression at (2) grants the function `f` access to
/>>/ `obj`. If I understand correctly, under your proposal the expression at
/>>/ (2), in the case where `obj` is a proxy, additionally grants `obj` access
/>>/ to `f`. Is that right?
/>>/
/>>/ In the case where obj is a Proxy f.call(obj) would give f's handler
/>>/ access to f.
/>>/
/>>/ Allen/
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss