5

のは、私はPlayerオブジェクトがあるとしましょう:それは素晴らしい作品JS Prototypal継承:子は同じ親プロパティを使用しますか?

var player = function(name) { 
    this.handlers = {}; 
} 

player.prototype.on = function(event, callback) { 
    if (!this.handlers[event]) { 
     this.handlers[event] = []; 
    } 
    this.handlers[event].push(callback); 
} 

、私は選手を作成することができ、それぞれがハンドラの独自のセットを持っています。今、私はplayerから継承する必要があるとします

var testPlayer = function(name) { 
    this.name = name; 
}; 

testPlayer.prototype = new player(); 

私はtestPlayer年代を作成するときに今、それらのそれぞれが同じhandlers特性を共有:

var adam = new testPlayer('Adam'); 
adam.on('test', function(){}); 

var eve = new testPlayer('Eve'); 
// eve.handlers == {'test':<function>} 

私はここで何をしないのですか?私はすべてtestPlayerのプロトタイプが同じであると理解していますnew player子クラスを記述するときに作成するオブジェクトです。しかし、すべてのtestPlayersが独自のハンドラセットを持つための方法はありますか?

答えて

5

古典的な継承に使用されていたものは確かに奇妙に見えますが、プロトタイプの継承がどのように機能するのでしょうか。インスタンスごとに個別のハンドラオブジェクトを持つには、子コンストラクタで1つを指定する必要があります。これは、同じ名前のプロトタイプのプロパティをシャドウします:

var testPlayer = function(name) { 
    this.name = name; 
    this.handlers = {}; 
}; 

testPlayer.prototype = new player(); 

別の解決策は、あなたのon方法から、オンデマンド、このシャドウイングプロパティを作成するには、次のようになります。

player.prototype.on = function(event, callback) { 
    // Check for a handlers property on the instance 
    if(!this.hasOwnProperty('handlers') { 
     this.handlers = {}; 
    } 
    if (!this.handlers[event]) { 
     this.handlers[event] = []; 
    } 
    this.handlers[event].push(callback); 
} 

興味深い事実

これは、プロトタイプのオブジェクト(または配列)のプロパティを変更する場合にのみ問題になります。プロトタイプに存在するプロパティに割り当てると、ローカルシャドウイングプロパティが自動的に作成されます(インスタンスからプロトタイププロパティに割り当てることはできません)。

+1

1を、これは最も使用可能なように見えます。 –

+0

私は同意する、それは完全に有効なプログラミングのパラダイムだ。厄介な部分は、 'ハンドラー 'を使うあらゆるメソッドにこのようなチェックを追加しなければならないということです。 – MaxArt

+0

コンストラクタから1つの 'init'メソッドを呼び出し、そこから実行することができます。これは、プロトタイプ上のオブジェクト(または配列)のプロパティを変更する場合にのみ問題になることに注意してください。プロトタイプに存在するプロパティに割り当てると、ローカルシャドウイングプロパティが自動的に作成されます(インスタンスからプロトタイププロパティに割り当てることはできません)。 – bfavaretto

1

ここでの問題は、handlersコンストラクタで追加されたプロパティがあるので、あなたは

testPlayer.prototype = new player(); 

を行うときにtestPlayer.prototypeに真新しいplayerオブジェクトのすべてのプロパティを追加し、ということだということですは、handlersを含む。

だから、そこにすべてのtestPlayerオブジェクト内のhandlers財産だ、とあなたはhandlersにプロパティを追加するときは、プロトタイプではなく、testPlayerオブジェクトのオブジェクトにプロパティを追加しています。

つまり、onメソッドを呼び出すときは、またはeve.handlersではなく、testPlayer.prototype.handlersにプロパティを追加しています。

安全のために、定義:「別の解決策」について

var testPlayer = function(name) { 
    this.name = name; 
    this.handlers = {}; 
}; 
関連する問題