2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptにおけるイミュータブル設計とミューテーション制御:副作用を排したデータ構造戦略

Posted at

概要

JavaScriptはミューテーション(変更)を許容する言語だが、
だからといって変更可能な構造を野放しにすべきではない。

「イミュータブル(不変)」とは、
状態を直接変更せず、新しい状態として再生成する設計を意味する。
これは特に 状態管理 / UI更新 / ロジックの純粋性維持 において、
副作用を排除し、予測可能でテスト容易なコードを生むために不可欠である。

本稿では、イミュータブル設計の基本と実践、ミューテーションの制御戦略、データ構造の選定原則について体系的に解説する。


1. イミュータブル設計の基本原則

const user = { name: 'Taro', age: 25 };

// ❌ 直接変更(ミューテーション)
user.age = 26;

// ✅ イミュータブル(再生成)
const updatedUser = { ...user, age: 26 };
  • ✅ 既存オブジェクトを 変更せずに新たに生成
  • 変更のトラッキングや状態の差分検出が容易に

2. 配列操作におけるミューテーション対策

const list = [1, 2, 3];

// ❌ 直接push(ミューテーション)
list.push(4);

// ✅ スプレッドで追加(イミュータブル)
const newList = [...list, 4];

// ✅ フィルターで削除
const filtered = list.filter(n => n !== 2);
  • map, filter, reduce などの純粋関数的手法が有効
  • ソートやスプライスなどの破壊的操作は避ける

3. ネストされた構造の更新

const state = {
  profile: {
    name: 'Taro',
    contact: {
      email: 'taro@example.com'
    }
  }
};

// ✅ ネストを崩さず再生成
const updated = {
  ...state,
  profile: {
    ...state.profile,
    contact: {
      ...state.profile.contact,
      email: 'jiro@example.com'
    }
  }
};
  • ✅ 深い更新には 構造的再構成が必要
  • Immer.js などのライブラリで簡潔に保てる場合も

4. イミュータブル設計の利点

  • 予測可能な状態遷移(差分が明確)
  • 副作用の排除(データ汚染がない)
  • 時間的整合性の確保(過去の状態を参照可能)
  • テストが容易(状態の再現性が高い)
  • 状態比較が容易(シャロー比較で済むことが多い)

5. 状態管理における具体的適用:Reduxなど

function reducer(state, action) {
  switch (action.type) {
    case 'UPDATE_NAME':
      return {
        ...state,
        name: action.payload
      };
    default:
      return state;
  }
}
  • ✅ Reduxなどのライブラリは イミュータブル前提
  • reducerは副作用を含まない純粋関数として設計される

設計判断フロー

① その状態は他の箇所と参照共有されていないか?

② 状態更新の過程で、元の構造を破壊していないか?

③ ネスト構造は分割して更新可能か? → 分離して再構成できるか?

④ データ構造はスプレッドやmap/filterで扱える形か?

⑤ ライブラリ導入(Immerなど)によって可読性と安全性が向上するか?

よくあるミスと対策

obj[prop] = value による直接代入

→ ✅ スプレッド構文や関数的手段で再生成


❌ 破壊的操作(push, splice, sort)でデータが壊れる

→ ✅ 非破壊的なメソッドを選択。必要ならslice + concatなど


❌ ネストが深くなり再生成が困難

→ ✅ 状態の分割設計 or Immer.jsなどの支援ライブラリ活用


結語

イミュータブル設計とは、「書き換えない」という禁則ではない。
それは**“状態を外部から隔離し、予測可能な構造として制御するための設計戦略”**である。

  • 状態は再生成し、構造の流れとして追跡可能に
  • 参照を汚さず、副作用のない制御を保証
  • 状態変化を「イベントの履歴」として設計できる

JavaScriptにおけるイミュータブル設計とは、
“変化を安全に扱うための非破壊的構造戦略”である。

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?