【JavaScript】filter()メソッドで生成される配列はシャローコピー?

filter() メソッドは、与えられた関数によって実装されたテストに合格したすべての配列からなる新しい配列を生成します。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

ここにあるように新しい配列を生成するを鵜吞みにしてガンガン組んでたら、後々何かがおかしいって気づいてから検証するとここに行きつくのに少々手間取ったりしてしまいます。

結論からいうと、filterで新しく生成される配列はシャローコピーです。

シャローコピ-って何?って方はシャローコピーとディープコピーの違いを調べてみてください。

とりとん
とりとん

早速コードを確認してみよう!

filter()メソッドで生成される配列を検証してみた

簡単に検証してみました。

JavaScript
let old_list = [
    {a:1, b:2, c:3},
    {a:2, b:3, c:4},
    {a:3, b:4, c:5},
]
let new_list = old_list.filter((item) => {return item.a == 1})

new_list[0].a = 2;

console.log(old_list)
console.log(new_list)

【出力結果】

old_list

0: {a: 2, b: 2, c: 3}
1: {a: 2, b: 3, c: 4}
2: {a: 3, b: 4, c: 5}

new_list

0: {a: 2, b: 2, c: 3}

このように、参照元の値まで変更してしまうときはシャローコピーされているということです。

完全に新しい配列を生成したい場合は、下記のようにディープコピーしましょう。

ちなみに、ディープコピーする方法はJSON.parse(JSON.stringify(lists))が多くヒットしますが、これだとundefindeのキーが消えてしまうといったこともあり、下記方法がオススメです。

JavaScript
let old_list = [
    {a:1, b:2, c:3},
    {a:2, b:3, c:4},
    {a:3, b:4, c:5},
]

let new_list = old_list.map(item => ({ ...item}))
new_list = new_list.filter((item) => {return item.a == 1})

new_list[0].a = 2;

console.log(old_list)
console.log(new_list)

【出力結果】

old_list

0: {a: 1, b: 2, c: 3}
1: {a: 2, b: 3, c: 4}
2: {a: 3, b: 4, c: 5}

new_list

0: {a: 2, b: 2, c: 3}
とりとん
とりとん

最後まで読んでいただきありがとうございました!


\ ぽちっと応援お願いします♪ /
ブログランキング・にほんブログ村へ人気ブログランキングへ
タイトルとURLをコピーしました