JavaScript の switch 文は、1 つの値に対して複数の候補と照合し、一致した分岐の処理を実行する構文です。if … else if を何段も重ねるより簡潔で読みやすく書けます。
本記事では、基本構文からbreak の重要性、フォールスルー、複数 case のグルーピング、switch(true) パターン、if 文との使い分け、オブジェクトマップによる代替まで解説します。
この記事でわかること
・switch 文の基本構文(case / break / default)
・break を忘れた場合のフォールスルー(貫通)
・複数の case をグルーピングする方法
・switch(true) で範囲条件を扱う方法
・switch は ===(厳密等価)で比較される仕様
・if 文との使い分けの判断基準
・オブジェクトマップで switch を置き換えるモダンなパターン
・switch 文の基本構文(case / break / default)
・break を忘れた場合のフォールスルー(貫通)
・複数の case をグルーピングする方法
・switch(true) で範囲条件を扱う方法
・switch は ===(厳密等価)で比較される仕様
・if 文との使い分けの判断基準
・オブジェクトマップで switch を置き換えるモダンなパターン
switch 文の基本構文
JavaScript(基本構文)
const fruit = "apple";
switch (fruit) {
case "apple":
console.log("りんご");
break;
case "banana":
console.log("バナナ");
break;
case "orange":
console.log("みかん");
break;
default:
console.log("不明な果物");
}
// 出力: りんご
| キーワード | 役割 |
|---|---|
| switch (式) | 評価する値を指定 |
| case 値: | 式の結果と比較する候補値 |
| break | その case の処理を終了し switch を抜ける |
| default | どの case にも一致しなかった場合の処理(else に相当) |
switch は === で比較する
switch 文の case は厳密等価(===)で比較されます。型変換は行われません。
switch 文の case は厳密等価(===)で比較されます。型変換は行われません。
switch (1) に対して case "1": は一致しません(型が異なるため)。break の重要性とフォールスルー
JavaScript(break を忘れた場合: フォールスルー)
const color = "red";
switch (color) {
case "red":
console.log("赤"); // 実行される
// break がない!
case "blue":
console.log("青"); // これも実行される(フォールスルー)
// break がない!
case "green":
console.log("緑"); // これも実行される
break;
default:
console.log("不明");
}
// 出力: 赤 → 青 → 緑(3 つ全て実行される)
break を忘れると後続の case が全て実行される
switch 文は一致した case 以降の処理をbreak に出会うまで全て実行します(フォールスルー)。意図しないフォールスルーは非常に多いバグの原因です。各 case の末尾には必ず break を書く習慣をつけてください。ESLint の
switch 文は一致した case 以降の処理をbreak に出会うまで全て実行します(フォールスルー)。意図しないフォールスルーは非常に多いバグの原因です。各 case の末尾には必ず break を書く習慣をつけてください。ESLint の
no-fallthrough ルールで検出可能です。複数の case をグルーピングする
フォールスルーを意図的に活用して、複数の case で同じ処理を実行できます。
JavaScript(複数 case のグルーピング)
const day = "Saturday";
switch (day) {
case "Monday":
case "Tuesday":
case "Wednesday":
case "Thursday":
case "Friday":
console.log("平日");
break;
case "Saturday":
case "Sunday":
console.log("休日");
break;
default:
console.log("不正な曜日");
}
// 出力: 休日
意図的なフォールスルーはコメントで明示
ESLint は break のない case を警告しますが、意図的なグルーピングの場合は
ESLint は break のない case を警告しますが、意図的なグルーピングの場合は
// falls through コメントを付けることで警告を抑制できます。関数内での return による switch
関数内で switch を使う場合、return を使えば break が不要になります。
JavaScript(return で値を返す)
function getLabel(status) {
switch (status) {
case "active": return "有効";
case "inactive": return "無効";
case "pending": return "保留中";
case "deleted": return "削除済み";
default: return "不明";
}
}
console.log(getLabel("active")); // "有効"
return を使えば break 忘れのバグがなくなる
関数内の switch では
関数内の switch では
return で値を返すパターンが推奨です。break 忘れによるフォールスルーのリスクがゼロになり、コードも簡潔になります。switch(true) で範囲条件を扱う
switch は通常「値の一致」を判定しますが、switch(true) と書くと case に条件式を書けます。
JavaScript(switch(true) パターン)
const score = 75;
switch (true) {
case score >= 90:
console.log("A 評価");
break;
case score >= 70:
console.log("B 評価");
break;
case score >= 50:
console.log("C 評価");
break;
default:
console.log("D 評価");
}
// 出力: B 評価
switch(true) は賛否が分かれる
switch(true) は動作しますが、本来の switch の使い方(値の一致判定)から外れるため「読みにくい」と感じる開発者もいます。範囲条件は
switch(true) は動作しますが、本来の switch の使い方(値の一致判定)から外れるため「読みにくい」と感じる開発者もいます。範囲条件は
if ... else if の方が自然な場合が多いため、チームの方針に合わせてください。default の位置
JavaScript(default は最後でなくても OK)
// default を先頭に書くパターン(あまり一般的ではないが動作する)
switch (value) {
default:
console.log("デフォルト処理");
break;
case 1:
console.log("値は 1");
break;
case 2:
console.log("値は 2");
break;
}
// 可読性のため default は最後に書くのが一般的
default は省略可能です。どの case にも一致せず default もない場合、switch は何もせずに終了します。
case 内での変数宣言(ブロックスコープ)
JavaScript(case 内の let / const)
// NG: case 内の let がスコープを共有してエラー
// switch (action) {
// case "create":
// let message = "作成しました"; // エラーになる場合あり
// break;
// case "delete":
// let message = "削除しました"; // 同じスコープで重複宣言
// break;
// }
// OK: 各 case を {} で囲む
switch (action) {
case "create": {
const message = "作成しました";
console.log(message);
break;
}
case "delete": {
const message = "削除しました";
console.log(message);
break;
}
}
case 内で let / const を使うなら {} で囲む
switch の case はデフォルトで同じブロックスコープを共有します。複数の case で同名の
switch の case はデフォルトで同じブロックスコープを共有します。複数の case で同名の
let / const を宣言するとSyntaxError になります。各 case を { } で囲めば独立したスコープになり、同名変数を安全に使えます。if 文との使い分け
| 場面 | 推奨 | 理由 |
|---|---|---|
| 1 つの値に対する多岐分岐(3 つ以上) | switch | case の一覧が見やすく、値と処理の対応が明確 |
| 範囲条件(>=, <=, BETWEEN) | if | switch は等価比較のみ。範囲は if が自然 |
| 複合条件(&& / ||) | if | switch では複合条件を表現しにくい |
| 2 択の分岐 | if / 三項演算子 | switch は 2 択には冗長 |
| 値からラベルへのマッピング | オブジェクトマップ | switch よりさらにシンプル(後述) |
if 文の詳細は「if 文による条件分岐の書き方」、三項演算子は「三項演算子の使い方」を参照してください。
オブジェクトマップで switch を置き換える
値とラベル(または関数)の単純なマッピングは、オブジェクトリテラルの方がシンプルに書けます。
JavaScript(オブジェクトマップ: ラベル変換)
// switch で書く場合
function getLabel(status) {
switch (status) {
case "active": return "有効";
case "inactive": return "無効";
case "pending": return "保留中";
default: return "不明";
}
}
// オブジェクトマップで書く場合(よりシンプル)
const STATUS_LABELS = {
active: "有効",
inactive: "無効",
pending: "保留中",
};
function getLabel(status) {
return STATUS_LABELS[status] ?? "不明";
}
JavaScript(オブジェクトマップ: 関数ディスパッチ)
// アクションに応じた処理を実行
const actions = {
create: (data) => createItem(data),
update: (data) => updateItem(data),
delete: (data) => deleteItem(data),
};
function handleAction(action, data) {
const handler = actions[action];
if (handler) {
handler(data);
} else {
console.error("不明なアクション:", action);
}
}
オブジェクトマップのメリット
・case / break の記述が不要でコードが短い
・マッピングデータを変数として外部から渡せる(動的な分岐)
・テストしやすい(オブジェクトの中身を検証するだけ)
ただし、副作用のある処理や複雑なロジックが必要な場合は switch / if の方が適しています。
・case / break の記述が不要でコードが短い
・マッピングデータを変数として外部から渡せる(動的な分岐)
・テストしやすい(オブジェクトの中身を検証するだけ)
ただし、副作用のある処理や複雑なロジックが必要な場合は switch / if の方が適しています。
実務パターン集
パターン(1): HTTP ステータスコードの分岐
JavaScript
function handleResponse(status) {
switch (status) {
case 200:
return { ok: true, message: "成功" };
case 400:
return { ok: false, message: "リクエストが不正です" };
case 401:
return { ok: false, message: "認証が必要です" };
case 403:
return { ok: false, message: "アクセス権限がありません" };
case 404:
return { ok: false, message: "見つかりません" };
case 500:
return { ok: false, message: "サーバーエラー" };
default:
return { ok: false, message: `不明なエラー: ${status}` };
}
}
パターン(2): イベントタイプによる処理分岐
JavaScript
document.addEventListener("keydown", (e) => {
switch (e.key) {
case "ArrowUp":
moveUp();
break;
case "ArrowDown":
moveDown();
break;
case "ArrowLeft":
moveLeft();
break;
case "ArrowRight":
moveRight();
break;
case "Escape":
closeModal();
break;
}
});
パターン(3): Reducer パターン(React / useReducer)
JavaScript
// React の useReducer で頻繁に使われるパターン
function reducer(state, action) {
switch (action.type) {
case "INCREMENT":
return { ...state, count: state.count + 1 };
case "DECREMENT":
return { ...state, count: state.count - 1 };
case "RESET":
return { ...state, count: 0 };
default:
throw new Error(`Unknown action: ${action.type}`);
}
}
パターン(4): 月の日数を取得
JavaScript
function getDaysInMonth(month) {
switch (month) {
case 2:
return 28; // 簡略化(うるう年は別途処理)
case 4: case 6: case 9: case 11:
return 30;
default:
return 31;
}
}
よくある間違い
| 間違い | 問題 | 対策 |
|---|---|---|
| break を忘れる | 後続の case が全て実行される(フォールスルー) | 各 case の末尾に必ず break / return を書く |
| case に型が異なる値 | switch は === で比較。case “1” と switch(1) は不一致 | 型を揃える。数値なら case 1、文字列なら case “1” |
| case 内で let/const を直接宣言 | 同じスコープで重複宣言エラー | 各 case を { } で囲んでブロックスコープにする |
| default を省略 | 想定外の値で何も処理されない | default でエラーログや例外を出す |
よくある質問
Qswitch は === で比較しますか? == ですか?
A=== (厳密等価)で比較します。型変換は行われないため、
switch (1) に対して case "1": は一致しません。Qdefault は必須ですか?
A必須ではありませんが、書くことを強く推奨します。想定外の値が来たときにエラーログを出したり例外を投げたりすることで、バグの早期発見につながります。
Qbreak の代わりに return を使えますか?
Aはい。関数内の switch では
return で値を返せば break は不要です。break 忘れのバグがなくなるため、関数内では return パターンが推奨です。Qswitch と if はどちらが速いですか?
A現代の JavaScript エンジンではパフォーマンスの差はほぼありません。可読性と保守性で選んでください。値の一致判定が 3 つ以上なら switch、範囲条件や複合条件なら if が適しています。
Qswitch の中に if 文を書いてもいいですか?
Aはい。case の中に if 文を書くことは可能で、特に問題ありません。ただし、ロジックが複雑になる場合は関数に切り出して case から呼び出す方が可読性が向上します。
QTypeScript では switch 文に特別な機能がありますか?
ATypeScript では switch 文と判別可能なユニオン型(Discriminated Unions)を組み合わせることで、case の網羅チェック(exhaustive check)をコンパイル時に行えます。default で
never 型を使うと、未処理の case があればコンパイルエラーになります。まとめ
switch 文の要点をまとめます。
| ポイント | 内容 |
|---|---|
| 基本構文 | switch (値) { case 候補: 処理; break; default: 処理; } |
| 比較方法 | ===(厳密等価)。型変換なし |
| break 必須 | 忘れるとフォールスルー(後続 case が全実行) |
| 複数 case のグルーピング | case “A”: case “B”: 処理; break; |
| 関数内では return 推奨 | break 忘れのリスクをゼロにできる |
| case 内の変数宣言 | { } で囲んでブロックスコープにする |
| 値 → ラベルの単純マッピング | オブジェクトマップ(switch より簡潔) |
| 範囲条件・複合条件 | if 文を使う(switch は等価比較のみ) |
if 文の詳細は「if 文による条件分岐の書き方」、三項演算子は「三項演算子の使い方」も併せて参照してください。