2011-11-22 7 views
9

で期待どおりに動作していない私は、次のコードで予期しない結果を得る:JavaScriptのprototypeプロパティは配列とオブジェクトフィールド

var TestModel, u, u2; 

function TestModel() {} 
TestModel.prototype.a = null; 
TestModel.prototype.b = []; 

u = new TestModel(); 
u.a = 1; 
u.b.push(1); 

u2 = new TestModel(); 
u2.a = 2; 
u2.b.push(2); 

console.log(u.a, u.b);  // outputs: 1 [1,2] 
console.log(u2.a, u2.b); // outputs: 2 [1,2] 

を私はそれは驚くべきu.bu2.bTestModelの各インスタンスかかわらず、同じ値が含まれていることを見つけますプロトタイプのセットアップ方法に応じて独自のインスタンス変数を持つ必要があります。だから、これは私が期待していた出力は次のようになります。私はオブジェクトで、配列としてそれを使用するのではなく、その上にキーを設定するbを設定した場合

console.log(u.a, u.b);  // expecting: 1 [1] 
console.log(u2.a, u2.b); // expecting: 2 [2] 

同じことが起こります。私はここで何を理解していないのですか?

答えて

1

どちらの場合も、配列は非常に同じ配列、つまりプロトタイプに設定した配列です。

TestModel.prototype.b 
u.b 
u2.b 

は、彼らはすべて同じプロパティを参照してください。これは、これらのすべてが[1, 2]になるように、両方の.push呼び出しは、その配列に作用していることを意味します。

通常、プロトタイプは関数に使用されるため、すべてのインスタンスが同じ機能を共有します。 に変更してのプロトタイププロパティを変更すると、すべてのインスタンスにも反映されますが、この場合はおそらく望ましくありません。インスタンスにそれぞれカスタム配列が必要な場合は、プロトタイプ経由ではなく、インスタンスごとにカスタム宣言も宣言します。

13

にはの値が割り当てられ、にはという値が割り当てられます。

u.a = 1; 

uによって参照されるオブジェクトに新しいaプロパティを作成します。割り当て前に、u.aTestModel.prototype.aに言及するが、新しい値を割り当てることは、実際に、実際のオブジェクトに新しいプロパティを作成します。

enter image description here

割付後

:他方

enter image description here

手、

u.b.push(1); 

ではなく、新しいプロパティを作成します。これは既存のプロパティである配列TestModel.prototype.bを参照します。

TestModelの各インスタンスは、私はすべてのインスタンスは、それゆえ、彼らはプロトタイプが持っている同じプロパティを参照、同じプロトタイプを参照プロトタイプにセットアップに

をしたかに応じて、独自のインスタンス変数を持つべきであるにもかかわらず。 TestMode.prototype === u.bTestMode.prototype === u2.bおよびu.b === u2.bがすべてtrueであることを簡単に確認できます。あなたにもu.bu2.bにも同様に新しい値を割り当てる場合、それがうまくいく

u.b = []; 

は、通常は、コンストラクタで行われます。

function TestModel() { 
    this.b = []; 
} 
+0

どうもありがとう:

あなたは、このような、独自の配列を持つように各インスタンスをしたいです!私はその微妙な違いを認識していませんでした。ですから、基本的には、他の場所で操作する前に、自分のコンストラクタのすべてのインスタンス変数を初期化する必要があります。 – hiddentao

+0

@hiddentao:そうです。プリミティブ型をデフォルト値としてプロトタイプのプロパティに割り当てるのは問題ありませんが、 "インスタンスごと"の場合は、オブジェクトと配列をコンストラクタで初期化する必要があります。私は通常プロトタイプのプロパティを定義しますが、 'TestModel.prototype.a'のように' null 'で初期化します。 –

+0

@Felix、あなたはTestModelの値の素晴らしいチャートを得るためにどのツールを使用していましたか? –

3

プロトタイプのプロパティは正反対ですプロトタイプのポイントは、すべてのインスタンスが自動的に同じプロトタイププロパティを共有するため、各インスタンスに対して再定義関数は必要ないということです。

function TestModel() { 
this.a = null; 
this.b = []; 
} 
関連する問題