super, methods, constructors & Co.

Herby Vojčík herby at mailbox.sk
Mon Jun 4 02:16:38 PDT 2012



Luke Hoban wrote:
>>> In fact, without<|, are there any cases where super behaves
>>> correctly in an object literal, other than making super calls to
>>> Object.prototype functions?
>
>> We haven't eliminated the ability to define object literals that
>> inherit from objects other than Object.prototype.  We have just
>> changed the syntax for specifying them from: proto<| {} to
>> {__proto__: proto}
>
> Good point.  Object literals with inline __proto__ declarations do
> provide method contexts where super will behave correctly. But I
> think it's fair to assume that most object literals will not include
> inline __proto__ declarations.
>
>> In general, if you have multiple level instance based inheritance
>> hierarchies, super has the same general utility that it has in an a
>> class/instance based inheritance hierarchy.
>
> But only if that multi-level instance hierarchy is created in a very
> specific (and arguably uncommon) way.  That's my concern.  We happen
> to be discussing adding a new syntactic construct for classes, and
> can make sure that 'super' always works inside classes.  But we can't
> make 'super' always work inside object literals.
>
>>> Take Backbone/Underscore as an example.  A developer writes some
>>> code like:
>>>
>>> var Note = Backbone.Model.extend({
>>>     set: function(attributes, options) {
>>>         super.set(attributes, options);
>>>     }
>>> });
>
>> Of course, the above is a case where I suggest a mustache should
>> probably be used.
>
> Although it isn't obvious from the code I shared, this is actually
> creating a new object which has Backbone.Model in its prototype
> chain, and putting a set method in the new instance.  So mustache
> doesn't easily integrate into the syntax here.  One would need to
> change the API model non-trivially, and the consumption syntax
> somewhat significantly, to use mustache here.

In that case, it is the place for {__proto__: Backbone.Model, set: ...} 
or similar construct, where super is highly usable.

>> The issue of passing new semantic constructors into legacy
>> frameworks is certainly worth thinking about.  Although, i tend to
>> think that actively maintain frameworks will get ahead of the ES6
>> adoption curve.  And that legacy using a out of date framework is
>> much less likely to start using new ES6 constructs.
>
> This seems optimistic, but possible.  More importantly though, do we
> know how these libraries would address this sort of thing?  And what
> the transition would look like (can they do it in a library-only way
> such that they can feature detect to work correctly with new ES6
> constructs, but still work in pre-ES6 environments)?
>
>> Of course, the above doesn't even work for ES5 since it it ignores
>> non-enumerable properties, doesn't copy accessor properties
>> correctly, and probably unintentionally includes inherited
>> properties. We should be cherry picking super as the only feature
>> that is problematic for such code. One might speculate if these
>> deficiencies aren't causing problems today, then perhaps the issue
>> of passing new language constructs into to legacy frameworks that
>> don't correctly deal with them is not a significant problem.
>
> Good point.  Though one might also speculate that none of the ES5
> features mentioned have seen enough adoption on the web yet to
> understand the full impact of these problems.
>
> But I think a difference that makes me more concerned about super is
> that this is something these APIs are trying to do already today.
> The backbone.js docs [1] that I took this example from explicitly
> call out __"Brief aside on super: JavaScript does not provide a
> simple way to call super — the function of the same name defined
> higher on the prototype chain. If you override a core function like
> set, or save, and you want to invoke the parent object's
> implementation, you'll have to explicitly call it..."__.  It gets a
> bit more subtle to say "JavaScript has a way to call super, but it
> won't work here."

And what is your concern here? super now allows to do it right (if you 
don't define a method bad way - in fact Object.defineMethod is needed 
for programmatic definition of a method from a variable). Libraries can 
begin to use it.

>> Here is another way to think about this class of issues. super is a
>> language feature that is design to work at the level of the
>> built-in behavior composition mechanism of ES (a fixed single
>> inheritance [[Prototype]] chain).  _extend and other abstraction
>> impose a different behavioral composition model.  super may not
>> work as expected with those other models unless their
>> implementation takes it input account in their implementation.
>
> That's a fair summary.  In practice though, a lot of object models in
> JavaScript are built using these higher-level abstractions built on
> top of the core JS prototype chain.  Mostly, features at the core
> language level continue to be usable via these higher level
> abstractions.  It's concerning to add core language features that
> can't (or can't sufficiently easily) be used by the common
> abstractions.

The question may be also, if those abstractions (which were filling the 
gap because raw prototype inheriotance was not good enough) are as badly 
needed now that prototype inheritance begins to be usable for much 
bigger crowd.

> Perhaps the ultimate question is just - what is the best an existing
> library developer offering a JS object model abstraction (like
> extend) can do to support super?
>
> Luke

Herby

> [1] http://backbonejs.org/


More information about the es-discuss mailing list