if / else if / else で段階判定
このレッスンで分かること
else ifをつなげると 3 つ以上に分けられます- 上から順に評価され、最初に当てはまった 1 つだけが動きます
if を並べただけだと、全部が動いてしまう
判定が 2 択で済まない場面はいくらでもあります。プロフィールサイトの作品に、閲覧数で 3 段階のラベルを付けたいとしましょう。前のレッスンの if をそのまま 3 つ並べると、こうなります。
JavaScript
// NG。views が 300 のとき、3 つとも実行される
let label = "";
if (views >= 200) { label = "人気"; }
if (views >= 100) { label = "注目"; }
if (views >= 1) { label = "これから"; }
// label は "これから" になってしまうif を並べるのは、独立した質問を 3 回することです。300 は 3 つとも満たすので代入が 3 回起き、最後に書いた値が勝ちます。ほしいのは「3 つのうち 1 つだけ」でした。それを書くのが else if です。
JavaScript
let label = "";
if (views >= 200) {
label = "人気";
} else if (views >= 100) {
label = "注目";
} else {
label = "これから";
}else if はいくつでもつなげられます。最後の else は「どれにも当てはまらなかったとき」の受け皿です。
ゆるい条件を先に書くと、後ろへ永遠に届かない
else if の連鎖は、上から順に評価して、最初に true になったところで打ち止めです。後ろの条件は評価すらされません。ですから並べる順番がすべてを決めます。
JavaScript
// NG。ゆるい条件を先に書いてしまった
if (views >= 1) {
return "これから";
} else if (views >= 100) {
return "注目";
} else if (views >= 200) {
return "人気";
}閲覧数が 500 でも「これから」が返ります。views >= 1 が最初に当たるので、その先には一生たどり着きません。下の 2 つは、書いてあるのに決して動かないコードになっています。数値の範囲で分けるときは、きびしい条件から順に並べるのが鉄則です。
裏を返すと、この性質のおかげで 2 つ目以降に上限を書き足す必要がありません。views >= 100 の枝に来た時点で、200 未満であることはすでに保証されています。
境目がどちらに入るか分からなくなる
枝が増えるほど、範囲の重なりや抜けが見えにくくなります。コードを書く前に、範囲を表にしてしまうのがいちばん確実です。
| 閲覧数 | 戻り値 | 条件式 |
|---|---|---|
| 200 以上 | "人気" | views >= 200 |
| 100 以上 200 未満 | "注目" | views >= 100 |
| 100 未満 | "これから" | else |
表にすると、ちょうど 200 がどちらの行に属するかがひと目で分かります。あとは表を上から順にコードへ書き写すだけです。表の行数と枝の数が合っていれば、抜けも重なりもありません。
範囲を表にする作業は、実務ではそのまま仕様の確認になります。「99 はどちらですか」と聞けば、仕様の穴がその場で見つかります。
よくある間違い
- 上限を二重に書く —
else ifは前の条件がfalseのときにしか来ないので、views >= 100 && views < 200の後半は不要です - 最後の
elseを書き忘れる — どの範囲にも当てはまらない値が来たときにundefinedが返ります。最後は必ずelseで受け止めてください
要件
- 関数名は skillLevel、引数は経験年数を表す数値 years の 1 つ
- 5 以上なら "上級"、3 以上 5 未満なら "中級"、1 以上 3 未満なら "初級"、1 未満なら "入門" を返す
- if と else if と else をつなげて書き、必ずどれか 1 つの枝で値を返す
- 戻り値はすべて文字列にする
入出力例
skillLevel(0) → "入門"
skillLevel(1) → "初級"
skillLevel(3) → "中級"
skillLevel(5) → "上級"
skillLevel(12) → "上級"