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