Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

shallow copy と deep copy の違いを理解する:JavaScriptにおけるオブジェクト構文設計の核心

Posted at

概要

オブジェクトを「コピーしたつもり」なのに、なぜか元の値も変わってしまう。
この現象の正体が、**shallow copy(浅いコピー)と deep copy(深いコピー)**の違いだ。

JavaScriptでは、コピーしただけでは“すべての値”が複製されるとは限らない。
特にネスト構造を持つオブジェクトや配列を安全に扱うためには、コピーの仕組みを理解し、目的に応じた設計的選択が必要だ。


対象環境

JavaScript(ES6以降)  
ブラウザ / Node.js 両対応

結論:shallow copy は“参照をコピー”するだけ

✅ shallow copy(浅いコピー)

const original = { user: { name: 'toto' } };
const copy = { ...original };

copy.user.name = 'bob';

console.log(original.user.name); // ❌ 'bob'(元データが変わる)

... は top-level のプロパティしかコピーしない
→ ネストされたオブジェクトは参照ごとコピーされる


✅ deep copy(深いコピー)

const original = { user: { name: 'toto' } };
const copy = structuredClone(original);

copy.user.name = 'bob';
console.log(original.user.name); // ✅ 'toto'

structuredClone() は再帰的に中身ごとコピーする


shallow copy の代表的な方法

方法 説明
Object.assign({}, obj) ES5〜 可読性やや低
{ ...obj } ES6〜 モダン記法
Array.slice() 配列のshallow copy

deep copy の安全な実装方法

✅ structuredClone(最も推奨)

const copy = structuredClone(obj);
  • ✅ ネストされた配列・オブジェクト・Dateなども安全に複製
  • ❌ 関数やSymbol、DOMノードなどはコピー不可

※ Chrome 98+, Node 17+(Polyfillあり)


❌ JSON方式(非推奨)

const copy = JSON.parse(JSON.stringify(obj));
  • ❌ Date → 文字列になる
  • ❌ undefined や関数 → 消える
  • ❌ 循環参照 → エラー

✅ ライブラリを使う(例:lodash)

import cloneDeep from 'lodash/cloneDeep';
const copy = cloneDeep(obj);
  • ✅ 検証済みの安全なdeep copy
  • ❌ バンドルサイズが増える可能性に注意

状態管理における正しい設計

React / Vue などのフレームワークで状態管理を行う場合:

  • useState() で更新するときは 新しいオブジェクトを生成する必要がある
  • 既存のstateを shallow copy して、そのまま子要素を mutate → バグの温床
// ❌ NG: mutateしてしまう
const newState = { ...state };
newState.user.name = 'bob';

// ✅ OK: ネストごとコピー
const newState = structuredClone(state);
newState.user.name = 'bob';

パフォーマンス考慮

  • shallow copy → 高速、だが用途限定
  • deep copy → 遅くなる可能性あり、だが安全性が高い

→ ✅ 設計時に「どこまでの変更が必要か」「元データに副作用を与えるべきか」を判断軸にする


設計判断のフロー

データがネストしている? → Yes
↓
元データに影響させたくない? → Yes
↓
→ deep copy(structuredClone or cloneDeep)

↓

データがflat or 参照可でも問題なし? → Yes
↓
→ shallow copy(スプレッド構文 / assign)

結語

shallow copy か deep copy かという選択は、ただの記法の問題ではない。
それは「オブジェクトがどこに責任を持つべきか」という設計そのものである。

  • 元のオブジェクトと結びついていてもいいのか?
  • 安全性と可読性、どちらを優先すべきか?
  • コードベースに副作用がどこまで波及するか?

コピーの深さ=設計の深さ。
JavaScriptのコピー処理は、常に意図と責任を明示するための設計選択である。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

Qiita Conference 2025 will be held!: 4/23(wed) - 4/25(Fri)

Qiita Conference is the largest tech conference in Qiita!

Keynote Speaker

ymrl、Masanobu Naruse, Takeshi Kano, Junichi Ito, uhyo, Hiroshi Tokumaru, MinoDriven, Minorun, Hiroyuki Sakuraba, tenntenn, drken, konifar

View event details
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?