Help us understand the problem. What is going on with this article?

JavaScript - 配列のコピー

More than 5 years have passed since last update.

JavaScriptでは配列を単純な代入によってコピーしたあと、コピー先の配列に変更を加えると、同時に元の配列も変更されてしまうらしい。

改善前
(function() {
   var x = ["a0", "a1", "a2"];
   var y = x;
   y.push("a3");
   /* 配列を表示 */
   console.log(x);
   console.log(y);
})();

たとえば、上記のコードを実行すると配列x, 配列yはともに

["a0", "a1", "a2", "a3"]   // 配列x
["a0", "a1", "a2", "a3"]   // 配列y

と表示された。

オリジナルの配列まで変更される事態を回避する方法をいろいろ試してみると、
「しっかりと配列のコピーをつくってやればよい」ことが分かった。
以下のコードでは、配列yに対して配列xの要素を1つずつコピーすることにより、x全体をコピーしている。
この方法であれば、コピー後に配列yに加えた変更は元の配列xに影響を与えることはなかった。

改善後
(function() {
   var x = ["a0", "a1", "a2"];
   var y = [];
   for(var i = 0; i < x.length; i++) {
      y.push(x[i]);
   }
   y.push("a3");
   /* 配列を表示 */
   console.log(x); 
   console.log(y); 
})();

/* 出力結果 */
["a0", "a1", "a2"]         // 配列x
["a0", "a1", "a2", "a3"]   // 配列y

おまけ

これとは別の以下のような方法でもOKだった。

  1. 単純な代入によって配列xを配列yにコピーする.

  2. コピー先の配列yに変更を加える前に、
    JSON.parse(JSON.stringify(x))
    によって配列xを文字列化し、再び、オブジェクトにパース(解析)してxに代入する.

この方法で書くと次のようになる。

おまけ
(function() {
   var x = ["a0", "a1", "a2"];
   var y = x;
   x = JSON.parse(JSON.stringify(x));
   y.push("a3");
   /* 配列を表示 */
   console.log(x); 
   console.log(y); 
})();

/* 出力結果 */
["a0", "a1", "a2"]         // 配列x
["a0", "a1", "a2", "a3"]   // 配列y
daiiz
趣味でchrome アプリ/拡張機能を作っています。 https://github.com/daiiz/ http://daiiz.hatenablog.com/
https://scrapbox.io/daiiz/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away