<div dir="ltr">You seem to be suggesting that ES6 should be making it easier for you to reimplement a core ES6 language feature. If you want `class`, can you not use `class`? That's what users who have access to ES6+ environments are likely to do anyways.<div><br></div><div>It's also worth noting that someone could do `constructor: () => {}` or `constructor: function *() {}` and `new`ing them would fail the same way.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 15, 2017 at 5:25 PM, /#!/JoePea <span dir="ltr"><<a href="mailto:joe@trusktr.io" target="_blank">joe@trusktr.io</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">> Because they're methods, not functions. The distinction between the<br>
> two was merely semantic in ES5, but now it's mechanical, due to<br>
> super(); constructing something intended as a method would make<br>
> super() behave in confusing and unintuitive ways, so methods just<br>
> don't have a constructor any more.<br>
<br>
</span>You are correct for app authors, but wrong for library authors. A<br>
library author may easily like to make an object that contains ES5<br>
constructors, and writing them like<br>
<br>
```<br>
let ctors = {<br>
  Foo() {},<br>
  Bar() {},<br>
}<br>
```<br>
<br>
is simply simple.<br>
<br>
For example, suppose a library author releases a `Class` function for<br>
defining classes, it could be used like this:<br>
<br>
```<br>
const Animal = Class({<br>
  constructor: function() {<br>
    console.log('new Animal')<br>
  }<br>
})<br>
```<br>
<br>
but most JS authors who don't know about these pesky new JavaScript<br>
language internals might be inclined to write:<br>
<br>
<br>
```<br>
const Animal = Class({<br>
  constructor() {<br>
    console.log('new Animal')<br>
  }<br>
})<br>
```<br>
<br>
If the `Class` implementation returns that "constructor", then when<br>
the user does `new Animal` they will get an unexpected error, and that<br>
is not ideal at all for a dynamic language like JavaScript.<br>
<br>
What's even stranger is that the `Class` implementation can wrap the<br>
concise method with a [[Construct]]able function and call the concise<br>
method with `.call` or `.apply` and it will work! But that is simply<br>
just messy and ugly.<br>
<br>
So why prevent it from working only sometimes? It would be much better<br>
for it to just work all the time, and make restrictions only when<br>
`super` is present in the function body. In the above example, the<br>
`constructor() {}` concise method does not use the keyword `super`, so<br>
treating it like `constructor: function constructor() {}` would be<br>
much more ideal.<br>
<br>
We shouldn't limit developer creativity for reasons that don't exist<br>
(I haven't heard of any compelling reasons so far).<br>
<br>
The new language features cause failures in unexpected ways, and I<br>
really don't think the language should be designed in this<br>
less-intuitive way.<br>
<br>
JavaScript pre-ES6 has a dynamic nature, but ES6 and newer features<br>
are less-so in that tradition.<br>
<span class=""><br>
> Making this one niche use-case ("I want to define several constructor-only classes inline in an object initializer") require a few characters less is not a sufficiently worthwhile benefit for the cost.<br>
<br>
</span>Actually, no, I want to allow end-users of my library to pass in<br>
objects containing methods and properties, and I don't want the result<br>
to fail in unexpected ways, and I also don't want to write ugly and<br>
hacky code to make it work.<br>
<span class=""><br>
> Just type the few extra characters (exactly what you would have typed in ES5, so it's not even a new imposition), and you'll be fine.<br>
<br>
</span>Like I said, it won't be me typing these things, it will be end users.<br>
Yes I can disguise the problem, but if I for example were implementing<br>
a `Class` tool, I wouldn't like to wrap their non-constructable<br>
methods in a proxy function just to make it work not only because it<br>
is ugly, but because it will show things in the console that are more<br>
difficult to debug.<br>
<br>
For example, have you ever looked at classes made with Backbone? They<br>
are not so nice to inspect because Backbone wraps constructors and<br>
prototypes like an onion.<br>
<br>
This language "feature" of concise methods that makes them not<br>
constructable forces library authors to write ugly code who's output<br>
is harder to inspect and debug by end developers.<br>
<span class="HOEnZb"><font color="#888888">/#!/JoePea<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
On Sat, Jul 30, 2016 at 3:04 AM, /#!/JoePea <<a href="mailto:joe@trusktr.io">joe@trusktr.io</a>> wrote:<br>
>>  The distinction between the two was merely semantic in ES5, but now it's<br>
>> mechanical, due to super(); constructing something intended as a method<br>
>> would make super() behave in confusing and unintuitive ways, so methods just<br>
>> don't have a constructor any more.<br>
><br>
> So, if `super` were dynamic, then it would be no problem.<br>
><br>
>> It's been explained to you already in previous threads why super() is<br>
>> designed the way it is, and how a dynamic super() would add significant cost<br>
>> to some situations<br>
><br>
> Those "some situations" haven't been listed yet (or I don't know where they<br>
> are listed). Do you know any? As far as I can tell, a dynamic super would<br>
> perform just fine:<br>
><br>
> - For constructor calls, `HomeObject` can just the `.prototype` property of<br>
> the function when `new.target` is the same as the function being<br>
> constructed. That's simple.<br>
> - If `new.target` is not the current constructed function, then the current<br>
> function was found on the prototype chain of<br>
> `Object.getPrototypeOf(new.<wbr>target)` (i.e. tje `.constructor` property was<br>
> found on some `HomeObject` in the prototype chain) and then that function is<br>
> called with the found `HomeObject`. This seems like a simple addition to the<br>
> property lookup algorithm.<br>
> - Functions called as methods simply have `HomeObject` passed as the<br>
> prototype (HomeObject) where they were found. This seems like a simple<br>
> addition to the property lookup algorithm.<br>
> - What else?<br>
><br>
> Based on those ideas from my limited knowledge on thetopic, a dynamic<br>
> `super` doesn't seem to "costly".<br>
><br>
> Suppose I write<br>
><br>
> ```js<br>
> obj.foo()<br>
> ```<br>
><br>
> Then, in ES5, there is already going to be a property lookup algorithm to<br>
> find `foo` on the prototype chain of `obj`. Therefore, when the<br>
> property`foo` is found on a prototype (a HomeObject), it doesn't seem like<br>
> all that much extra cost to simply pass that found object by reference to<br>
> the `foo` method call, since we already found it. That's not very costly.<br>
><br>
> I may be using the word "HomeObject" wrong, but I think you get what I mean.<br>
><br>
><br>
> /#!/JoePea<br>
><br>
> On Thu, Jul 28, 2016 at 9:11 AM, Tab Atkins Jr. <<a href="mailto:jackalmage@gmail.com">jackalmage@gmail.com</a>><br>
> wrote:<br>
>><br>
>> On Wed, Jul 27, 2016 at 11:44 AM, /#!/JoePea <<a href="mailto:joe@trusktr.io">joe@trusktr.io</a>> wrote:<br>
>> > What's the good reason that object-initializer methods can't be<br>
>> > constructors<br>
>> > though? I mean, I get that "that's what spec says", but what's the<br>
>> > actual<br>
>> > good reason?<br>
>><br>
>> Because they're methods, not functions. The distinction between the<br>
>> two was merely semantic in ES5, but now it's mechanical, due to<br>
>> super(); constructing something intended as a method would make<br>
>> super() behave in confusing and unintuitive ways, so methods just<br>
>> don't have a constructor any more.<br>
>><br>
>> There are several very similar ways you can write your example that do<br>
>> achieve what you want. As Allen said, you can just use the non-concise<br>
>> syntax, explicitly typing "function" (or better, "class") for each of<br>
>> the values.  This is only a few characters more and achieves exactly<br>
>> what you want.<br>
>><br>
>> It's been explained to you already in previous threads why super() is<br>
>> designed the way it is, and how a dynamic super() would add<br>
>> significant cost to some situations.  Making this one niche use-case<br>
>> ("I want to define several constructor-only classes inline in an<br>
>> object initializer") require a few characters less is not a<br>
>> sufficiently worthwhile benefit for the cost.  Just type the few extra<br>
>> characters (exactly what you would have typed in ES5, so it's not even<br>
>> a new imposition), and you'll be fine.<br>
>><br>
>> ~TJ<br>
><br>
><br>
</div></div><div class="HOEnZb"><div class="h5">______________________________<wbr>_________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" rel="noreferrer" target="_blank">https://mail.mozilla.org/<wbr>listinfo/es-discuss</a><br>
</div></div></blockquote></div><br></div>