0Pricing
JavaScript Academy · レッスン

純粋関数と副作用

予測しやすくテスト可能な関数を記述します。

「純粋関数と副作用」はCoddyKit上の無料JavaScript Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJavaScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 JavaScript Academyコースには全4レッスンが含まれています。

純粋な関数とは

純粋関数には2つの性質があります。同じ入力に対して常に同じ出力を返すことと、観測可能な副作用を起こさないことです。純粋関数は予測しやすく、テストも簡単です。

function add(a, b) {
  return a + b;
}
console.log(add(2, 3));
console.log(add(2, 3)); // always 5

決定的な出力

純粋であるということは、決定的であるということです。同じ引数は常に同じ結果に対応し、隠れた状態、時間、乱数に依存してはいけません。

function double(n) {
  return n * 2;
}
console.log(double(10)); // always 20

副作用とは

副作用とは、値を返すこと以外に関数が行うすべてのことです。ログ出力、外部状態の変更、ストレージへの書き込み、ネットワーク通信、引数の変更などが該当します。

let total = 0;
function impureAdd(n) {
  total += n;     // side effect: mutates outer state
  return total;
}
console.log(impureAdd(5));
console.log(impureAdd(5)); // 5 then 10, not pure

外部状態への依存

変更可能な外部状態を読み取ることも純粋性を損ないます。引数が同じままでも、出力が変わってしまうためです。

let rate = 1.5;
function priceImpure(x) {
  return x * rate; // depends on outside variable
}
console.log(priceImpure(10)); // 15
rate = 2;
console.log(priceImpure(10)); // 20 - different result

純粋にする

関数に必要なものをすべて引数として渡してください。これで、結果は入力だけに依存するようになります。

function price(x, rate) {
  return x * rate;
}
console.log(price(10, 1.5)); // 15
console.log(price(10, 2));   // 20

引数の変更は純粋ではない

渡されたオブジェクトや配列を変更することは、呼び出し元から観測できる副作用です。純粋関数は入力を変更しません。

function impurePush(arr, x) {
  arr.push(x);   // mutates caller array
  return arr;
}
const a = [1, 2];
impurePush(a, 3);
console.log(a); // [1, 2, 3] - caller changed

新しい値を返す

純粋な実装では、入力を変更する代わりに新しい値を作成して返します。

function pureAppend(arr, x) {
  return [...arr, x];
}
const a = [1, 2];
const b = pureAppend(a, 3);
console.log(a); // [1, 2] unchanged
console.log(b); // [1, 2, 3]

純粋性のメリット

純粋関数は設定やモックが不要で簡単にテストでき、キャッシュ(メモ化)しても安全です。また、どの順番でも、並列でも安全に実行できます。コードについて局所的に考えられるようになる点も利点です。

function square(n) { return n * n; }
console.log([1, 2, 3].map(square)); // [1, 4, 9]

不純な処理を分離する

すべての副作用を避けることはできません。アプリケーションではログ出力、データ取得、描画が必要です。目標は、副作用を端に追いやり、中心となるロジックを純粋に保つことです。

function computeTotal(items) {
  return items.reduce((s, i) => s + i.price, 0);
}
const total = computeTotal([{ price: 5 }, { price: 7 }]);
console.log(total); // 12 - pure core, log at the edge

参照透過性

純粋な呼び出しは、動作を変えずにその結果で置き換えられます。どこでもadd(2, 3)は5と置き換えられます。この性質を参照透過性と呼びます。

function add(a, b) { return a + b; }
const x = add(2, 3) + add(2, 3);
const y = 5 + 5;
console.log(x === y); // true

不純性を見抜く

手がかりに注目してください。console、Math.random、Date.now、外側の変数への代入、引数の変更などです。これらのいずれかがあれば、その関数は不純です。

function pureRoll(seed) {
  return (seed * 1103515245 + 12345) % 100;
}
console.log(pureRoll(42)); // deterministic, testable

確認問題

純粋関数の見分け方

まとめ

純粋関数は決定的で、副作用がありません。外部状態の変更、I/O、引数の変更を行わない関数です。依存するものは引数として渡し、変更する代わりに新しい値を返してください。純粋性によって、テストのしやすさ、メモ化、参照透過性、並列実行の安全性が得られます。中心となる処理を純粋に保ち、副作用は端に追いやってください。

よくある質問

「純粋関数と副作用」レッスンは無料ですか?

はい。「純粋関数と副作用」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、JavaScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 JavaScript Academyコースには全4レッスンが含まれています。

「純粋関数と副作用」で何を学びますか?

予測しやすくテスト可能な関数を記述します。 ブラウザで直接実行するハンズオンコードでJavaScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

JavaScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJavaScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「純粋関数と副作用」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJavaScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのJavaScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 純粋関数と副作用
  2. 宣言的なデータ変換
  3. ミューテーションを避ける
  4. ポイントフリースタイル
← JavaScript Academyに戻る