2
4

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

概要

副作用(side effect)は、プログラムにおける見えない変化の根源である。
特にJavaScriptのような柔軟な言語では、副作用は便利さと同時に予測困難な挙動の原因ともなる。

本稿では、純粋関数の原則、副作用の識別と分離、制御構造としての活用戦略に焦点を当てる。
テスト容易性や拡張性を高める上で、副作用をどのように扱うべきか、その設計視点を明確にする。


1. 純粋関数 vs 非純粋関数

// 純粋関数
function add(a, b) {
  return a + b;
}

// 非純粋関数(副作用あり)
function addAndLog(a, b) {
  const result = a + b;
  console.log(result); // ← 副作用
  return result;
}
  • 純粋関数は入力に対して出力が常に一定
  • ❌ 非純粋関数は外部とのやり取りを含み、テストが困難

2. よくある副作用の例

種類 具体例
I/O console.log(), alert(), fetch() など
DOM操作 document.querySelector(), appendChild()
状態変更 グローバル変数の書き換え
時間参照 Date.now(), setTimeout() など
ランダム性 Math.random()

3. 副作用の分離設計

// ✗ ロジックと副作用が混在
function updateAndRender(data) {
  const transformed = transform(data);
  document.body.innerHTML = render(transformed);
}

// ✓ 分離された構造
function update(data) {
  return transform(data);
}

function applyToDOM(html) {
  document.body.innerHTML = html;
}
  • ✅ ロジックと出力(副作用)を明確に切り分ける
  • ✅ 副作用部分は常に境界として設計し、外側でまとめて扱う

4. 副作用制御のためのレイヤー分離

// pure.ts
export function calculateTax(price) {
  return price * 0.1;
}

// effect.ts
import { calculateTax } from './pure.js';

const tax = calculateTax(1000);
console.log(`Tax is: ${tax}`);
  • ロジックと副作用が別ファイル → テスト可能・再利用可能
  • ✅ 副作用のある処理は最小限のゲートウェイとして設計

5. フレームワークにおける副作用制御(React例)

useEffect(() => {
  document.title = 'Loaded';
}, []);
  • ✅ Reactでは副作用は useEffect に隔離
  • ✅ 「純粋なレンダリング関数 + 副作用専用の構造」を徹底している設計思想

設計判断フロー

① この関数は常に同じ出力を返すか? → 純粋関数として設計可能

② 外部と通信しているか? → 副作用として分離・制御

③ テスト可能な構造か? → 外部依存を渡す or 別モジュールに切り出す

④ UI更新とロジックが混在していないか? → DOM操作を外に出す

⑤ 時間やランダム性を使っていないか? → モック・依存注入に切り替える

よくあるミスと対策

console.log() を開発時から本番まで放置

→ ✅ 副作用は環境ごとに制御(ロガーインタフェースの抽象化)


❌ DOM操作が関数内にベタ書きされ、再利用不能に

→ ✅ DOM操作は呼び出し元が責任を持ち、関数は値だけ返す


❌ グローバル状態を直接書き換えてテスト不能

→ ✅ 状態は関数の戻り値として受け渡す or ストア経由で制御


結語

副作用を完全に排除する必要はない。
むしろそれを構造として認識し、制御下に置くことこそが設計の本質である。

  • 純粋関数をベースに、拡張しやすくテスト可能な設計を構築
  • 副作用は「悪」ではなく、「境界」であり、「責務」である
  • アーキテクチャとは、副作用をどこまで許容するかの戦略選択でもある

JavaScriptにおける副作用設計とは、
“振る舞いと環境との接点を明確にし、予測可能性を守るための設計制御である。”

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?