🖨️
JavaScript ネストされた配列の深いコピー
結論
追記
JavaScriptのグローバルメソッドに追加された、structuredClone()
を使う
const arr = [{ a: 100, b: { c: 2, d: 4 } }, 3, [4, 5, [6, [7, 8, 9]]], 'a']
const copy = structuredClone(arr) // [{ a: 100, b: { c: 2, d: 4 } }, 3, [4, 5, [6, [7, 8, 9]]], 'a']
失敗する例
const arr = [1, 2, 3]
const copy = arr
copy[0] = 4
// copyだけ変更したはずなのに、arrも変わってしまう
console.log(arr, copy) // [4, 2, 3], [4, 2, 3]
配列のコピーが、浅いコピーになっているので、コピーした配列の要素を変更すると、コピー元の配列も変更されてしまう
これに対処するには、深いコピーをしてコピー元との関係を切り離す必要がある
一次元配列の深いコピー
const arr = [1, 2, 3]
const copy1 = [...arr]
const copy2 = arr.concat()
const copy3 = Array.from(arr)
const copy4 = arr.slice()
上記の方法だと、ネストされた配列はディープコピーされないので、ネストされた配列には別の方法でコピーをする
ネストされた配列の深いコピー
structuredClone()を使おう
JavaScriptのグローバルメソッドに追加された、structuredClone()
を使うことで簡単に深いコピーをすることが出来る
const arr = [{ a: 100, b: { c: 2, d: 4 } }, 3, [4, 5, [6, [7, 8, 9]]], 'a']
const copy = structuredClone(arr) // [{ a: 100, b: { c: 2, d: 4 } }, 3, [4, 5, [6, [7, 8, 9]]], 'a']
他の方法
mapを使う
二次元配列のみ対応
三次元配列や、配列以外のオブジェクトや値が入るとエラーが出てしまう
const arr = [
[1, 2, 3],
[4, 5, 6],
]
const copy = arr.map(v => v.map(v2 => v2))
JSON.parse, JSON.stringifyを使う
一次元配列、深いネスト、オブジェクト全てに対応。以前はこの方法が正解だった
const arr = [{ a: 100, b: { c: 2, d: 4 } }, 3, [4, 5, [6, [7, 8, 9]]], 'a']
const copy = JSON.parse(JSON.stringify(arr))
Discussion