new instantiation design alternatives

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Sep 15 11:24:27 PDT 2014


On Sep 14, 2014, at 8:48 PM, Kevin Smith wrote:

> 
> Would this work?
> 
>     class C extends B {
>         constructor(a, b, c) : super(...gimmeSomeComplexSuperArgsYo(a, b, c)) {
>             // ...
>         }
>     }
> 
> Or using static helper methods, if you prefer:
> 
>     class C extends B {
>         constructor(a, b, c) : super(...this.gimmeSomeSuperArgsYo(a, b, c)) {

this would have to be:
     
constructor(a, b, c) : super(...new^.gimmeSomeSuperArgsYo(a, b, c)) {
                                              note^,  `new^` rather than `this`

On a `new` call we don't have a `this` at this point.  It's why we are calling the `super` constructor.  But thanks, this points out that even with this design we have to deal with `this` TDZ issues.


>             // ...
>         }
>         static gimmeSomeSuperArgsYo(a, b, c) {
>             // ...
>         }
>     }
> 
> If being (painfully) explicit is desired, then you could require the "new" in there:
> 
>     class C extends B {
>         constructor() : new super() { }
>     }
> 
> It seems to me that with the proposed design we're going to have to branch on "new^" continually:  if we don't, then the function will always fail if [Call]'ed and it contains a this-setter.
> 
> With the class create expression approach, that branch is taken care of automatically.

If you want a [[Call]] to the constructor to do an implicit `new`, then you need to branch on `new^`:

class C extends B {
   constructor (a,b,c) {
      if (!new^) return new C(a,b,c);
      // continue with instance initialization code
   }
}

But [[Call]] same as [[Construct]] is not normal default JS behavior, so it shouldn't be unexpected that you need to explicitly say something if that is what you want.  The whole point of new^ is that a constructor function that wants differing call vs construct behavior needs to explicitly implement the alternatives. Just like today, if you only want your constructors to support one or the other of [[Call]]/[[Construct]] you code for what you care about and errors will occurs if it is invoke the other way. 

Allen



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140915/99626139/attachment.html>


More information about the es-discuss mailing list