I think David has a point. The fundamental vs. derived distinction is, as I
understand it, what Mark wrote recently, and David's application of it is sound
(we do that prototype-walk with shadowing "duplicate removal" when starting a
for-in loop in SpiderMonkey). Tom should weigh in.
But proxies have a proto chain for instanceof and good old prototype-based
delegation purposes, even though their traps could ignore the proto parameter.
The instanceof operator will not, and note how there is no getPrototypeOf trap,
either.
This is a feature. I asked early on in the development of proxies whether the
alternative, of putting the proto-chain walk "on the outside" of the proxy's
handler traps was considered, and Mark pointed out the obvious: that doing so
is strictly less flexible for cases where a proxy wants to do something
different.
But this greater-flexibility design decision does not mean the universal,
object -invariant (ignoring mutable __proto__) instanceof and getPrototypeOf
(and ES3's isPrototypeOf) relations should be outside of a proxy's control. The
Proxy.create proto parameter is the way to control those relations, for the
life of a given proxy, and modulo property lookup trap freedom to do other
things than just delegate up the proto chain.
/be
On Jan 23, 2011, at 8:43 AM, François REMY wrote:
> Moreover, should a Proxy really have a prototype ?
> I mean, what’s the point about having a prototype, since the “get” method can
> return everything you would like for any property ?
>
> I think getProtototypeOf should be defined as a new trap. And its default
> behaviour should be to return null (or Object.prototype, but I think null is
> the intented behavior of a proxy).
>
> On the other hand, overriding getPropertyNames should not be allowed.
> getPropertyNames should *always* return the concatenation of the properties
> returned by getOwnPropertyNames() and by
> getPrototypeOf(this).getPropertyNames(). It makes no sense otherwhise.
>
> I understand that we may want to redefine the way an ECMAScript Object can
> handle the native commands, but I’m strongly against anything that can
> conduce to illogical results (if there’s not an use case that justify it,
> naturally). The definition of getPropertyNames is clear and being able to
> redefine it locally seems me wrong. A proxy can modify is own behavior, not
> the behavior of the ES engine. Being able to have getPropertyNames and
> getOwnPropertyNames returning incompatible results is somewhat hurting me. Is
> there any reason we should allow that ? Any use case ?
>
> I’m issuing the same concerns for the “has” trap. It think it should not be a
> trap. It should always return hasOwn(key) || prototype.has(key). Each one of
> hasOwn and prototype can be tuned by the proxy, but not the “has” itself.
> We’re not removing features, but we prevent bad usage of it. Whatever the
> user code do, the ‘has’ behavior will stay logical.
>
> Another thing I don’t quite understand is the difference between “keys” and
> “enumerate”. If there’s no strong difference, it should be the same trap
> (same logic: enumerate should return the concatenation of this.keys and
> this.prototype.keys). Having two different but similar traps will cause
> confusion. Maybe there’s a need for this difference however. I just didn’t
> understand why such a difference should exist, but at least I see more
> possible usages than the first three traps I “contested”.
>
> Anyway, if we should retain only one thing from the discussions we already
> have seen on the Proxy hub, is that it’s a great feature, but one that still
> needs some work before implementation ;-)
>
> Regards,
> François
>
> From: David Bruant
> Sent: Sunday, January 23, 2011 4:24 PM
> To: es-discuss
> Cc: Mark S. Miller
> Subject: [ES Harmony Proxies] Fundamental trap definition
>
> Hi,
>
> I am wondering if getPropertyDescriptor and getPropertyNames fundamental
> traps shouldn't rather be derived traps since they could have a pretty
> straightforward default implementation.
> One implementation of getPropertyNames could be :
> --------------------------
> Object.getPropertyNames = function(o){
> var objectToInspect;
> var result = [];
>
> for(objectToInspect = o;
> objectToInspect !== null;
> objectToInspect = Object.getPrototypeOf(objectToInspect))
> {
> result =
> result.concat(Object.getOwnPropertyNames(objectToInspect));
> }
>
> return result.removeDuplicates(); // the removeDuplicates method is made
> up, but you get the point
> }
> --------------------------
> This seem to fit the proposal
> (http://wiki.ecmascript.org/doku.php?id=harmony:extended_object_api&s=getpropertydescriptor)
> expectations). This could be also the default getPropertyNames trap
> implementation.
>
> I haven't really seen a strong definition of what fundamental traps are in
> the proposal. On Mark Miller's e-mail
> (https://mail.mozilla.org/pipermail/es-discuss/2011-January/012601.html) is
> written:
> [a trap is fundamental if] there is no coherent default behavior to fall back
> to that would be defined in terms of the remaining traps. (please tell me if
> I misinterpret what you meant)
> If we're going with this definition, then getPropertyDescriptor and
> getPropertyNames should probably be derived traps since they can clearly be
> defined thanks to other traps (respectively getOwnPropertyDescriptor and
> getOwnPropertyNames as I showed above) which seems to be coherent fallback
> behavior.
> Instead of a formal definition, this could be a rational for deciding what is
> a fundamental trap and what isn't.
>
> In the 5 remaining traps (getOwnPropertyDescriptor, getOwnPropertyNames,
> defineProperty, delete, fix), I don't see any that could be defined thanks to
> the others. They seem to be also the fundamental actions that one can perform
> on a single object:
> Property-wise:
> - create/configure a property (defineProperty)
> - delete a property (delete)
> - retrieve a property (getOwnPropertyDescriptor. Can be used to separate the
> create and configure cases of defineProperty)
> Property-set-wise:
> - retrieve the property set (getOwnPropertyNames. More can be found later on
> each property with getOwnPropertyDescriptor)
> - prevent further extension (and optional reconfigurations for seal and
> freeze)(fix)
> The prototype can be retrieved thanks to Object.getPrototypeOf (which cannot
> be trapped for consistency purposes) and all actions can be performed by
> climbing the prototype chain.
>
> Any thoughts on the fundamental trap definition?
> Or on the idea of turning getPropertyDescriptor and getPropertyNames into
> derived traps with the suggested definition?
>
> David
>
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss