2015-10-27 8 views
7

のNode.js 4.2.1に次のコードを実行している場合:JavaScriptでECMAScript 6クラスから古いスタイルのクラスを継承することはできますか?

'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の構文にオプトインすると、本当に脱出できません。

のようなコンストラクタ呼び出しであるsuper()の戻り値でthisキーワードを後で初期化することによって、ES6での継承が行われるという問題があります。現在の "初期化されていない"子インスタンスの親コンストラクタに "適用する"(.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で呼び出される必要がないこと、追加の利点を持っています(new.targetが空の場合MyDerivedを指定している限り)。