Le 13/04/2011 23:24, Sean Eagan a écrit :
> One way to get truly shared proxy handlers
Do we want it?
In my previous thread, I discussed shared handlers, but more from a
proxy writer experience point of view, not with the idea of having
something specified toward it. The topic had already been discussed, it
was one of the rationale behind [1]. I wanted to provide a bit of
experience of what is (for a proxy writer) to be considered when
thinking about shared handlers: Which "proxy library" use cases can
consider using shared handlers? Which use cases cannot use shared
handlers? What are the benefits and downsides of shared handlers against
one handler per instance (for proxy writers, not specifiers or
implementors)?
But do we want to set "truly shared proxy handlers" as a Proxy API
design goal?
Having a bit of experience in discussing the Proxy API design here, I
think that the first question to answer when discussing the Proxy API
design is:
What use cases does this proposal cover that wasn't covered before?
>From what I understand, "truly" shared proxies do not solve anything
that couldn't be solved before.
> would be to allow proxies
> to have some internal instance "state" that gets passed to each trap,
> just like objects have internal instance state ( [[Prototype]],
> [[Class]], [[Extensible]] etc) that gets "passed" to their "traps" (
> [[Get]], [[GetOwnProperty]], [[Call]] etc.). This would add another
> argument to each trap, but I think it might be better anyway to switch
> to a single object argument for all traps so that the order becomes
> irrelevant, of course the argument names then become relevant, so it's
> a tradeoff. There could be a "create" trap to initialize this state,
> and a way to pass arguments to this trap.
>
> It might also be useful to have a "getPrototypeOf" trap to avoid
> having to explicitly (and correctly) calculate and pass the prototype
> argument on each Proxy.create call. Removing the prototype argument
> could also allow Proxy.create and Proxy.createFunction to be merged
> into a single API.
TC39 seems to be going in the opposite direction (adding a prototype
argument to createFunction) [2]
I am under the impression that starting here, you're proposing other
changes to the Proxy API, so at some point, the question will arise too:
What is the use case you're addressing?
> This trap could be called just once (to avoid
> mutable prototypes) right after the "create" trap. This trap would be
> ignored for function proxies since they should always have
> Function.prototype.
If you merge Proxy.create and Proxy.createFunction, how do you intend to
distinguish function proxies from "object proxies"?
I think that the rational behind having two methods is actually to have
a clear distinction between how both are created so that creation rules
can be different.
> Putting this altogether, and utilizing destructuring, this could look
> something like...
>
> Proxy.Handler = {
> ...
> create: function(target) {
I'm puzzled by the "target" argument name. Are you only addressing the
forwarding proxy use case?
> let state = {target: target};
> return state;
> },
> ...
> getPrototypeOf: function ( { state } ) {
> return Object.getPrototypeOf ( state.target ) );
> }
> ...
> get: function( { state, proxy, receiver, name } ) { ... },
> ...
> }
> In order to be able to pass the createArgs to the "create" trap,
> definition of the full handler (handler + callTrap + constructTrap)
> would need to be separated from actual proxy instance construction.
> Here's how this might look...
>
> //Proxy.Constructor would return a proxy constructor which constructs
> proxies having the passed handler, callTrap (optional), and
> constructTrap(optional)
> let ProxyConstructor = Proxy.Constructor(handler, callTrap, constructTrap);
>
> The proxy constructor when called would first forward its arguments to
> the handler's "create" trap to initialize the state, then call
> the handler's "getPrototypeOf" trap passing the state, then construct
> and return the actual proxy using handler, callTrap, and
> constructTrap.
>
> let proxy = new ProxyConstructor(...createArgs); // would also work
> without "new"
>
> For Proxy.Handler proxies, this would translate to...
>
> let ForwardingProxy = Proxy.Constructor(Proxy.Handler);
> let proxy = new ForwardingProxy(target);
All what you're describing is quite interesting, but I don't think it is
solving a new use case. I have the impression that besides the
additional state argument (which could be emulated as state objects in a
WeakMap indexed on your proxies), all what you're describing could be
written as a library on top of the current Proxy API.
Cheers,
David
[1] http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy
[2] http://wiki.ecmascript.org/doku.php?id=strawman:function_proxy_prototype
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss