早期 return でネストを浅くする

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

早期 return でネストを浅くする とは

ガード節 (早期 return) を使い、深い if のネストを浅いコードに書き換える。本レッスンでは、早期 return でネストを浅くする の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

早期 return でネストを浅くする

if / else を素直に書いていくと、条件が増えるほどコードが右にズレていって、深いネスト (if の中に if の中に if…) になりがちです。読みにくく、修正もしにくいコードができてしまいます。これを避けるためのテクニックが ガード節 (guard clause) です。「早期 return」とも呼ばれます。

ガード節は「ありえない入力を最初に追い返す」発想です。バグの原因になる値を関数の入口で処理してしまえば、本体は理想的なケースだけ書けばよくなります。

Before — 深いネスト

問題の典型例を見てみましょう。nameage を受け取り、age0 以上のときだけ 'こんにちは、 NAME さん (AGE 歳)' を、それ以外は '入力エラー' を返す関数です。

JavaScript

function greetBefore (name, age) { if (name) { if (typeof age === 'number') { if (age >= 0) { return 'こんにちは、 ' + name + ' さん (' + age + ' 歳)'; } else { return '入力エラー'; } } else { return '入力エラー'; } } else { return '入力エラー'; } }

このコードは「本体の処理」が 3 段奥に押し込まれています。条件を 1 つ追加するたびにインデントが深くなり、修正のたびにどの else がどの if に対応するのか追いかけることになります。

After — ガード節

同じ処理をガード節で書き直すと次のとおりです。

JavaScript

function greetAfter (name, age) { if (!name) return '入力エラー'; if (typeof age !== 'number') return '入力エラー'; if (age < 0) return '入力エラー'; return 'こんにちは、 ' + name + ' さん (' + age + ' 歳)'; }

本体の処理が インデントの一番浅い位置 にあり、目線が右にズレません。手前に並ぶのは「正常系から外れた入力」を弾く return だけです。新しいエラー条件を追加するときも、行を 1 行追加するだけで済みます。

「早期 return は読み手にやさしい」と言われます。読む人は最初に並んだガード節を読み飛ばし、本体の処理だけに集中できるからです。

動きを追ってみる

diagram (will load when visible)

図の左側のように、各ガード節は「ここで条件に当てはまったら、関数を打ち切る」役目です。複数の入口エラーを 1 か所にまとめずに、それぞれの if で吐き出すのが分かりやすさのコツです。

適用するときの注意

ガード節は便利ですが、何でも return で打ち切れば良いわけではありません。次の点を意識すると安全です。

  • エラーや例外的なケース を先頭で return する
  • 本体の処理 は最後に 1 つだけ書く
  • 同じ階層で if / else の分岐が必要なときは、無理にフラットにせず else を残す

また、関数の最初の数行を見ただけで「どんな入力が許されているのか」が分かるようになります。これはコードを読む人にとって大きな利点です。ドキュメントを書かなくても、ガード節そのものが入力仕様を兼ねてくれます。

ガード節と else は対立するものではありません。「異常系を弾く」のがガード節、「同じ重みの複数枝に分ける」のが else if です。役目を分けて使うと自然に整理されます。

よくある間違い

  1. ガード節の後に else を続ける。if (x < 0) return 'error'; else { return 'ok'; } は意味が重複しています。早期 return を使ったら、後続には else ではなく直接処理を書きます。
  2. ガード節だけで本体を書き切ろうとする。本体の判定までガードに混ぜると、結局読みにくくなります。本体は 1 行〜数行で素直に書くのが目安です。
  3. 戻り値の型がバラバラ。エラーで null を返したり '' を返したりすると、呼び出し側の判定が複雑になります。エラーの戻り値は 1 種類に統一しましょう。

やってみよう

name (文字列) と age (数値) を受け取り、age0 以上の数値で name が空でなければ 'こんにちは、 NAME さん (AGE 歳)' を返し、それ以外はすべて '入力エラー' を返す関数 greetUser を、ガード節 (早期 return) を使って 実装してください。本体の return 文は 1 つだけで書けます。

よくある質問

Q. ブラウザと Node.js で動作は変わりますか?

A. JavaScript の構文・組み込み機能(配列・文字列・Promise 等)はどちらでも同じです。違いは DOM API(ブラウザ専用)と fs などのファイル系(Node 専用)など、実行環境固有の機能です。コアロジックは両方で動くため、テストもしやすくなります。

Q. ES6 以降の新機能は使っても大丈夫ですか?

A. 現代のブラウザ・Node.js は ES2020 以降の機能をほぼサポートしています。古い IE 等を対象にする必要が無ければ、let/const、アロー関数、分割代入、async/await を積極的に使ってください。トランスパイル(Babel/Vite)が必要なケースは年々減っています。

Q. TypeScript に進む価値はありますか?

A. 型情報があるとリファクタやエディタ補完が劇的に効くため、規模が大きくなるなら TypeScript への移行を強くおすすめします。最初は any を許容しつつ徐々に型を付ければ、JS の知識をそのまま活かせます。

次のレッスン

次は BMI で体型を判定する で、ガード節 (早期 return) を使い、深い if のネストを浅いコードに書き換える を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. guard clause の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. guard clause とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. ガード節 (早期 return) を使って異常系を先に弾くこと
  2. 本体の return は 1 か所にまとめること
  3. 正常時は 'こんにちは、 NAME さん (AGE 歳)' の形式で返すこと

入出力例

test-cases.txt

greetUser("太郎", 20)"こんにちは、 太郎 さん (20 歳)" greetUser("花子", 0)"こんにちは、 花子 さん (0 歳)" greetUser("", 20)"入力エラー" greetUser("太郎", -1)"入力エラー" greetUser("太郎", "20")"入力エラー" greetUser(null, 20)"入力エラー"

ヒント

main.js
main.js
学習モード

メモ

早期 return でネストを浅くする

⌘S で保存