Why are object initializer methods not usable as constructors?

Andrea Giammarchi andrea.giammarchi at gmail.com
Wed Jul 27 20:09:07 UTC 2016


I hope you're not using `Object.assign` to copy anything different from
basic setup-like or arguments objects: if I were you I would use
`Object.defineProperties(targetProto,
Object.getOwnPropertyDescriptors(superProto))` or it gonna be "bad time".

I think they answered already on the dynamic super, not sure keep raising
the issue would help :-(

Best Regards

On Wed, Jul 27, 2016 at 8:13 PM, /#!/JoePea <joe at trusktr.io> wrote:

> > 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/e501cf61/attachment-0001.html>


More information about the es-discuss mailing list