2016-06-23 11 views
0

JavaScriptで新しいオブジェクトをインスタンス化して、そのオブジェクトのプロパティの1つとして別のオブジェクトがある場合、そのオブジェクトは常に同じオブジェクトを参照しますか?例えば新しいオブジェクトのインスタンス化参照同じプロパティ

function test() {} 

test.prototype.state = { 
    num: 0 
}; 

var obj1 = new test(); 
var obj2 = new test(); 

obj1.state.num = 1; 

console.log(obj1.state.num,obj2.state.num); // Outputs 1 1 instead of 1 0 

また、何それは新しいオブジェクトのプロパティにそれがインスタンス化されるたびに作成させるための適切な方法だろうか?

+0

これはプロトタイプのためのものです。プロトタイプではなく、コンストラクター関数自体がプライベート変数である場合は、オブジェクトをインスタンス化するたびに異なるものを取得します – Redu

答えて

2

これはプロトタイプなので、すべてのインスタンス間で共有オブジェクトです。 { num: 0 }オブジェクトは明示的に1回しか作成されていないため、1回だけ存在します。新しいtestをインスタンス化するときにJavascriptがクローンしません。通常、プロトタイプはファンクションに使用されますが、これは何の違いもありません。あなたはインスタンス固有の属性が必要な場合は、コンストラクタ関数でそれらを作成する必要があります。

function test() { 
    this.state = { num: 0 }; 
} 
+0

興味深いことに、私はそれを知りませんでした。それを達成する他の方法はありますか? –

+0

基本的に:いいえ。もちろん、多かれ少なかれ同様のことをするために後方に曲げる方法はたくさんありますが、どうしてでしょうか?インスタンス固有の属性/値はコンストラクタ関数で 'this'に代入することによって定義され、 'prototype'は全てのものの間で共有されます。それがどのように機能するのですか? – deceze

0

私は、次のコードで説明したいと思います。

function test() { 
 
    var o = {a:1}; 
 
    this.geto = function(){return o.a}; 
 
    this.seto = function(v){o.a = v}; 
 
} 
 

 
test.prototype.p = {a:0}; 
 

 
var obj1 = new test(); 
 
var obj2 = new test(); 
 

 
obj1.p.a = 100; 
 
obj1.seto(50); 
 
console.log(obj1.p.a); // <- 100 
 
console.log(obj2.p.a); // <- 100 
 
console.log(obj2.geto()); // <- 1 
 
console.log(obj1.geto()); // <- 50

は、最初のコードであり、閉鎖され、それが共有されていません。すべてのインスタンス化されたオブジェクトには別のクロージャがあります。プロトタイプ版ではクロージャはなく、すべてのインスタンス化されたオブジェクトはコンストラクタのプロトタイプで全く同じオブジェクトにアクセスします。

さらに複雑なクロージャの共有があり、私はhereについて説明しましたが、クロージャ自体をプロトタイプで共有しています。

0

あなたのコードでは、.status.numはインスタンスではなくクラスに属しているようです。コードを次のように変更します。

function test() { 
    this.state = {num:0};//instance property 
} 
var obj1 = new test(); 
var obj2 = new test(); 

obj1.state.num = 1; 

console.log(obj1.state.num,obj2.state.num);//1 0 as expected 
関連する問題