Q1>= 50000 を先に、>= 100000 を後に else if でつないだ分岐に 120000 を渡すと、どちらの枝が実行されますか?
条件分岐 — else if / 三項演算子 / switch
JavaScript の条件分岐を基礎から学びます。段階的に判定する else if、値を返す三項演算子、1 つの値で振り分ける switch と break の役割までを扱います。
会員ランクの判定や注文状態の表示では、条件が 2 つに割り切れないことがほとんどです。プラチナ・ゴールド・レギュラーの 3 段階を if を並べて書くと、上の条件で決まったあとも下の条件が判定され、当てはまる条件の数だけ表示が出てしまいます。
この記事では、段階的に判定する else if、値そのものを返す三項演算子、1 つの値を複数の候補と照合する switch を扱います。
3 段階以上に分ける — else if を続けて書く
商品レビューの平均点から評価のラベルを決めます。4.5 点以上なら「非常に高評価」、3.5 点以上なら「高評価」、どちらにも届かなければ「評価が低め」です。
if を 2 つ並べると判定が独立するため、4.8 点では両方の条件が成り立ち、「非常に高評価」と「高評価」の 2 行が表示されます。
else if(前の条件が成り立たなかったときだけ判定される、次の条件)を続けると、複数の条件を 1 つの分岐にできます。条件ごとに続く { } の中身を枝と呼びます。
条件は上から順に判定され、最初に成り立った枝だけが実行されます。どれにも当てはまらないときは else の枝が実行されます。
const score = 4.8; // 商品レビューの平均点
// if を並べると、それぞれが独立して判定される
if (score >= 4.5) {
console.log("非常に高評価"); // 成り立つ
}
if (score >= 3.5) {
console.log("高評価"); // ここも成り立つ → 表示は 2 行
}
// else if でつなぐと、最初に成り立った枝で分岐が終わる
if (score >= 4.5) {
console.log("非常に高評価"); // ここだけ実行される
} else if (score >= 3.5) {
console.log("高評価"); // 判定されない
} else {
console.log("評価が低め"); // 判定されない
}
4.8 点は 1 段目の score >= 4.5 で成立して右へ抜け、2 段目は判定されません。矢印が下の段へ進むのは、条件が不成立のときだけです。
else は省略できます。省略した分岐でどの条件にも当てはまらなければ、どの枝も実行されずに分岐の次の行へ進みます。
下の表は、同じ分岐に 3 つの点数を通したときに、どの段で判定が終わるかをまとめたものです。
| 平均点 | 上から順に判定 | 表示される行 |
|---|---|---|
| 4.8 点 | 4.5 以上が成立してここで終了 | 非常に高評価(1 行だけ) |
| 3.8 点 | 4.5 以上は不成立 / 3.5 以上が成立 | 高評価(1 行だけ) |
| 2.1 点 | どちらも不成立で else へ下りる | 評価が低め(1 行だけ) |
条件を書く順序で結果が変わります
当てはまる範囲が広い条件を先に置くと、範囲の狭い条件には処理が届きません。score >= 3.5 を先に書くと、4.8 点の商品も「高評価」で確定します。4.8 点を「非常に高評価」にするには、score >= 4.5 のように範囲の狭い条件から先に並べます。
結果を値で受け取る — 三項演算子の書き方
在庫数によって「在庫あり」「在庫切れ」を切り替え、その文字列を変数に入れて使い回したい場面があります。if と else で書くと、const は宣言と同時に値を入れる必要があるため使えず、先に let で宣言だけしておき、2 つの枝でそれぞれ代入する形になります。
stock > 0 のように評価すると 1 つの値が残る書き方を式、if (…) { … } のように処理を実行するだけで値が残らない書き方を文と呼びます。
三項演算子(条件・true のときの値・false のときの値の 3 つを取り、値そのものを返す式)なら、2 つの枝を 1 行で書けます。
const stock = 0; // 在庫数
// if は文なので、宣言と代入が分かれる
let label;
if (stock > 0) {
label = "在庫あり";
} else {
label = "在庫切れ";
}
console.log(label); // 在庫切れ
// 三項演算子は式なので、const に直接入れられる
const badge = stock > 0 ? "在庫あり" : "在庫切れ";
console.log(badge); // 在庫切れ
// テンプレートリテラルの中にもそのまま書ける
console.log(`状態: ${stock > 0 ? "購入できます" : "入荷待ちです"}`); // 状態: 入荷待ちです
分けたい先が 3 つ以上になるときは else if に戻します。三項演算子は入れ子にもできますが、a ? x : b ? y : z のように ? と : が 1 行に何度も現れ、どの条件がどの値に対応するのかを目で追うことになります。
1 つの値で振り分ける — switch と case
選ばれた支払い方法から、手数料の文言を決めます。else if でも書けますが、paymentMethod === "credit"、paymentMethod === "convenience" と同じ変数を何度も書くことになり、何を比べている分岐なのかが読み取りにくくなります。
switch(1 つの値を複数の候補と順に照合し、一致した枝から実行する構文)は、比べる対象を丸括弧に 1 回だけ書き、候補を case 値: で並べます。枝の最後の break で switch を抜け、どの case にも一致しないときは default: の枝を実行します。
const paymentMethod = "credit"; // 選ばれた支払い方法
switch (paymentMethod) {
case "credit":
console.log("手数料なし"); // ここが実行される
break;
case "convenience":
console.log("手数料 200 円"); // 一致しない
break;
case "cod":
console.log("手数料 330 円"); // 代金引換。一致しない
break;
default:
console.log("支払い方法を選んでください");
}
default は省略できます。省略した switch に一致しない値が来ると、どの枝も実行されずに次の行へ進みます。候補にない値が届くことがある場面では、default に文言を置いておくと、想定外の値が来たことに画面で気づけます。
case の照合は文字列と数値を区別します
switch の照合は === と同じで、型が違えば一致しません。入力欄から受け取った文字列の "200" は、case 200: には入らず default に進みます。数値と文字列が混ざる値は、照合の前にどちらかへそろえます。
次の case まで実行される — break の省略
switch でつまずきやすいのが break の書き忘れです。文法としては正しいので構文エラーにはならず、実行して初めて表示が 1 行では済んでいないことに気づきます。
フォールスルー(break が無いため、一致した case より下の case の処理も続けて実行されること。fall-through)が起きると、下の case に書いた値とは比べないまま、break に出会うか switch の終わりに届くまで処理が続きます。
const orderStatus = "paid"; // 注文の状態
// break が無いと、一致した case の下も続けて実行される
switch (orderStatus) {
case "paid":
console.log("入金済み"); // 一致してここから開始
case "shipped":
console.log("発送済み"); // break が無いので続く
default:
console.log("状態を確認してください"); // default まで実行される
}
// case を並べると、複数の候補を 1 つの処理にまとめられる
switch (orderStatus) {
case "pending":
case "paid":
console.log("発送前"); // pending と paid の両方がここに入る
break;
}
この動きは、複数の候補を同じ処理にまとめるときに使えます。処理を書かずに case を 2 つ並べると、上の case に一致したときもそのまま下の処理へ進みます。まとめた枝の末尾には break を書きます。
理解度チェック
まずは1問ずつ答えてみましょう。
Q2total >= 5000 ? 0 : 500 は、total が 5000 のとき何を返しますか?
Q3case の処理の最後に break を書き忘れると何が起きますか?