Why are object initializer methods not usable as constructors?

/#!/JoePea joe at trusktr.io
Wed Jul 27 19:13:17 UTC 2016


> IIRC methods shorthand are the only where super is allowed, at least in
Chrome and Firefox.

If `super` were dynamic, then `super` could be allowed anywhere, not just
in Classes or object-initializer shorthand methods.

For what it's worth, `Object.assign` is a concept promoted into the
language by pre-ES6 ideas, like underscore's `_.extend` and others. So, the
 mere fact that `Object.assign` will fail to produce expected results when
copying something from an ES6 prototype that uses `super` means that the
direction of the ES6+ language is backwards-incompatible with pre-ES6
JavaScript and that ES6+ features are incompatible with themselves.

If something like `Function.prototype.toMethod` made it into spec but not a
dynamic `super`, then solution would be half-complete: tools like
`Object.assign` would also need to start using `toMethod` internally so
that results would be intuitive.

Arguably, the best solution would be for `super` to be dynamic and for
`Function.prototype.toMethod` to exist, following the same patterns as we
*love* about JavaScript's `this` keyword. This would open up
meta-programming possibilities, for example it would then be easy to write
a [prototype-based implementation of multiple inheritance](
https://gist.github.com/trusktr/8c515f7bd7436e09a4baa7a63cd7cc37) whereby a
single prototype chain is created based on the multiple classes we wish to
extend from (this is in constrast to a [`Proxy`-based implementation](
https://gist.github.com/trusktr/05b9c763ac70d7086fe3a08c2c4fb4bf)).

Claude Pache [mentioned that he likes for method borrowing to maintain the
same HomeObject](
https://esdiscuss.org/topic/the-super-keyword-doesnt-work-as-it-should#content-16),
but in my opinion that does not stay inline intuitive expectations coming
from pre-ES6 with a dynamic `this`: "I intuitively expect super to be
relative to the prototype chain of the current object where a method is
called".

If you are technical enough to understand why method borrowing fails due to
a static `super`, then you'd also be technical enough to understand why it
works the dynamic way if that ever became reality. Plus, if
`Function.prototype.toMethod` is brought into spec, then you'd also be
technical enough to borrow the method and assign the original HomeObject
that you wish.

*/#!/*JoePea

On Wed, Jul 27, 2016 at 11:44 AM, /#!/JoePea <joe at trusktr.io> wrote:

> What's the good reason that object-initializer methods can't be
> constructors though? I mean, I get that "that's what spec says", but what's
> the actual good reason?
>
> The problem here would be solved with a dynamic super.
>
> I feel that ES6 diverges from ES5 in backwards-incompatible ways. Some
> people say ES6 classes are "syntax sugar" over the ES5 constructor pattern
> classes, but, *not really*, since they aren't compatible in the same
> places. ES6 classes  and object-initializer methods are not
> backwards-incompatible in a bad way because they cannot be treated the same
> as we are used to in ES5 (f.e. copying methods with underscore's
> `_.extend()` doesn't work because of static HomeObjects), and that is
> backwards-incompatible with previous concepts, ideas, and methodologies
> that we love JavaScript for.
>
> Some old code might do something like
>
> ```js
> _.extend(SomeClass.prototype, OtherClass.prototype)
> ```
>
> where `SomeClass` and `OtherClass` are ES5 constructor-pattern classes. If
> the classes are updated to be ES6 classes, then that code may fail because
> of the static `HomeObject` properties, and that is backwards-incompatible
> with the paradigms and patterns of ES5.
>
> **A dynamic super would remedy this problem.**
>
> For now, I am contemplating using a custom and dynamic
> `Object.prototype.super` getter in all apps where my code runs so that my
> ES6 classes remain as flexible as in ES5. The overhead associated with a
> custom `Object.prototype.super` would only be due to the fact that it is
> not possible for us to hook into the native property lookup algorithm,
> otherwise the overhead of finding a HomeObject would be completely
> negligible because the native property lookup algorithm already finds the
> HomeObject where a property or method is located and therefore it would
> cost next to nothing to use the found HomeObject on a method call by
> passing HomeObject as an argument in the native side of the JS engine.
>
>
> */#!/*JoePea
>
> On Wed, Jul 27, 2016 at 7:58 AM, Allen Wirfs-Brock <allen at wirfs-brock.com>
> wrote:
>
>> The most common case is the “methods” are designed to be used as
>> constructors.  This has always be recognized for built-in methods in the
>> ECMAScript specification  which says: "Built-in function objects that are
>> not identified [in this specification] as constructors do not implement the
>> [[Construct]] internal method unless otherwise specified in the description
>> of a particular function.”.   When “concise methods” where add as part of
>> Object Initializers and Class Definitinos this default was applied to them.
>>
>> You can still define constructible properties for Object Initializers,
>> just not by using concise method syntax:
>>
>> ```js
>> let classes = {
>>   Cat: function() {},
>>   Dog: function() {},
>>   Bird: class {}
>> };
>>
>> let [c, d, b] = [new classes.Cat, new classes.Dog, new classes.Bird];
>> ```
>>
>>
>>
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160727/190dbdc3/attachment.html>


More information about the es-discuss mailing list