LoginSignup
1
0

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-06-14

今日のコード

問題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関数」などを使うようにしましょう。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0