Making "super" work outside a literal?

Sean Eagan seaneagan1 at gmail.com
Tue Jun 21 07:28:40 PDT 2011


On Sun, Jun 19, 2011 at 2:14 PM, Brendan Eich <brendan at mozilla.com> wrote:
> On Jun 19, 2011, at 10:20 AM, Axel Rauschmayer wrote:
>
> It would be nice if "super" could work in any method and not just those
> methods that are defined inside an object literal. Then, a method would have
> to know what object it resides in, e.g. via an implicit parameter.
>
> We wish to avoid another parameter computed potentially differently for each
> call. It will cost

What costs do you foresee?  I am not sure that there is much to
compute.  Assume a method call O.m().  Assume "m" is found on an
object P within O's protoype chain.  This will result in P.m being
called, for which the "super binding" can simply be computed as
P.[[Prototype]].  Next assume a direct function call, e.g.
f.call(this) or f() (this === undefined), the "super binding" here
could just be calculated as this.[[Prototype]] or undefined if |this|
is not an object.

> , and it will lead to surprises.

What surprises do you foresee?  I think a static |super| in light of
ES's dynamic |this| would actually be much more surprising.  This
would lead to looking for properties in a static |super| object that
may be completely unrelated to the dynamic |this| value of a given
function activation, which would certainly be surprising.

> Also, anything reachable from |this| can be computed using ES5's Object.*
> APIs.

Wouldn't the ES5 Object.* APIs be unreliable and inconvenient for such
a calculation?  It is impossible to determine which property name a
method m was accessed with from within m, and even if you assume a
static property name p, climbing the prototype chain of |this| to
determine on which object m was found via
|Object.getOwnPropertyDescriptor(prototypeChainObject, p)| may not be
accurate if there are any proxies in the prototype chain, or if
anything has changed in the prototype chain since it was initially
climbed by the engine.

> Quoting from
> http://wiki.ecmascript.org/doku.php?id=harmony:object_initialiser_super :
>
>  When a function contains a reference to super, that function internally
> captures an internal reference to the [[Prototype]] of the object created by
> the enclosing object initialiser. If such a function is subsequently
> extracted from the original object and installed as a property value in some
> other object, the internal reference to the original [[Prototype]] is not
> modified. Essentially, when a function references super it is statically
> referencing a specific object that is identified when the function is
> defined and not the [[Prototype]] of the object from which the function was
> most recently retrieved.
>
> This behavior is consistent with that of most other languages that provide
> reflection function to extract methods containing super and then
> independently invoke them.

Consistency with other languages is valuable, but consistency with
this language (ES) is vital.  A static |super| would be inconsistent
with ES's dynamic |this|.  The semantics of |super| will be related to
the value of |this| no matter how |super| ends up being specified, and
thus the "super binding" should be calculated in terms of the "this
binding" if intra-language consistency is to be kept.

>
> /be
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>



Cheers,
Sean Eagan


More information about the es-discuss mailing list