純粋関数と副作用
予測しやすくテスト可能な関数を記述します。
「純粋関数と副作用」は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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 純粋関数と副作用
- 宣言的なデータ変換
- ミューテーションを避ける
- ポイントフリースタイル