Le 18/10/2011 17:17, Sean Eagan a écrit :
> On Tue, Oct 18, 2011 at 6:45 AM, David Bruant <[email protected]
> <mailto:[email protected]>> wrote:
>
>     Hi,
>
>     The initial proxy proposal was about to provide "proxy" as an
>     additional argument to all traps.
>     The current proxy has "target" instead, but still "proxy" for get
>     and set traps.
>     Regardless of the proposal, I have recently come up with a use
>     case [1] where I expressed the need of passing the "receiver" to
>     some traps when the proxy is up on the [[Prototype]] chain. (of
>     course, there is still need for an agreement that this use case is
>     worthwhile and that there is really no way to implement what i
>     want without passing "receiver").
>
>
> I think the "reciever" issue is unaffected by the change to direct
> proxies, it is still unnecessary if [[GetProperty]] continues to be
> propogated up the prototype chain, but necessary if [[Put]] and
> [[Get]] are propogated instead.
My need is unrelated to the exact behavior of [[Put]] and [[Get]].
Here is my use case. I'm working in the context of event as properties
[1]. I want inherited events:
-----
var o = new EventedObject();
o.o = 'o';

Object.defineProperty(o, 'e', {event:true});
o.e.addListener(function(){console.log(JSON.stringify(this));});
           
var o1 = Object.create(o);
o1.a = 1;

var o2 = Object.create(o);
o2.b = 2;
           
o1.e(); // I expect '{"a":1}' to be logged
o2.e(); // I expect '{"b":2}' to be logged
-----

o1 and o2 are normal objects following ES5.1 - 8.12 definitions. In the
current definition of [[Get]], "o1.e" does a [[GetProperty]] on o1, then
on o. At this point, o has to return a property descriptor. I could
return a property descriptor of a regular data property, but it looses
the nice event enumeration I'm trying to add. So, i'll return the thing
that has been passed to create the event property: {event:true,
configurable:false, enumerable:false}
Back to [[get]] with this descriptor, the step 4 (or 11 with the typo in
ES5) is incorrect: my descriptor is not a data descriptor, but is not an
accessor descriptor either! So first of all, o1.[[Get]] has no idea of
what to do with my descriptor (it cannot find the listeners related to
o.e). This is true for any non-standardized property descriptor. This is
ISSUE 1.

ISSUE 2 is that since o1.[[Get]]('e') cannot do what I need, I need to
do it by myself. I can't rely on o1.[[Get]] semantics to do the proper
|this| binding, so I need to do it myself at the prototype level. So I
need the receiver. I really do not see alternative. And the trap that is
being called on does not matter to me, i just need it in a way or
another. One problem with "o1.e" calling o.[[GetProperty]] is that there
is no way to distinguish from "Object.getPropertyDescriptor(o)" which is
annoying.

I think ISSUE 2 can find a solution if the get trap is called on the
prototype with the receiver. I'm not sure ISSUE 1 can have a solution
besides reforming [[Get]] (and certainly [[Put]]?) to delegate to the
same internal on the prototype.


> The advantage of the latter is that you don't have to construct a
> complete property descriptor for [[Get]]s and [[Put]]s when you only
> really need the "get" or "set" attribute, the disadvantage is that it
> allows proxies to lie in their Object.getOwnPropertyDescriptor return
> value's "get" and "set" attributes, since that is no longer
> necessarily what is actually used for [[Get]]s and [[Put]]s.
I fully agree with the rationale of receiver being useless for current
property descriptors (data and accessor), but my exeriment shows that
[[Get]] and [[Put]] are unable to handle property descriptors they have
not been prepared for.

>  
>
>     I'm afraid this is getting a bit verbose when writing/reading
>     traps. I think alternatives should be considered. Of course,
>     putting things directly on the handler is out of question to
>     respect proper stratification as previously said (by Tom?) on this
>     list.
>
>     One idea could be to have a unique optional argument which would
>     be an object with 3 properties: "proxy", "target" & "receiver".
>     These aren't always necessary, but I think there is no harm in
>     making all of them available to all traps.
>
>
> The downside of named arguments is that you commit to the names for
> eternity, the function author is not allowed to use their own names,
> such as abbreviations, and they have to remember the names (as opposed
> to indexes) of the arguments.  Also, since the other traps have
> varying numbers of other arguments, and this argument is proposed as
> last, this argument would not appear at the same index, which would
> not be a problem if the argument were first.  It also seems kind of
> arbitrary to have some named arguments and some positional.
>  Destructuring helps with the conciseness of named arguments though.
>  If changing to named arguments, I would propose a single Object
> argument containing all args:
>
> set: function( {name, value, proxy, target /*, receiver*/} )
Interesting idea. Thanks.

David

[1] https://mail.mozilla.org/pipermail/es-discuss/2011-October/017263.html
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to