2017-09-24 4 views
1

ES6クラスで簡単なORMを作成すると、ブロック問題が発生します。クラスを正しくコピーできません(ES5ではutil.extendと同じです)。ES6クラスのオブジェクトコンストラクタをクローンする方法は?

具体的には、ここで私が試したものです:

class BaseModel { 

    echo() { 
    console.log(this.props); 
    } 

    static _setProperties(props) { 
    this.props = props; 
    } 

} 

function makeModel(props) { 

    // Try to copy the Class object 
    const Model = 
     Object.assign(Object.create(Object.getPrototypeOf(BaseModel)), BaseModel); 

    // Copy my static methods – is there a better way to do this? 
    Object.getOwnPropertyNames(BaseModel).forEach((key) => { 
    if (!key.startsWith('_')) return; 
    Model[key] = BaseModel[key]; 
    }); 

    // Configure the new model 
    Model._setProperties(props); 
    return Model; 
} 

const GreeterModel = makeModel('hello'); 
const greeter = new GreeterModel(); 
greeter.echo(); // Should log hello 

私が手にエラーがある:

TypeError: GreeterModel is not a constructor 

はES6クラスでこれを達成する方法はありますか、私はに固執する必要がありますES5スタイル?

オプションの質問:静的メソッドをコピーするより良い方法はありますか? getOwnPropertyNamesのソリューションは、lengthのような読み取り専用のプロパティも返すので理想的ではありません。

ありがとうございます!

+0

'Object.create'は関数を作成しません。このコードはES5でも機能しません。 – Bergi

+0

なぜES6 'class extends'を使うのではないのですか? – Bergi

答えて

5

基本クラスにロジックミスがあります。 thisは常に関数の呼び出し方法に依存します。静的関数は通常コンストラクタで呼び出されます。つまり、BaseModel._setProperties(...)です。この場合、thisBaseModelを指します。 インスタンスメソッドはインスタンス自体で呼び出されるため、thisはコンストラクタではなくインスタンスを参照します。これは、「クローンではないされていることを

function makeModel(props) { 
    class Model extends BaseModel {} 
    Model._setProperties(props); 
    return Model; 
} 

注意:あなたが

echo() { 
    console.lof(this.constructor.props); 
} 

を使用するようにしかし、あなたの実際の質問に答える必要がありますBaseModel仕事は、あなたは、単にクラスを拡張することができますようにするに

"基本クラスは、それを拡張しています。 JavaScriptで関数をクローンする合理的な方法はありません。

関連する問題