2015-10-27 1 views
7

При выполнении следующего кода на Node.js 4.2.1:Возможно ли наследовать класс старого стиля из класса ECMAScript 6 в JavaScript?

'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();

Я получаю следующее сообщение об ошибке:

constructor(name) { 
     ^

TypeError: Class constructors cannot be invoked without 'new' 

Интересно, если это вообще возможно наследовать классы JavaScript «старого класса» из классов ECMAScript 6? И, если возможно, тогда как?

ответ

7

Нет выхода, если вы выбрали синтаксис class.

Проблема заключается в том, что наследование в ES6 производится поздней инициализацией this ключевого слова со значением возврата из super(), который является вызовом конструктора, как с new. Старая идиома «применения» (.call()) родительского конструктора на текущем «неинициализированном» дочернем экземпляре работает не более.

Что вы можете сделать, это обратиться к «паразитный наследование» - вы должны явно построить экземпляр, расширить его, и return это:

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

Когда вы делаете это с new MyClass, вы однако, прототип не будет установлен правильно. Для этого вам нужно будет использовать новую функцию ES6 Reflect.construct, который принимает класс ребенка как необязательный третий параметр:

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

Это имеет дополнительное преимущество, что MyDerived не нужно вызывать с new больше (если вы подаете MyDerived, когда new.target пуст).

Смежные вопросы