Quantcast
Channel: 連想配列タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 129

[JS]オブジェクトや配列をコピーすると、コピー元の編集がコピー先にも反映される件

$
0
0

今日のコード

問題1 ふつうの値の場合

問題1
let a = 1;
let b = a;
a = 100; // 後からaにだけ100を代入し直す。
console.log(b); // さてbには何が入っているでしょう。 1? 100?

さて、これで出力される値は、どちらでしょうか?
正解は…

答え1
1

正解は、1ですね。これはまぁ、当然かと思います。
bにaが代入された時点で、b=1という、値が代入されているので、その後aに違う値が代入されても、bはそのまま1です。

問題2 オブジェクトの場合

問題2
let obj1 = {'one':''};
let obj2 = obj1;
obj1.one = ''; // 後からobj1にだけ「い」を代入し直す。
console.log(obj2); // さてこれは? 「あ」? 「い」?

これはどうか。

答え2
{one: "い"}

こちらでは、なんと再代入していない方(再代入前にコピーされたもう一方)も、値が「い」になってしまいました。

問題3 配列の場合

問題3
let arr1 = [1,2,3];
let arr2 = arr1;
arr1[0] = 10000; // 後からarr1にだけ10000を代入し直す。
console.log(arr2[0]); // さてこれは? 1? 100?

こちらはどうか。

答え3
10000

はい。オブジェクトの場合と同様に、再代入していない方(再代入前にコピーされたもう一方)にも、影響がありました。
以下で詳しく説明します。

どういうことか

これは、JavaScriptのコピー(値を渡す挙動)における仕様によるものです。

JavaScriptでは、配列やオブジェクトがコピーされた場合(値が渡された場合)、基本的に参照渡しで渡される。

つまり、新しいarr2やobj2が作られて、新たに値が入れられるわけではない。
実は内部的には、arr2はarr1と同じものを常に参照しているだけ、(obj2はobj1を常に参照しているだけ)という状態になっている。

これにより、コピー元を変更すると、コピー先も影響を受けてしまうので、注意が必要です。
コピーしたい場合は、使い勝手が良いと噂のlodashの「_.deepClone関数」などを使うようにしましょう。


Viewing all articles
Browse latest Browse all 129

Trending Articles