=
JavaScript の演算子が行うことと行わないことを理解することが重要です。
=
オペレータはなりませんコピーデータのを。
=
オペレータは、新しい作成し、参照に同じデータを。
元のコードを実行した後:
var a = $('#some_hidden_var').val(),
b = a;
a
そしてb
今、2つの異なる名前である同じオブジェクト。
このオブジェクトの内容に加えた変更は、a
変数を介して参照する場合もb
変数を介して参照する場合も同じように表示されます。それらは同じオブジェクトです。
したがって、後でこのコードb
を使用して元のa
オブジェクトに「戻そう」とすると、次のようになります。
b = a;
とまったく同じものであるため、コードは実際には何もしません。コードは、作成した場合と同じです。a
b
b = b;
明らかに何もしません。
新しいコードが機能するのはなぜですか?
b = { key1: a.key1, key2: a.key2 };
ここでは、{...}
オブジェクトリテラルを使用して新しいオブジェクトを作成しています。この新しいオブジェクトは、古いオブジェクトと同じではありません。したがってb
、この新しいオブジェクトへの参照として設定しているので、必要な処理を実行できます。
任意のオブジェクトを処理するには、Armandの回答に記載されているようなオブジェクトのクローン作成関数を使用できます。または、jQueryを使用しているため、$.extend()
関数を使用するだけです。この関数は、オブジェクトの浅いコピーまたは深いコピーを作成します。(これを、オブジェクトではなくDOM要素をコピーするための$().clone()
メソッドと混同しないでください。)
浅いコピーの場合:
b = $.extend( {}, a );
または深いコピー:
b = $.extend( true, {}, a );
浅いコピーと深いコピーの違いは何ですか?浅いコピーは、オブジェクトリテラルで新しいオブジェクトを作成するコードに似ています。元のオブジェクトと同じプロパティへの参照を含む新しい最上位オブジェクトを作成します。
オブジェクトに数値や文字列などのプリミティブ型のみが含まれている場合、ディープコピーとシャローコピーはまったく同じことを行います。しかし、あなたのオブジェクトが内部にネスト他のオブジェクトや配列が含まれている場合は、浅いコピーはしませんコピーし、それらのネストされたオブジェクトを、それは単にそれらへの参照を作成します。したがって、ネストされたオブジェクトで、最上位オブジェクトと同じ問題が発生する可能性があります。たとえば、次のオブジェクトがあるとします。
var obj = {
w: 123,
x: {
y: 456,
z: 789
}
};
そのオブジェクトの浅いコピーを行う場合x
、新しいオブジェクトのプロパティはx
元のオブジェクトと同じオブジェクトです。
var copy = $.extend( {}, obj );
copy.w = 321;
copy.x.y = 654;
これで、オブジェクトは次のようになります。
// copy looks as expected
var copy = {
w: 321,
x: {
y: 654,
z: 789
}
};
// But changing copy.x.y also changed obj.x.y!
var obj = {
w: 123, // changing copy.w didn't affect obj.w
x: {
y: 654, // changing copy.x.y also changed obj.x.y
z: 789
}
};
これはディープコピーで回避できます。ディープコピーは、ネストされたすべてのオブジェクトと配列(およびArmandのコードのDate)に再帰し、トップレベルのオブジェクトのコピーを作成したのと同じ方法でそれらのオブジェクトのコピーを作成します。したがって、変更copy.x.y
しても影響はありませんobj.x.y
。
短い答え:疑問がある場合は、おそらく深いコピーが必要です。
a
設定された.val()
場合、それは正しいですか?JSON.parse(a)
ある時点で実際のオブジェクトを取得するために使用しますか?