純粋関数と副作用 | 関数型プログラミングの基礎 | JavaScript 超完全入門 基本から発展までのすべて

スポンサーリンク
スポンサーリンク
amazon
スマイルSALE
--:--:--
ad. 価格範囲を指定して商品を探せます

純粋関数とは?

関数型プログラミングにおいて、純粋関数(Pure Function)とは、同じ入力に対して必ず同じ出力を返し、外部の状態を変更しない関数のことです。

純粋関数は、外部の変数や状態に依存せず、関数の外側へ影響を与えません。そのため、結果を予測しやすく、テストやデバッグがしやすいという特徴があります。

純粋関数の特徴

純粋関数には、主に次の2つの特徴があります。

特徴 説明
入力が同じなら出力も常に同じ 同じ引数を与えれば、何度実行しても同じ結果を返します。
副作用がない 外部の変数、DOM、ファイル、通信などを変更しません。

この2つを満たす関数が、純粋関数と呼ばれます。

純粋関数の例

次のadd()関数は、純粋関数の基本的な例です。


function add(a, b) {
    return a + b;
}

console.log(add(2, 3));

このadd()関数は、23を渡すと常に5を返します。

外部の変数を変更せず、外部の状態にも依存していないため、純粋関数といえます。

副作用とは?

副作用(Side Effect)とは、関数が外部の状態に影響を与えることです。

代表的な副作用には、次のようなものがあります。

  • 外部変数の値を変更する。
  • DOMを書き換える。
  • コンソールへ出力する。
  • API通信を行う。
  • ファイルやデータベースへ書き込む。

副作用がある関数は、必ず悪いというわけではありません。実際のアプリケーションでは、画面更新や通信などの副作用は必要です。ただし、副作用が多すぎると、処理の流れが追いにくくなります。

副作用を持つ関数の例

次の関数は、外部の変数を変更しているため、副作用を持っています。


let count = 0;

function increment() {
    count++;
}

increment();

console.log(count);

increment()関数は、関数の外側にあるcountを変更しています。

このように、関数の外部に影響を与える処理は副作用です。

純粋関数と副作用の比較

純粋関数と副作用を持つ関数の違いを整理すると、次のようになります。

比較項目 純粋関数 副作用を持つ関数
外部状態への影響 なし あり
出力の一貫性 同じ入力なら常に同じ出力を返す 外部状態によって結果が変わることがある
テストのしやすさ 入力と出力だけを確認すればよい 外部状態も考慮する必要がある
デバッグのしやすさ 原因を追いやすい どこで状態が変わったか追いにくいことがある

副作用を避ける理由

副作用を持つ関数が増えると、コードの動作を予測しにくくなります。

特に大規模なアプリケーションでは、どの処理がどの状態を変更しているのか分かりにくくなり、不具合の原因を見つけるのが難しくなります。

そのため、すべての処理を純粋関数にする必要はありませんが、計算処理やデータ変換処理はできるだけ純粋関数として書くと、保守しやすいコードになります。

副作用を回避する例

外部変数を直接変更する代わりに、新しい値を返すようにすると、副作用を避けやすくなります。


function incrementPure(count) {
    return count + 1;
}

const result = incrementPure(0);

console.log(result);

この例では、countを直接変更せず、新しい値を戻り値として返しています。

このように書くと、関数の動作が入力と出力だけで決まるため、理解しやすくなります。

配列を変更しない純粋関数の例

配列を扱う場合も、元の配列を直接変更しないようにすると、純粋関数に近い形で書けます。


function addItem(items, newItem) {
    return [...items, newItem];
}

const fruits = ["Apple", "Banana"];
const newFruits = addItem(fruits, "Cherry");

console.log(fruits);
console.log(newFruits);

この例では、fruits配列を直接変更せず、新しい配列を作成して返しています。

push()を使うと元の配列が変更されますが、スプレッド構文(...)を使うことで、元のデータを保ったまま新しい配列を作成できます。

初心者が覚えておきたいポイント

  • 純粋関数は、同じ入力に対して常に同じ出力を返します。
  • 純粋関数は、外部の変数や状態を変更しません。
  • 副作用には、DOM操作、API通信、外部変数の変更などがあります。
  • 副作用は悪ではありませんが、扱う場所を整理することが重要です。
  • 計算処理やデータ変換処理は、できるだけ純粋関数にすると保守しやすくなります。

まとめ

  • 純粋関数は、同じ入力に対して常に同じ出力を返す関数である。
  • 純粋関数は、外部状態を変更しない。
  • 副作用とは、関数が外部の状態に影響を与えることである。
  • 副作用が多いコードは、動作の予測やデバッグが難しくなりやすい。
  • 外部変数を直接変更せず、新しい値を返すことで副作用を減らせる。
  • 純粋関数を意識すると、テストしやすく保守性の高いコードを書きやすくなる。