そういえば最近のJavascriptのことが全然わからないなと思い、個人的にちょっとひっかかってしまった問題をやってみました。
大概は浅いコピーで済むんですけど、たまにディープコピーが欲しいなっていうことがあります。それで作ってみました。
あんまりよくわかってないんですけど、ディープコピーって多分こんな流れだと見当をつけました。
- もし、配列なら、配列
をシャローコピーして各要素に再帰的にディープコピーをかける // mapで新しい配列が作られるのでシャローコピー(.slice()いれてました)不要でした。@hoo-chanありがとうございました。 - 配列でなければ単純に(そのまま)返す
いろいろ試行錯誤してこんな感じになりました。
// Arrayをディープコピーする関数
//clone = a => Array.isArray(a) ? a.slice().map(clone) : a //.slice()不要だった
clone = a => Array.isArray(a) ? a.map(clone) : a
const a = [[[0,0],[0,0]],[[1,1],[1,1]]]
const b = clone(a)
b[1][1][1] = 2
//console.log(`a : ${a}\nb : ${b}`)
console.log(`a : ${JSON.stringify(a)}\nb : ${JSON.stringify(b)}`)
// 結果:console.log(`a : ${a}\nb : ${b}`)の出力 //表示がフラットになって構造が不明
//a : 0,0,0,0,1,1,1,1
//b : 0,0,0,0,1,1,1,2
// 結果:console.log(`a : ${JSON.stringify(a)}\nb : ${JSON.stringify(b)}`)の出力
// 配列の構造まで表示(編集リクエスト@hoo-chanより)
a : [[[0,0],[0,0]],[[1,1],[1,1]]]
b : [[[0,0],[0,0]],[[1,1],[1,2]]]
わーいちゃんとコピーできてる!
意外とすっきりでした。
配列とプリミティブな要素限定なので厳密なものではないですが、使いどころがわかって使う分には十分だと思います。
実際書いてみて、新しい書き方がなんとなくわかってきました。
アローとか map とか const とか ${} とか、その他いろいろ。
おかしいよ、とか、もっといい方法があるよ、とかありましたらコメントおねがいします。