<div dir="ltr">For demo sake, I was talking about something like this in ES5:<div><br></div><div>```js</div><div><div>Object.defineProperty(</div><div>  Function.prototype,</div><div>  'new',</div><div>  {</div><div>
    configurable: true,</div><div>    get: function() {</div><div>      var Constructor = this;</div><div>      Object.defineProperty(</div><div>        Constructor,</div><div>        'new',</div><div>        {</div>
<div>          value: function(/*...args*/) {</div><div>            // ES6: return new Constructor(…args);</div><div>            var</div><div>              o = Object.create(</div><div>                Constructor.prototype</div>
<div>              ),</div><div>              r = Constructor.apply(o, arguments)</div><div>            ;</div><div>            switch(typeof r) {</div><div>              case 'undefined':</div><div>              case 'boolean':</div>
<div>              case 'number':</div><div>              case 'string':</div><div>                return o;</div><div>              default: // including null</div><div>                return r || o;</div>
<div>            }</div><div>          }</div><div>        }</div><div>      );</div><div>      return Constructor.new;</div><div>    }</div><div>  }</div><div>);</div></div><div><br></div><div>// example</div><div>function A() {}</div>
<div><br></div><div>A.new() instanceof A; // true<br></div><div>```</div><div><br></div><div>Regards</div><div><br></div><div>P.S. please note, in case you do like above idea, some quirky engine will fail without weird tricks on lazy reassignment.</div>
<div>I can write a more appropriate one if needed.</div><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Aug 21, 2014 at 3:30 AM, Andrea Giammarchi <span dir="ltr"><<a href="mailto:andrea.giammarchi@gmail.com" target="_blank">andrea.giammarchi@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I like the `Function.prototype.new` hint but unless it's an implicitly<br>
self bound method you still cannot easily pass it around as callback<br>
for a map without binding it all over.<br>
<br>
`arr.map(MyClass.new)` without needing to explicitly bind it each time<br>
is needed/used would be an exception, but probably a good one.<br>
<br>
Regards<br>
<br>
<br>
Sent from my Windows Phone From: Allen Wirfs-Brock<br>
Sent: ‎8/‎21/‎2014 1:19<br>
To: <a href="mailto:brendan@mozilla.org">brendan@mozilla.org</a><br>
Cc: <a href="mailto:es-discuss@mozilla.org">es-discuss@mozilla.org</a><br>
Subject: Re: Promise() vs. new Promise()<br>
<div class="HOEnZb"><div class="h5"><br>
On Aug 20, 2014, at 1:11 PM, Brendan Eich wrote:<br>
<br>
> Alex Kocharin wrote:<br>
>> I mean, not using `new`. JS is a functional language after all, and having a function that can't be called as a function is weird.<br>
><br>
> Gotcha, and my point was not to mandate `new`, just allow it. I thought we relaxed things so `new` was optional if there was no issue leaving it out:<br>
><br>
> <a href="http://esdiscuss.org/topic/make-class-constructors-work-with-call-too" target="_blank">http://esdiscuss.org/topic/make-class-constructors-work-with-call-too</a><br>
><br>
> But that was a while ago.<br>
><br>
>> If constructor supports calling it without new, I can pass it around as a function, do this for example:<br>
>><br>
>> ```<br>
>>> >  ['foo', 'bar'].map(Error)<br>
>> [ [Error: foo], [Error: bar] ]<br>
>> ```<br>
>><br>
>> With mandatory `new` this would be much less elegant.<br>
><br>
> Agreed, mandating `new` where there's no issue (legacy, e.g., Date; or other?) would be Bad(tm).<br>
><br>
>> I was about to construct realistically-looking chain with [fn1, fn2, fn3].map(Promise).forEach(addThenHandler), but FF already seem to throw on it.:(<br>
><br>
> Hrm.<br>
<br>
We've talked about this several times at TC39 meetings and the<br>
consensus has always been to not conflate the meaning of new C() and<br>
C() for new built-in constructors.<br>
<br>
The problem is that is difficult to correctly code  (in ES code) a<br>
constructor function that has this behavior. Even assuming there is a<br>
way to reliably determined if you were called  with or without `new`<br>
you still need to have to separate logic paths for the two cases and<br>
there are other subclassing issues (more below).  For these reasons,<br>
we should expect that most constructors defined using `class` will<br>
require use of  `new` to instantiate them.<br>
<br>
If as  matter of principle, we shouldn't be specifying built-ins that<br>
do things in a way that is difficult to reproduce in ES code and we<br>
shouldn't be encouraging  usage patterns  that confuse people or are<br>
error prone to implement.<br>
<br>
If you want a purely functional way to do instantiation, then I<br>
suggest adding a `new` method to Function.prototype:<br>
`<br>
   Function.prototype = function new(...args) {return new this(...args);<br>
`<br>
<br>
Back to subclassing, assume that Map was implemented in ES, something like this:<br>
( **called-via-new** is a placeholder for new syntax)<br>
`<br>
class Map {<br>
   constructor(...args) {<br>
      if (! **called-via-new**) return new Map(...args);<br>
      // initialize this using args<br>
   }<br>
   //methods<br>
}<br>
<br>
//then the  following do the same thing:<br>
var m = Map();<br>
var m = new Map;<br>
`<br>
You might then,  reasonably expect to code<br>
`<br>
class ExtendedMap extends Map {<br>
   additionalMethod() {}<br>
}<br>
`<br>
but if you do, you will discover:<br>
`<br>
var m = ExtendedMap();  //actually creates an instance of Map<br>
var m = new ExtendedMap; //actually creates an instance of ExtendedMap;<br>
`<br>
the problem is that the Map constructor explicitly references `Map`<br>
rather than the actually invoked constructor and there is no good may<br>
to determine what the actual constructor was.  So to make the subclass<br>
work correctly you have to remember to code the subclass as:<br>
`<br>
class ExtendedMap extends Map {<br>
   constructor(...args)  {<br>
        if (! **called-via-new**) return new ExtendedMap(...args);<br>
        return new super(...args);<br>
   }<br>
   additionalMethod() {}<br>
}<br>
`<br>
<br>
and repeat a pattern like this in every other subclass you write.<br>
Much better to just avoid this sort ot two-faced constructors.<br>
<br>
Alen<br>
_______________________________________________<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" target="_blank">https://mail.mozilla.org/listinfo/es-discuss</a><br>
</div></div></blockquote></div><br></div>