extending an ES6 class using ES5 syntax?

John Lenz concavelenz at gmail.com
Mon May 16 20:31:36 UTC 2016

On Sun, May 15, 2016 at 6:23 PM, Rob Brackett <rob at robbrackett.com> wrote:

> > I'm trying to provide a path where common code can migrate to ES6
> classes before all the consumers have.   So I was really looking for
> something that didn't require the subclasses to be touched at all (I wasn't
> clear about this).
> I hope it was clear that newless supports this (functions, classes, and
> other newless constructors can all inherit from newless constructors and
> vice versa). Obviously there is the caveat noted in the README about
> dealing with `this`. In newless, it’s mostly a non-issue unless the *super*
> class needs to keep a reference to the actual instance that was created.
I didn't look as closely as I should have the first time around.

> You simply can’t get around the fact that calling an ES6 class constructor
> will create a new object instance, even if you already have one with the
> right prototype chain (Even when using `Reflect.construct()`, which you
> really can’t depend on in practice). Newless tries to work around this by
> setting the prototype of the instance you already had (i.e. the one a
> function constructor called `SuperConstructor.call(this)` with) to the
> object that was created when instantiating the underlying class
> constructor. This preserves all the instance properties, but means that the
> `this` in the superclass’s constructor is not the exact same object as the
> `this` in the subclass’s constructor. (It also *returns* the `this` from
> the superclass’s constructor, so a knowledgable inheriting function can
> work with that instead and be totally safe with no caveats.)
Having a different "this", multiple objects be instances and a unique
prototype chain per instance is a little too harsh for my usecase.

> > I have a fair amount of control over how the inheritance is setup and
> how the ES6 class is written but that is about it.
> However! If you are in control of the the class hierarchy from your class
> down to the root, you can do a little better than newless can if you are
> willing to get a little tricky:
> ```
> class FunctionInheritable {
>   constructor() {
>     return this._constructor.apply(this, arguments);
>   }
>   _constructor() {}
>   static call(context, ...args) {
>     return this.apply(context, args);
>   }
>   static apply(context, args) {
>     return this.prototype._constructor.apply(context, args) || context;
>   }
> }
> class YourActualLibraryClass extends FunctionInheritable {
>   // all your inheritable classes will have to use `_constructor` instead
> of `constructor`
>   _constructor(firstArg) {
>     // do whatever you want, there are no special requirements on what’s
> in here
>     this.something = firstArg;
>     global.libraryInstance = this;
>   }
>   someLibraryClassFunction() {
>     return this.something;
>   }
> }
> // any ES5 or earlier function-style “class” can now inherit with no
> changes
> function SomeEs5FunctionConstructor() {
>   this.somethingElse = 'whatever';
>   YourActualLibraryClass.call(this, 'something');
> }
> SomeEs5FunctionConstructor.prototype =
> Object.create(YourActualLibraryClass.prototype);
> ```
Having some variant of this (parallel ES5/ES6 construction) is what I'm
currently investigating.

> But, bottom line, you’re going to have to do something funky if you want
> to upgrade function-style classes in the middle of an inheritance chain to
> ES6 classes without imposing any changes on the ultimate subclasses at the
> end of the chain. ES6 simply goes out of its way to make it impossible to
> do that without some hackery, be it some code like the above, a tool like
> newless, or a transpiler (that does not fully enforce ES6 restrictions).
> As a *library* author, I’ve run into the same issues you have here—with
> rare exception, it’s still much too early to impose ES6-only support on a
> library’s users. It’s why libraries I work on generally haven’t moved to
> ES6 classes unless they’re doing something special as noted above.

Yes, we are on the same page here.  I just need to provide some guidance to
future developers that have this problem.

> Hope that helps,
> Rob
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160516/bcf0baa2/attachment-0001.html>

More information about the es-discuss mailing list