Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to inherit old-style class from ECMAScript 6 class in JavaScript?

When running the following code on Node.js 4.2.1:

'use strict';

var util = require('util');

class MyClass {
  constructor(name) {
    this.name = name;
  }
}

function MyDerived() {
  MyClass.call(this, 'MyDerived');
}

util.inherits(MyDerived, MyClass);

var d = new MyDerived();

I get the following error:

constructor(name) {
         ^

TypeError: Class constructors cannot be invoked without 'new'

I wonder if it is at all possible to inherit old-style JavaScript "classes" from ECMAScript 6 classes? And, if possible, then how?

like image 739
weekens Avatar asked Oct 27 '15 13:10

weekens


People also ask

Which inheritance is not supported in JavaScript?

JavaScript does not support multiple inheritance. Inheritance of property values occurs at run time by JavaScript searching the prototype chain of an object to find a value.

Do classes exist in JavaScript 6 ES6?

What are ES6 classes? In ES6, the "class" keyword and associated features are a new approach to creating prototype constructors. They are not true classes in a way that would be familiar to users of most other object-oriented languages.

Is inheritance possible in JavaScript If yes what type is possible?

When it comes to inheritance, JavaScript only has one construct: objects. Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype.

How JavaScript inherits from another class?

We use the extends keyword to say that this class inherits from another class. The Professor class adds a new property teaches , so we declare that. Since we want to set teaches when a new Professor is created, we define a constructor, which takes the name and teaches as arguments.


1 Answers

There's not really a way out once you've opted in to class syntax.

The problem is that inheritance in ES6 is done by late-initialising the this keyword with the return value from super(), which is a constructor call like with new. The old idiom of "applying" (.call()) the parent constructor on the currently "uninitialised" child instance does work no more.

What you can still do is to resort to "parasitic inheritance" - you'll have to explicitly construct the instance, extend it, and return it:

function MyDerived() {
  var derived = new MyClass('MyDerived');
  … // set up properties
  return derived;
}

When you do this with new MyClass, you won't get the prototype set up correctly however. For that, you will need to use the new ES6 Reflect.construct function, which takes the child class as an optional third parameter:

function MyDerived() {
  var derived = Reflect.construct(MyClass, ['MyDerived'], new.target||MyDerived);
  … // set up properties
  return derived;
}

This has the additional benefit that MyDerived doesn't need to be called with new any more (as long as you supply MyDerived when new.target is empty).

like image 53
Bergi Avatar answered Sep 22 '22 00:09

Bergi