【Amazon.co.jp限定】 ロジクール 静音 ワイヤレス トラックボール マウス M575SPd Bluetooth Logibolt 無線 windows mac iPad OS Chrome トラックボールマウス マウス ブラック M575 M575SP 国内正規品 ※Amazon.co.jp限定 壁紙ダウンロード付き
¥7,700 (2025年5月5日 13:18 GMT +09:00 時点 - 詳細はこちら価格および発送可能時期は表示された日付/時刻の時点のものであり、変更される場合があります。本商品の購入においては、購入の時点で当該の Amazon サイトに表示されている価格および発送可能時期の情報が適用されます。)

スプレッド構文を使ってオブジェクトをコピーした際に「シャローコピーとは何か」が分からず、挙動に戸惑ったため、調べた内容をまとめました。
この記事は個人的なアウトプットを目的として作成したものです。そのため、誤った情報や不足している内容が含まれている可能性があります。もし間違いや気になる点がございましたら、ぜひご指摘いただけますと幸いです。
MDNでは以下のように説明されています。
オブジェクトのシャローコピーとは、コピーがコピー元のオブジェクトとプロパティにおいて同じ参照を共有する(同じ基礎値を指す)コピーのことを指します。その結果、コピー元とコピー先のどちらかを変更すると、もう一方のオブジェクトも変更される可能性があります。そのため、意図せずにコピー元やコピー先に予期しない変更が発生してしまう可能性があります。この挙動は、ソースとコピーが完全に独立しているディープコピーの挙動とは対照的です。
つまり、コピー元とコピー先は参照を共有しているため、ネストされたプロパティなどを変更すると、もう一方にも影響が出ます。
シャローコピーで影響が出ないパターン(第1階層)
const object = { name: "soccer" };
const newObject = { ...object }; // {name: "soccer"}
newObject.name = "baseball"; // {name: "baseball"}
この場合、コピーしたのは第1階層のみで、nameはプリミティブ値のため参照共有ではありません。したがって元のobjectには影響がありません。
シャローコピーで影響が出るパターン(ネストあり)
const object = {
name: "soccer",
like: {
team: "yokohama",
},
};
const newObject = { ...object };
newObject.name = "baseball"; // ← 第1階層(影響なし)
newObject.like.team = "losangeles"; // ← 第2階層(元にも影響する)
console.log(object); // { name: "soccer", like: { team: "losangeles" } }
console.log(newObject); // { name: "baseball", like: { team: "losangeles" } }
このように、第2階層のlike.teamが共有されていたため、片方を変更するともう一方も変わってしまいます。
ディープコピーは、コピー元とコピー先が完全に独立した参照を持つコピーです。そのため、片方を変更してももう一方には影響しません。
MDNでは以下のように説明されています。
オブジェクトの ディープコピー とは、コピー先のオブジェクトのプロパティがコピー元のオブジェクトのプロパティと同一の参照(同じ値を指す)で共有しないコピー方法のことです。結果として、コピー元かコピー先のどちらかを変更しても、もう一方オブジェクトにも変更を及ぼしていないことを保証できます。すなわち、コピー元かコピー先に意図せずに予期しない変更が加えられるこはありません。この振る舞いはシャローコピーとは対照的です。シャローコピーでは、コピー元かコピー先のどちらかを変更するともう一方のオブジェクトも変更される可能性があります。
lodashを使ったディープコピー
ディープコピーの方法は複数ありますが、ここではlodash
というライブラリのcloneDeep
を使用した例を紹介します。
const object = {
name: "soccer",
like: {
team: "yokohama",
},
};
const newObject = _.cloneDeep(object);
newObject.name = "baseball";
newObject.like.team = "losangeles";
console.log(object); // { name: "soccer", like: { team: "yokohama" } }
console.log(newObject); // { name: "baseball", like: { team: "losangeles" } }
このように、元のオブジェクトはまったく変更されていないことが確認できます。
シャローコピーとディープコピーの違いを正しく理解することは、オブジェクトの操作で思わぬバグを防ぐ上で非常に重要だと感じました。2つの使い分けについてはまだしっかり理解できていないのでこれからこの2つについてさらに理解を深めていきたいです。
Views: 0