2016-12-01 6 views
4

問題を説明するのは簡単ではありませんが、サンプルコードを見てください。リテラルオブジェクトの属性としての配列

var test = { 
 
\t my_array: [], 
 
\t my_var: '' 
 
} 
 

 

 
var a = Object.create(test); 
 
var b = Object.create(test); 
 

 

 
a.my_array.push('aaa'); 
 
b.my_array.push('bbb'); 
 

 
a.my_var = 'this is obj A'; 
 
b.my_var = 'this is obj B'; 
 

 

 
document.write(a.my_array[0]); //output: aaa 
 
document.write('<br>'); 
 
document.write(b.my_array[0]); //output: aaa 
 
document.write('<br>'); 
 
document.write(a.my_var); //output: this is obj A 
 
document.write('<br>'); 
 
document.write(b.my_var); //output: this is obj B

方法であること、オブジェクトBはオブジェクトと同じ配列値を持っている可能性が?

答えて

2

が共有するという2つのオブジェクトを1つのプロトタイプオブジェクトとして作成しました。オブジェクトのプロトタイプのプロパティは、オブジェクトプロパティの参照中に見つかります。作成時にオブジェクトインスタンスにコピーされません。

あなたは

a.my_var = 'this is obj A'; 

のようにオブジェクトのプロパティに値を代入すると、プロパティが以前prototypeプロパティであっても、オブジェクトのローカル「自分」プロパティになります。そのような割り当てによってプロトタイプのプロパティ値を変更することはできません。

+0

[OK]を、私は問題を理解しています。しかし、どうすればそれを解決できますか?リテラル表記のクラスから分離した配列を持つseperatオブジェクトを作成することは可能ですか? –

+0

@EvgeniTch新しいオブジェクトのプロパティを直接初期化する必要があります。通常、コンストラクタ関数でそれを行います。あるいは 'Object.assign()'を使うこともできます。 – Pointy

0

あなたがしかここに1つの配列オブジェクトを、作成している:

my_array: [] 

あなた Object.createことから、新しいオブジェクトは、その配列が再インスタンス/ /重複クローン化することになるだろうされていません。どちらのインスタンスも同じ配列オブジェクトを共有します。

この問題(https://jsfiddle.net/dafuaLkj/)を回避する方法:

Objects

EDIT(私はちょうどconsole.log(a, b)を作る):答えを完了するに

0

は、このイメージはかなり明示的です。

var test = function() { 
    this.my_array = []; 
    this.my_var = '' 
} 


var a = new test(); 
var b = new test(); 
+2

さて、写真から、 'a .__ proto__'と' b .__ proto__'は同じオブジェクトであることは明らかではありません。 – georg

+0

あなたのコメントでは、今です。ありがとう@georg – Fefux

0

あなたがやっていることは簡単なクローニングです。あなたが望むのはディープクローンです。深いクローンを作成するには、他の選択肢を使用する必要があります。これは、ここにObject.create()があるため、割り当てられているプロパティがオブジェクトまたは配列であるときにプロパティ参照をコピーします。

オブジェクトの深いコピー(つまり、プロトタイプチェーンを歩いているすべてのネストされたプロパティの再帰的コピー)が必要な場合は、別のアプローチを使用する必要があります。以下に例を示します。 (Source: MDN

function clone(objectToBeCloned) { 
 
    // Basis. 
 
    if (!(objectToBeCloned instanceof Object)) { 
 
    return objectToBeCloned; 
 
    } 
 

 
    var objectClone; 
 
    
 
    // Filter out special objects. 
 
    var Constructor = objectToBeCloned.constructor; 
 
    switch (Constructor) { 
 
    // Implement other special objects here. 
 
    case RegExp: 
 
     objectClone = new Constructor(objectToBeCloned); 
 
     break; 
 
    case Date: 
 
     objectClone = new Constructor(objectToBeCloned.getTime()); 
 
     break; 
 
    default: 
 
     objectClone = new Constructor(); 
 
    } 
 
    
 
    // Clone each property. 
 
    for (var prop in objectToBeCloned) { 
 
    objectClone[prop] = clone(objectToBeCloned[prop]); 
 
    } 
 
    
 
    return objectClone; 
 
} 
 

 
var test = { 
 
\t my_array: [], 
 
\t my_var: '' 
 
} 
 

 

 
var a = clone(test); 
 
var b = clone(test); 
 

 

 
a.my_array.push('aaa'); 
 
b.my_array.push('bbb'); 
 

 
a.my_var = 'this is obj A'; 
 
b.my_var = 'this is obj B'; 
 

 

 
document.write(a.my_array[0]); //output: aaa 
 
document.write('<br>'); 
 
document.write(b.my_array[0]); //output: aaa 
 
document.write('<br>'); 
 
document.write(a.my_var); //output: this is obj A 
 
document.write('<br>'); 
 
document.write(b.my_var); //output: this is obj B

+0

元の質問には何も起こっていません。 – Pointy

+0

これはまさに私が達成したかったものです。ありがとうございました!!! –

1

あなたがオブジェクトを作成する方法は、my_arrayプロパティは、両方のオブジェクトで同じ参照を持つことになりますので。私は期待される結果を達成するための簡単な適応を提供しました。

var test = function() { 
 
    return { 
 
\t my_array: [], 
 
\t my_var: '' 
 
    } 
 
} 
 

 
var a = Object.create(test()); 
 
var b = Object.create(test()); 
 

 
a.my_array.push('aaa'); 
 
b.my_array.push('bbb'); 
 

 
a.my_var = 'this is obj A'; 
 
b.my_var = 'this is obj B'; 
 

 
document.write(a.my_array[0]); //output: aaa 
 
document.write('<br>'); 
 
document.write(b.my_array[0]); //output: aaa 
 
document.write('<br>'); 
 
document.write(a.my_var); //output: this is obj A 
 
document.write('<br>'); 
 
document.write(b.my_var); //output: this is obj B

関連する問題