早期 return でネストを浅くする
早期 return でネストを浅くする とは
ガード節 (早期 return) を使い、深い if のネストを浅いコードに書き換える。本レッスンでは、早期 return でネストを浅くする の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
早期 return でネストを浅くする
if / else を素直に書いていくと、条件が増えるほどコードが右にズレていって、深いネスト (if の中に if の中に if…) になりがちです。読みにくく、修正もしにくいコードができてしまいます。これを避けるためのテクニックが ガード節 (guard clause) です。「早期 return」とも呼ばれます。
ガード節は「ありえない入力を最初に追い返す」発想です。バグの原因になる値を関数の入口で処理してしまえば、本体は理想的なケースだけ書けばよくなります。
Before — 深いネスト
問題の典型例を見てみましょう。name と age を受け取り、age が 0 以上のときだけ 'こんにちは、 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は読み手にやさしい」と言われます。読む人は最初に並んだガード節を読み飛ばし、本体の処理だけに集中できるからです。
動きを追ってみる
図の左側のように、各ガード節は「ここで条件に当てはまったら、関数を打ち切る」役目です。複数の入口エラーを 1 か所にまとめずに、それぞれの if で吐き出すのが分かりやすさのコツです。
適用するときの注意
ガード節は便利ですが、何でも return で打ち切れば良いわけではありません。次の点を意識すると安全です。
- エラーや例外的なケース を先頭で
returnする - 本体の処理 は最後に 1 つだけ書く
- 同じ階層で
if / elseの分岐が必要なときは、無理にフラットにせずelseを残す
また、関数の最初の数行を見ただけで「どんな入力が許されているのか」が分かるようになります。これはコードを読む人にとって大きな利点です。ドキュメントを書かなくても、ガード節そのものが入力仕様を兼ねてくれます。
ガード節と
elseは対立するものではありません。「異常系を弾く」のがガード節、「同じ重みの複数枝に分ける」のがelse ifです。役目を分けて使うと自然に整理されます。
よくある間違い
- ガード節の後に
elseを続ける。if (x < 0) return 'error'; else { return 'ok'; }は意味が重複しています。早期returnを使ったら、後続にはelseではなく直接処理を書きます。 - ガード節だけで本体を書き切ろうとする。本体の判定までガードに混ぜると、結局読みにくくなります。本体は 1 行〜数行で素直に書くのが目安です。
- 戻り値の型がバラバラ。エラーで
nullを返したり''を返したりすると、呼び出し側の判定が複雑になります。エラーの戻り値は 1 種類に統一しましょう。
やってみよう
name (文字列) と age (数値) を受け取り、age が 0 以上の数値で 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 つができることを確認しましょう。
- guard clause の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. guard clause とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- ガード節 (早期 return) を使って異常系を先に弾くこと
- 本体の return は 1 か所にまとめること
- 正常時は 'こんにちは、 NAME さん (AGE 歳)' の形式で返すこと
入出力例
test-cases.txt
greetUser("太郎", 20) → "こんにちは、 太郎 さん (20 歳)"
greetUser("花子", 0) → "こんにちは、 花子 さん (0 歳)"
greetUser("", 20) → "入力エラー"
greetUser("太郎", -1) → "入力エラー"
greetUser("太郎", "20") → "入力エラー"
greetUser(null, 20) → "入力エラー"