なぜconsole.log()すら「副作用(Side Effect)」とされるのか?―関数型プログラミングの視点から解説
こんにちは。ゆうせいです。
JavaScriptの学習中、関数型プログラミングに出会うと「副作用(Side Effect)を避けましょう」とよく言われます。
そしてこんな一文に出会うことがあります。
「console.log()ですら副作用である」
「えっ?ただのログ出力でしょ?なんで副作用なの?」「副作用って何か悪いことなの?」
そう思ったあなたの疑問、まさに本質です!
今回はこの「副作用」という考え方と、なぜ console.log()
もその1つに含まれるのかをやさしく解説していきます。
まず「副作用(Side Effect)」とは何か?
関数の外側の状態に影響を与える処理、または外側の状態に依存する処理のこと。
もっとざっくり言うと…
「その関数を実行することで、何かが“変わる”こと」
主な副作用の例
処理内容 | 副作用? | 理由 |
---|---|---|
ログを出力する | 副作用あり | コンソールという外部に影響を与える |
DOMを操作する | 副作用あり | ページに変化が起きる |
グローバル変数を変更する | 副作用あり | 外部状態が変化 |
API通信する | 副作用あり | ネットワークとやりとりが発生 |
データベースに保存する | 副作用あり | データが書き換わる |
console.log()
の本質は?
function greet(name) {
console.log("こんにちは、" + name + "さん!");
}
この関数は、画面(コンソール)に出力するという「外の世界に影響を与える行為」をしていますよね。
つまり、「関数の外」に何かが起こる=副作用なんです!
反対に「副作用がない関数(純粋関数)」とは?
function add(a, b) {
return a + b;
}
この関数は、
- 外部を変更しない
- 毎回同じ入力 → 同じ出力
- 他に一切影響を与えない
という意味で「純粋関数(pure function)」です。
なぜ関数型では副作用を嫌うのか?
✅ 1. バグが発生しやすくなるから
副作用があると、コードの動作が状況に依存してしまいます。
let count = 0;
function increment() {
count++;
}
このように、実行するたびに状態が変わる関数は、どこで何が起きているか分かりづらくなるのです。
✅ 2. テストがしづらくなるから
function greet(name) {
console.log("こんにちは、" + name);
}
この関数をテストしたくても、「出力結果を確認する」には特殊な環境(モックやスパイ)が必要です。
一方、次のように純粋にすれば:
function createGreeting(name) {
return "こんにちは、" + name;
}
関数の戻り値さえ検証すればOK! テストが簡単になります。
console.log()
はダメってこと?
→ いいえ!必要な場面では使ってOK!
副作用=悪ではありません。
ただし、「副作用があることを意識して、必要最小限にする」のが関数型の考え方です。
まとめ:なぜconsole.log()
は副作用なのか?
項目 | 理由 |
---|---|
外部に影響を与える? | 出力(画面やログ)という形で影響あり |
実行のたびに何かが変わる? | はい(ログが増える) |
状態を持つ? | 直接ではないが、外の状態を変える |
関数の“純粋性”を乱す? | はい(戻り値がない or 出力以外の影響がある) |
今後の学習のヒント
関数型プログラミングでは、副作用の扱いがとても重要です。さらに深く理解したい方は次のテーマに進んでみましょう!
- 純粋関数と副作用のバランスのとり方
- 副作用を分離する設計パターン(コアとシェル)
- Reactでの副作用(useEffect)との付き合い方
- 関数型ライブラリ(Ramda, Lodash/fp)での実践
副作用をコントロールできる=プロフェッショナルなコードを書く力です!
「どこで何が起きるか」を意識するだけで、コードはぐんと読みやすくなりますよ!
セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク
投稿者プロフィール
