制御構文 — if・switch・for・whileの実務パターン
JavaScriptの制御構文は、コードの実行順序を変えるための仕組みです。条件によって処理を分岐したり、繰り返したり、途中で抜け出したりできます。
この章では実務でよく使うパターンを中心に整理します。
学習者if と switch はどう使い分けるの?break や return を書き忘れてバグを出したことがある…。
条件分岐:if / else
最も基本的な制御構文です。条件が truthy か falsy かによって、実行するブロックを切り替えます。
const score = 75;
if (score >= 90) {
console.log('優');
} else if (score >= 70) {
console.log('良'); // こちらが実行される
} else {
console.log('可');
}早期 return パターン
ネストが深くなりがちな条件分岐は、**早期 return(Guard Clause)**で扁平にできます。
// ネストが深くなるパターン
function processOrder(order) {
if (order) {
if (order.isPaid) {
if (order.items.length > 0) {
// 本来の処理
ship(order);
}
}
}
}
// 早期 return で扁平にしたパターン
function processOrder(order) {
if (!order) return;
if (!order.isPaid) return;
if (order.items.length === 0) return;
// 本来の処理
ship(order);
}条件分岐:switch
複数の値と比較するときは switch が読みやすくなります。
const day = 'Monday';
switch (day) {
case 'Saturday':
case 'Sunday':
console.log('週末');
break;
case 'Monday':
console.log('月曜日'); // こちらが実行される
break;
default:
console.log('平日');
}フォールスルーに注意
break を書き忘れると、次の case の処理も続けて実行されます(フォールスルー)。
switch (status) {
case 'pending':
console.log('pending');
// break がないと次の case も実行される!
case 'active':
console.log('active'); // status が 'pending' のときも実行される
break;
}意図的なフォールスルー(複数の値に同じ処理)以外は、必ず break を書きます。
ループ:for / for...of / for...in
for 文
インデックスが必要な場合や、回数を指定して繰り返すときに使います。
for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}for...of
配列や文字列などのイテラブルを順に処理するときに使います。インデックスが不要なケースはこちらが読みやすいです。
const fruits = ['apple', 'banana', 'cherry'];
for (const fruit of fruits) {
console.log(fruit);
}
// インデックスも必要な場合は entries()
for (const [index, fruit] of fruits.entries()) {
console.log(index, fruit); // 0 'apple', 1 'banana', ...
}for...in
オブジェクトの列挙可能なプロパティキーを順に処理します。
const user = { name: 'Alice', age: 30 };
for (const key in user) {
console.log(key, user[key]); // 'name' 'Alice', 'age' 30
}while / do...while
条件が満たされる間、繰り返し実行します。
let count = 0;
while (count < 3) {
console.log(count); // 0, 1, 2
count++;
}
// do...while は最低1回は実行される
let n = 10;
do {
console.log(n); // 10(条件を満たさなくても1回実行)
n++;
} while (n < 5);break と continue
break
ループや switch を途中で抜け出します。
const numbers = [1, 3, 5, 2, 8, 4];
for (const n of numbers) {
if (n % 2 === 0) {
console.log(`最初の偶数: ${n}`); // '最初の偶数: 2'
break; // ループを終了
}
}continue
現在のイテレーションをスキップして、次のイテレーションに進みます。
for (let i = 0; i < 5; i++) {
if (i % 2 === 0) continue; // 偶数はスキップ
console.log(i); // 1, 3
}return と throw — 制御フロー文
return と throw は、if や for と同様に**制御フロー文(Control Flow Statement)**です。どちらも、その後のコードを実行せずに処理の流れを変えます。
return — 関数を終了して値を返す
return は関数の実行をそこで終了し、呼び出し元に値を返します。
function divide(a, b) {
if (b === 0) {
return null; // ここで関数終了。以降は実行されない
}
return a / b;
}
console.log(divide(10, 2)); // 5
console.log(divide(10, 0)); // nullreturn の後ろに書くもの(null や a / b)は**式(Expression)**です。return 自体は文なので、変数に代入したりできません。
// return は文なので、式としては使えない
const x = return 5; // SyntaxErrorreturn だけ書いた場合、または return を省略した関数は undefined を返します。
function doSomething() {
console.log('実行');
return; // undefined を返す
}
function doNothing() {
// return がない場合も undefined を返す
}throw — 例外を投げて処理を中断する
throw は例外を発生させ、呼び出し元に向かってスタックを遡ります。try...catch でキャッチされるまで伝播し続けます。
function getUser(id) {
if (!id) {
throw new Error('id は必須です'); // ここで関数終了。例外を投げる
}
return fetchUser(id);
}
try {
getUser(null);
} catch (error) {
console.log(error.message); // 'id は必須です'
}throw の後ろに書くもの(new Error(...))も式です。技術的には任意の値を投げられますが、Error オブジェクト(またはそのサブクラス)を使うのが慣習です。
throw new Error('メッセージ'); // 推奨
throw new TypeError('型が違います'); // 組み込みエラー型
throw new RangeError('範囲外です'); // 組み込みエラー型
throw 'エラー文字列'; // 技術的には可能だが非推奨
throw 42; // 同上return と throw の使い分け
| 状況 | 使うもの |
|---|---|
| 正常な終了(値を返す) | return |
| 値を返さずに終了 | return(undefined が返る) |
| 想定内の「早期終了」(ガード節) | return |
| 呼び出し元に問題を知らせたい | throw |
| 引数が不正・前提条件を満たさない | throw |
// 正常な早期終了 → return
function formatName(name) {
if (!name) return '名前未設定'; // 値として返せるのでreturnでよい
return name.trim();
}
// 呼び出し元に問題を知らせる → throw
function parsePositiveInt(str) {
const num = parseInt(str, 10);
if (isNaN(num)) {
throw new TypeError(`'${str}' は数値に変換できません`);
}
if (num <= 0) {
throw new RangeError(`正の整数が必要です: ${num}`);
}
return num;
}まとめ
| 構文 | 役割 |
|---|---|
if / else | 条件によって分岐 |
switch | 単一値の多分岐(break 必須) |
for...of | イテラブルの反復 |
for...in | オブジェクトのキー列挙(配列には使わない) |
while | 条件が真の間繰り返す |
break | ループ・switch を抜ける |
continue | 今のイテレーションをスキップ |
return | 関数を終了して値を返す(制御フロー文) |
throw | 例外を投げて処理を中断(制御フロー文) |
throw を使った例外のキャッチ(try...catch)やカスタムエラークラスの詳細は、14章「エラーハンドリング」で扱います。

次の章では、関数の定義方法と this の挙動を詳しく見ていきます。