2012-11-02 15 views
6

私はプロトタイプ継承を使用するJavaScriptプロジェクトで作業しています。私がそれを使用することを決めた方法は以下の通りです:プロトタイプ継承がコンストラクタを2回呼び出す

var MySuperClass = function (param) { 
    this.prop = param; 
}; 
MySuperClass.prototype.myFunc = function() { 
    console.log(this.prop); 
}; 

var MySubClass = function (param) { 
    MySuperClass.call(this, param); 
}; 
MySubClass.prototype = new MySuperClass(); 
MySubClass.prototype.constructor = MySubClass; 

var obj = new MySubClass('value'); 
obj.myFunc(); 

継承を重視しています。

問題は、各クラス(スーパーとサブ)のコンストラクタにconsole.logを入れた場合、スーパークラスはサブクラスに渡されたときに一度二度呼び出されます。MySubClass.prototype = new MySuperClass();サブクラスのコンストラクターで 'コンストラクターを盗まれた'ときは、パラメーターを1回使用します。

これらのパラメータを保存しようとするとエラーが発生する可能性があります。つまり、空のパラメータを処理するロジックを追加する必要があります。

は、私がこれを行う場合今:

var MySubClass = function (param) { 
    MySuperClass.call(this, param); 
}; 
MySubClass.prototype = MySuperClass; 
MySubClass.prototype.constructor = MySubClass; 

すべてが正常に動作しているようですが、私は誰もが(私のGoogl'ingで)前にこれを行う見たことがありません。

2番目のものが間違っていると(それはCrockfordの継承関数に似ているように見えます)、どうすれば2番目に発火しないように修正するのですか?これを行う

+0

[ここに「新しい」キーワードを使用する理由は何ですか?](http://stackoverflow.com/questions/12592913/what-is-the-reason-to-use -the-new-keyword-here) – Bergi

答えて

7

は正しい解決策ではありません。

MySubClass.prototype = MySuperClass; 

あなたはプロトタイプの代わりに、プロトタイプオブジェクトとしての機能自体を設定しているので、あなたが期待するものを継承していません。


あなたは正しいです。これを行うとコンストラクタが呼び出され、問題が発生する可能性があります。

MySubClass.prototype = new MySuperClass(); 

ソリューションは、継承を設定するためにObject.createを使用することです。これは、提供されたオブジェクトから継承する新しいオブジェクトを提供しますが、コンストラクタを呼び出すことはありません。

MySubClass.prototype = Object.create(MySuperClass.prototype); 

は今、あなたはMySuperClass.prototypeから継承MySubClass.prototypeに割り当てられたオブジェクトを持っていますが、実際には、コンストラクタを呼び出す必要があったことはありません。


非ES5準拠した実装はObject.createをサポートしていませんが、あなたはそれのために(部分)シムを作ることができます。

if (!Object.create) { 
    Object.create = function(proto) { 
     function F(){} 
     F.prototype = proto; 
     return new F(); 
    }; 
} 

繰り返しますが、これは完全なシムではありませんが、それだけで十分なプロトタイプオブジェクトを参照するコンストラクタを呼び出すことなく、継承されたオブジェクトを作ることができるようにエミュレートします。

+0

ありがとうございます。 – obie

+0

よろしくお願いします。 –