2016-05-06 12 views
1

私は1つのイベントウィジェットで作業していて、奇妙な振る舞いを見つけました。以下は Javascriptの代入演算子奇妙な振る舞い

は、イベントオブジェクト内部の競争の私は

var event={0:{competition:{like:false}}} 
console.log(event[0].competition.like); //returns false 
var cmpt=event[0].competition; 
cmpt.like=true; 
console.log(event[0].competition.like) //returns true 

に取り組んでいたコードブロックあなたはなぜ属性の値は、[のように]、私は理解を助けることができます更新取得されています。 このイベントオブジェクトや更新されていないイベントオブジェクトを防止するにはどうすればよいですか?

私はgoogle /を調べてみましたが、それらの質問は別の問題に対処していました。

+0

あなただけの参照ではなく、オブジェクトをコピーしています。 –

+1

これは、javascriptオブジェクトが参照渡しであるため、競合オブジェクトを複製する必要があるように動作させるためです。 – jcubic

+1

文字列でも数字でもない場合は、参照(ポインタ)です。 (それを指すのではなく)オブジェクトをコピーするには、prototypeが 'event [0] .competition'に設定された新しいオブジェクトを作成する' Object.create(event [0] .competition) ' – slebetman

答えて

3

あなたは属性の値、イベントオブジェクトの内部 競争の[ように]

を更新なっている理由私は、理解を助けることができますが、参照をコピーこの割り当てを行うことによりevent[0].competitioncmptに設定します。

cmptは、event[0].competitionが指しているのと同じオブジェクトを指しています。したがって、値を更新すると、基本的に両方の変数が指している同じオブジェクトに変更が加えられます。

どのように私はこれを防ぎ、イベントオブジェクトを更新することはできませんか?

古い値は更新されませすべきことを確実にしたい場合は

を割り当てる際、あなたはディープクローンオブジェクトに必要

var cmpt=JSON.parse(JSON.stringify(event[0].competition)); 
+0

ありがとうございました。私は、新しい変数でオブジェクトをコピーするためにjQuery.cloneを使用しました。 – Ravi

1

あなたは、変数cmpt

event[0].competition 

への参照を代入し、それが価値だ変更されている - あなたは元のインスタンスで行います何がJavaScriptオブジェクトでも

1

cmpt変数に影響を及ぼします常に参照によって渡されます。つまり、オブジェクトを別の変数に代入すると、そのオブジェクトは同じオブジェクトを指しています。 2つの別々のオブジェクトが必要な場合は、そのオブジェクトを複製する必要があります。あなたは_.clone() method from lodash libraryを使用して、たとえば、これを行うことができます

var cmpt = _.clone(event[0].competition); 
1

var cmpt=event[0].competition; 

を交換してくださいあなたがオブジェクトを持って、そしてあなたが「コピー」するときに、新しいオブジェクトに行ったようにそれを、古いオブジェクトが更新され、新しいオブジェクトを変更します。

この

は、あなたが実際にそれをコピーしていないので、あなただけ。これは

1

...ので、今まで何を「コピー」に変更元に反映され、元のオブジェクトへの別の参照を、持っていますあなたが別の変数にオブジェクト値を割り当てるときにJavaScriptで、あなたは実際に(primitve値がやるように、それは、コピーされません)に値を代入しています。

したがって、'cmpt 'と'event [0] .competition'は同じオブジェクトを参照します。

オブジェクトを複製する必要があり、プリミティブ値、配列、および単純なオブジェクト(関数なし)のみが含まれている場合は、'JSON.stringify 'と'JSON.parse'を使用できます。

1

なぜ、私はちょうどイベントの名前を変更していますか、あなたはこのようにすることができます。

var event={0:{competition:{like:false}}} 
console.log(event[0].competition.like); //returns false 
var cmpt = {}; 
cmpt.like = event[0].competition.like; 
cmpt.like = true; 
console.log(event[0].competition.like) //returns false 
1

次を使用することができます。

var event={0:{competition:{like:false}}} 
console.log(event[0].competition.like); //returns false 
var cmpt=jQuery.extend({}, event[0].competition); 
cmpt.like=true; 
console.log(event[0].competition.like) //returns false (changed) 
1

とどのように私はこれを防ぎ、イベントオブジェクトを更新することはできませんか?

あなたはnullに設定された第1パラメータにObject.create()を使用することができます。 、Object.create()の2番目のパラメータでプロパティ記述子のvalueevent[0].competition特性を反復null、各プロパティの値を設定し、nullevent[0].competitionセットの新しく作成されたオブジェクトを有するプロパティを返します。

var event = { 
 
    0: { 
 
    competition: { 
 
     like: false 
 
    } 
 
    } 
 
} 
 

 
console.log(event[0].competition.like); //returns false 
 

 
var cmpt = Object.create(null, { 
 
    competition: { 
 
    value: (function(obj) { 
 
     var _obj = {}; 
 
     for (var prop in obj) { 
 
     _obj[prop] = null 
 
     }; 
 
     return _obj 
 
    }(event[0].competition)), 
 
    writable: true, 
 
    enumerable: true, 
 
    configurable: true 
 
    } 
 
}); 
 
cmpt.competition.like = true; 
 
console.log(event[0].competition.like, cmpt.competition.like 
 
      , event[0], cmpt) //`false, `true`