[[Invoke]] and implicit method calls
Tom Van Cutsem
tomvc.be at gmail.com
Fri Sep 20 04:02:02 PDT 2013
2013/9/20 David Bruant <bruant.d at gmail.com>
> Further, a long-standing invariant in JS has been the equivalence of
> o.m(...args) and m.call(o, ...args). The invoke trap allows allows to
> break this invariant. I'm not sure this is for the best. This promotes a
> given coding pattern, but at the detriment of another.
I'm well aware. I originally advocated against invoke() for precisely this
> I'm still inclined to think a generic solution to private state and
> proxies should be found. Given this solution, the invoke trap may end up
> being plain redundant. That would be unfortunate.
> I realize private state isn't figured out for ES6, so I think this issue
> should be left pending, the invoke trap included.
My point of view is that we have already found the "generic solution" to
private state: WeakMaps. WeakMaps are able to store private state, and they
don't interact with proxies at all. I realize WeakMaps have syntactic and
implementation-level usability issues, and I'm hopeful the relationships
strawman can overcome these. But relationships semantically still build
upon WeakMaps, and they were tested to work across membranes in all cases.
Coming back to invoke(), I reviewed my notes from the May meeting (where we
decided to add the trap):
A good point made by Yehuda is that the "get" trap already allows a proxy
to re-bind |this| for intercepted accessors.
That is, in ES5, you had the "invariant" that if obj.x triggers a getter,
the getter's |this| is always bound to obj. With proxies, this is no longer
true. The "get" trap gives access to the thisBinding, and allows the proxy
to override. invoke() simply extends the power to re-bind |this| from just
accessor calls to general method calls.
Dave Herman also reminded us that on platforms with __noSuchMethod__, the
invoke = get + call invariant is already weakened.
In fact, as we've discussed on several occasions on this list, proxies
can't faithfully emulate __noSuchMethod__ without invoke().
And finally, if all we gain by leaving out invoke() is a simpler API, then
we should probably reconsider all derived traps. As I mentioned earlier, we
can easily get rid of traps like has(), hasOwn(), keys() etc., and they
don't seem nearly as important to intercept as method invocation.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the es-discuss