Prompt
javascriptのスプレッド構文の注意点とは!
おー、JavaScriptのスプレッド構文の注意点だね!これは、便利な機能だからこそ、その「落とし穴」をしっかり理解しておくことが重要だよ。INFPの君が、技術の本質と、その安全な使い方を追求しているのが伝わってくるな。
結論から言うと、スプレッド構文の主な注意点は、**「浅いコピー(Shallow Copy)」と「予期せぬ上書き」**の2つだね!
スプレッド構文の注意点 ⚠️
1. 浅いコピー(Shallow Copy)であること
スプレッド構文は、オブジェクトや配列の**「一番上の階層」**しかコピーしないんだ。これは「浅いコピー」と呼ばれていて、深いネストを持つデータ構造を扱うときに思わぬバグの原因になることがあるよ。
-
どういうこと?
-
コピーした配列やオブジェクトの「トップレベルのプロパティ」は、元のものとは別の参照になる。
-
しかし、そのプロパティの値がオブジェクトや配列(つまり参照型)だった場合、新しいコピーと元のデータは同じ参照を共有し続けるんだ。
-
だから、コピーした側のネストされたオブジェクトや配列の中身を変更すると、元のデータも一緒に変更されてしまう、という副作用が発生するんだ。
-
-
例:
JavaScript
const original = { id: 1, name: 'Alice', profile: { theme: 'dark', lang: 'ja' } }; // スプレッド構文でコピー const shallowCopy = { ...original }; // トップレベルのプロパティを変更 -> OK! shallowCopy.name = 'Bob'; console.log(original.name); // 'Alice' (元のデータは変わらない) // ネストされたプロパティを変更 -> NG! shallowCopy.profile.theme = 'light'; console.log(original.profile.theme); // 'light' (元のデータも変わってしまった!) -
対策:
- 深いコピー(Deep Copy)が必要な場合は、スプレッド構文ではなく、
JSON.parse(JSON.stringify(obj))のような手法を使うか、lodashのcloneDeepのようなライブラリを使うのが一般的だよ。
- 深いコピー(Deep Copy)が必要な場合は、スプレッド構文ではなく、
2. プロパティの予期せぬ上書き
オブジェクトのスプレッド構文は、同じプロパティ名が複数存在する場合、後から書かれたものが優先されるという特性があるんだ。
-
どういうこと?
- オブジェクトリテラルの中で、スプレッド構文で展開されたオブジェクトと、明示的に書かれたプロパティに同じキーがあると、後に書かれたプロパティの値が優先されて、前の値が上書きされてしまう。
-
例:
JavaScript
const user = { id: 1, name: 'Alice', age: 30 }; const newInfo = { age: 31, // ageが上書きされる city: 'Tokyo' // 新しいプロパティが追加される }; const updatedUser = { ...user, // userオブジェクトを展開 ...newInfo // newInfoオブジェクトを展開 }; console.log(updatedUser); /* { id: 1, name: 'Alice', age: 31, // newInfo.ageで上書きされた city: 'Tokyo' } */ -
対策:
- この挙動を理解し、上書きしたいプロパティは、スプレッド構文の後に明示的に記述するようにしよう。意図しない上書きが起きないように、コードを書く順番に注意することが大切だよ。
3. Rest Parameters との混同
これは構文上の注意点だね。スプレッド構文と同じ ... 記号だけど、**「バラす」と「まとめる」**で役割が真逆になるんだ。
-
スプレッド構文: 関数呼び出し側やリテラルで使い、配列やオブジェクトをバラす。
- 例:
myFunc(...myArray)
- 例:
-
Rest Parameters: 関数定義側で使い、複数の引数を1つの配列にまとめる。
- 例:
function myFunc(...args)
- 例:
スプレッド構文は、これらの注意点を理解して正しく使えば、コードを非常に簡潔かつエレガントに保つことができる、強力なツールだよ。INFPの君が、技術の「光」と「影」を深く見つめるように、この構文もその特性を理解して、安全に使いこなしていこうね!