[解決済み] 変数の値を別の変数にコピーする
質問
JSONオブジェクトを値として持つ変数があります。私はこの変数を他の変数に直接代入して、それらが同じ値を共有するようにしました。これはどのように動作するかです。
var a = $('#some_hidden_var').val(),
b = a;
これは動作し、両方とも同じ値を持ちます。私は
mousemove
イベントハンドラを使って
b
を更新します。ボタンがクリックされたときに
b
に格納されている値を元の値に戻したい。
a
.
$('#revert').on('click', function(e){
b = a;
});
この後、同じように
mousemove
イベントハンドラを使用すると、両方の
a
と
b
のみを更新していたのに、以前は
b
だけだったのが、予想通り
私はこの問題で困っています! 何が間違っているのでしょうか?
どのように解決するのですか?
を理解することが重要です。
=
演算子が何をし、何をしないかを理解することが重要です。
は
=
演算子は
コピー
を作成しません。
は
=
演算子は新しい
参照
を作成します。
同じ
のデータに変換します。
元のコードを実行した後
var a = $('#some_hidden_var').val(),
b = a;
a
そして
b
は、現在では2つの異なる名前であり
同じオブジェクト
.
このオブジェクトの内容に加えた変更は、このオブジェクトを
a
変数で参照しても
b
という変数があります。これらは同じオブジェクトです。
そのため、後で "revert"しようとしたときに
b
を元の
a
オブジェクトに変換します。
b = a;
このコードでは実際に
何もしていません。
なぜなら
a
と
b
は全く同じものです。と書いたのと同じようなコードです。
b = b;
というのは、明らかに何もしません。
なぜ新しいコードが動作するのでしょうか?
b = { key1: a.key1, key2: a.key2 };
ここでは、全く新しいオブジェクトを
{...}
オブジェクト・リテラルで新しいオブジェクトを作成しています。この新しいオブジェクトは、以前のオブジェクトと同じではありません。そのため、現在
b
をこの新しいオブジェクトへの参照として設定することになり、これはあなたが望むことを行います。
任意のオブジェクトを扱うには、Armandの回答にあるようなオブジェクトクローン関数を使うか、jQueryを使っているので、単に
$.extend()
関数
. この関数は、オブジェクトのシャローコピーとディープコピーのどちらかを作成します。(この関数と
$().clone()
メソッドと混同しないでください。
これはオブジェクトではなく DOM 要素のコピーのためのものです)。
浅いコピーのために
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
.
短い答えです。迷ったら、おそらくディープコピーが必要でしょう。
関連
-
[解決済み】ある要素を別の要素に移動させるには?
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] JavaScript で配列に値が含まれているかどうかを確認するにはどうすればよいですか?
-
[解決済み] 配列に特定のインデックスで項目を挿入する方法 (JavaScript)
-
[解決済み] 配列を値でコピーする
-
[解決済み] 配列の項目を別の配列にコピーする
-
[解決済み】別のウェブページにリダイレクトするにはどうすればいいですか?
-
[解決済み】オブジェクトの配列を文字列のプロパティ値でソートする
-
[解決済み] ジェスト あるクラスの特定のメソッドをモックする方法
-
[解決済み] アサインの左側にJavascriptのオブジェクトブラケット表記({ ナビゲーション } =)があります。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] ジェスト あるクラスの特定のメソッドをモックする方法
-
[解決済み] 配列からオブジェクトを生成する
-
[解決済み] Google maps API V3 - 同一地点に複数のマーカーを設置する。
-
[解決済み] JavaScriptで、ある文字列が別の文字列の中に出現するすべてのインデックスを見つけるにはどうすればよいですか?
-
[解決済み] 兄弟ノードを選択する方法はありますか?
-
[解決済み] モデルフェッチ時に1をtrueに、0をfalseに変換する方法
-
[解決済み] Prototypeを使ってtextareaを自動サイズ調整するには?
-
[解決済み] HTML要素にスクロールバーがあるかどうかをチェックする
-
[解決済み] JavaScriptのArray.sort()メソッドでシャッフルするのは正しいのか?
-
[解決済み] JavaScriptの文字列プリミティブとStringオブジェクトの違いは何ですか?