1

Yes, this question is about using Es5 to extend a native Es6 class that was declared using the class keyword and which has not been transpiled to Es5 and not the other way around.

Why would anyone do that? I have a library that needs to be strict Es5 but users of that library might be using Es6 native classes, at least possibly during development without using a transpiler. Now the library contains a functionality where given such a class it needs to dynamically create a subclass of that class, however without using the class keyword and more specifically without using the super keyword. A proper subclass implementation however needs to call the super constructor which in this case would be the constructor of the Es6 class and which in Es6 would not to be done using the super keyword.

From an Es5 perspective the Es6 base class is a simple function (the constructor), however I don't see a way how to properly invoke that function.

Is there a way to invoke the Es6 constructor in an Es5 compatible source code file without using eval-like programming?

  //Es6 Code class declaration
  class BaseClass {
    constructor(foo){
      this.foo = foo;
    }
  }

  // "Typescript-Es5-extends-style" helper method
  var __extends = (this && this.__extends) || (function () {
        var extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return function (d, b) {
          extendStatics(d, b);
          function __() { this.constructor = d; }
          d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
      })();

  // subclass declaration
  var SubClass = (function (_super) {
    __extends(SubClass, _super);
    function SubClass() {
      // Error: super keyword unexpected
      //super();

      // Error: Class constructor BaseClass cannot be invoked without 'new'
      // BaseClass();
      // return Function.prototype.bind.apply(_super, [this].concat(arguments))();
      return _super.apply(this, arguments) || this;
    }
    return SubClass;
  }(BaseClass));

  // Instantiation  
  // won't work (Class constructor BaseClass cannot be invoked without 'new')
  new SubClass();
Community
  • 1
  • 1
Sebastian
  • 7,729
  • 2
  • 37
  • 69
  • Why use "classes" in ES5...? Why not use prototypal inheritance like the language was created to do? – evolutionxbox Mar 27 '17 at 08:31
  • 1
    @evolutionxbox - I answered exactly your question even before you asked it in my second paragraph. There is more than one party involved here and the parties could be disagreeing upon which flavor to use. – Sebastian Mar 27 '17 at 08:36
  • Fair point. I should read the actual question next time... – evolutionxbox Mar 27 '17 at 08:37
  • 1
    "*I have a library that needs to be strict Es5*" - can you expand on that? Why can't you write it in ES6 and provide a transpiled version for those who need it? In any case, it is impossible to subclass ES6 classes with only ES5, you need either `Reflect` or `class` – Bergi Mar 27 '17 at 09:59
  • @Bergi - The library file needs to execute properly in an ES5 environment, thus it may not use Es6 syntax to parse properly. I could provide different versions, but that is inconvenient for both the user as well as the library authors. I would even resort to `eval()`-ing the subclass. The `Reflect` approach with the third argument sounds promising, though, thanks for identifying the duplicate! – Sebastian Mar 27 '17 at 12:00
  • Yes, I just meant that to subclass an ES6 `class` you need to use some ES6 features, though you can make the script not break in ES5 environments – Bergi Mar 27 '17 at 13:45

0 Answers0