2012-01-30 10 views
6

は、次のコードを見てみましょう:あなたはnew Human()を検査する場合JavaScriptの継承:派生メンバーはどこですか?

function Primate() { 
    this.prototype = Object; 
    this.prototype.hairy = true; 
} 

function Human() { 
    this.prototype = Primate; 
} 

new Human(); 

、何hairyメンバーはありません。私は1つあると期待します。 Primateから継承する別の方法がありますか? Object.create()(ECMAScript5は私のシナリオで使用するのは問題ありません)を含む何か?

+0

あなたがjsの中に、この理解するための継承を読まなければならない:http://javascript.crockford.com/inheritance.htmlとhttp://javascript.crockford.com/prototypal.html – bfavaretto

+1

あなたはそれを間違っている。 'Primate'と' Human'のコンストラクタの 'prototype'オブジェクトを操作したいとします。新しく作成されたインスタンス(コンストラクタ内の 'this'値)は関数ではないため、' prototype'プロパティを追加するのは無意味です。 –

+0

プロトタイプチェーンにパッチを当てるのではなく、Object.createを使ってオブジェクトを作成して拡張します。コンストラクタとして関数を使用すると、JavaScriptオブジェクトをクラスのような構造として実装しているため、混乱を招く可能性があります。 – rxgx

答えて

4

コードが記述されると、new Human()を使用して作成されたオブジェクトの値は、Primate関数への参照であるprototypeと呼ばれるプロパティになります。それは明らかにあなたが望むものではありません(それは特別ではありません)。

いくつかのこと:

  • あなたは通常(newオペレーター付き)コンストラクタとして使用されることを意図しています機能prototypeを変更したいです。つまり、Humanprototypeを設定する(のインスタンスHumanではありません)。

  • もしprototypeに割り当てる値がインスタンス所望のタイプのなければならない(または、全くの初期化作業が必要ない場合には、所望のタイプのprototype)コンストラクタへ、ない参照。

  • Object(またはObjectインスタンス)を関数のprototypeに明示的に割り当てる必要はありません。これは暗黙的です。

    function Primate() { 
        this.hairy = true; 
    } 
    
    function Human() {} 
    Human.prototype = new Primate(); 
    Human.prototype.constructor = Human; 
    
    var h = new Human(); 
    

    hによって参照Humanが値trueでhairyというプロパティを持っています

はおそらくもっとこのような何かをしたいです。前の例で

は、hairyPrimateHuman.prototypePrimateのインスタンスを割り当てなければならない理由である、呼び出される一度だけその値が割り当てられます。代わりに、このような初期化が必要ないように記述することもできます。

例:

function Primate() {} 
Primate.prototype.hairy = true; 

function Human() {} 
Human.prototype = Primate.prototype; 
Human.prototype.constructor = Human; 

var h = new Human(); 
関連する問題