Private Constructors

One Problem I see with the MyClass.prototype.#constructor approach is that .constructor is just a regular property. The new operator calls the function passed as it's operand, not the prototype's constructor property. So while new and new# look very similar, their behavior is quite different. Also it quite breaks the "a class is just a function" concept. I'd prefer having just one constructor, a private one replacing the public one, that throws if it gets called with new from the outside (similar to the snippets above). Detecting from where the constructor was called could be made available through a Metaproperty just like new.target, e.g. new.self which is set if the function new is called on is the [[HomeObject]] of the function currently executing. Polyfilling would then also be quite easy:

    const _new = { self: false };

    class MyClass {
      constructor() {
        if(!_new.self) 
          throw new Error("MyClass has a private constructor and can only be constructed from within it's methods"); 
         _new.self = false;
          /*...*/
       }

       static create() {
         _new.self = true;
        new MyClass();
      }
    }

I think that would align quite nicely with the existing language and wouldn't be "too much magic". Also with this approach there is not yet another keyword (new#).

1 Like