if文とは
if
文は条件によって処理を変えるための構文です。
条件分岐と呼ばれることもあります。
基本構文
if
文は2つの要素から構成されます。
- 条件式: 処理をするかどうかを判定する真偽値
- 処理
構文はこんな感じです。
if (条件式) {
// 処理
}
例えば、number
変数が10
以上のときのみログ出力する処理が書けます。
const number = 12
if (number >= 10) { // numberは12なのでtrue
console.log('numberは10以上です')
}
// ログは出力される
const number = 8
if (number >= 10) { // numberは8なのでfalse
console.log('numberは10以上です')
}
// ログは出力されない
なお、ブロック({}
)は省略することもできます。
if (条件式) 1行の処理
// 例
if (number >= 10) console.log('numberは10以上です')
else
elseを使うと、条件式がfalse
の場合に実行する処理を追加できます。
if (条件式) {
// trueの場合に実行される処理
} else {
// falseの場合に実行される処理
}
else if
また、else if
を使うと、最初の条件がfalse
だった場合の新しい条件を加えることができます。
if (条件式1) {
// 条件式1がtrueの場合に実行される処理
} else if (条件式2) {
// 条件式1がfalseかつ、
// 条件式2がtrueの場合に実行される処理
} else {
// 条件式1がfalseかつ、
// 条件式2がfalseの場合に実行される処理
}
同じ処理はif
文の中にif
文を書くことでもできます。
if (条件式1) {
// 条件式1がtrueの場合に実行される処理
} else {
if (条件式2) {
// 条件式1がfalseかつ、
// 条件式2がtrueの場合に実行される処理
} else {
// 条件式1がfalseかつ、
// 条件式2がfalseの場合に実行される処理
}
}
しかし、左側の余白が増える(ネストが深くなる)とコードが読みづらくなってしまうことがあります。
そのため、使う機会は条件式1がfalse
だった場合に共通の処理があるなど、結構限られてくるかもしれません。
if (条件式1) {
// 略
} else {
// 条件式1がfalseの場合に実行される、共通の処理
if (条件式2) {
// 略
} else {
// 略
}
}
用途
ここからはif
文の使い所を紹介します。
条件分岐
先ほども説明した通り、if
文は条件に応じて処理を変えることができます。
これを条件分岐と呼ぶことがあります。
条件分岐はとにかくいろんなところで使えます。
例えばこれは、入力されたスコアに応じて出力されるログを変える処理です。
// prompt関数で入力を受け取る
const score = parseInt(prompt())
if (score >= 90) {
console.log('素晴らしい!');
} else if (score >= 75) {
console.log('良い感じ!');
} else {
console.log('もう少し頑張りましょう');
}
早期リターン
if
文の活用方法として、関数の早期リターンがあります。
早期リターンというのは、主に関数の最初のほうで処理したくない場合を検知し、早めにそれ以降の処理を中断することです。
もっと平たく言えば、最初の方にif
文を使ってreturn
を書くことです。
function sample() {
if (条件式) return; // これが早期リターン
// 処理
}
これは引数のチェックなどに使えます。
早期リターンを使うメリットとして、普通にif
文を使うよりネストが深くなりづらいことが挙げられます。
この普通のif
文を使うというのは、例えばこんな感じのコードになります。
function sample() {
if (条件式) {
// 通常の処理
// この処理は数行以上ある
}
// ここには何の処理もない
}
このように書くと、通常の処理の部分のネストが深くなり、コードが読みづらくなってしまうことがあります。
もちろん一概には言えないのですが、このように書くより、早期リターンを使ったほうが読みやすくなることは多いです。
function sample() {
if (条件式) return // 何の処理も必要ないので、returnで中断する
// 通常の処理
// この処理は数行以上ある
}
早期リターンの例
例えば、配列の数値の和を返すsum
関数があります。
この関数は引数に配列を取ります。
また、以下の条件では配列の合計を計算しません。
- 長さが0の場合:
null
を返す - 負の数が混ざっている場合: その数は足さない
このとき、早期リターンを使って以下のように実装できます。
(reduce
メソッドを使う手もありますが、今回はfor
文で実装します。)
function sum(array) {
// 早期リターン1: 配列の長さが0ならnullを返す
if (array.length === 0) return null
let result = 0
for (const num of array) {
// 早期リターン(?)2: numが負の数なら何も足さない
if (num) continue // 次のループに行く
result += num
}
return result
}
こんなふうに最初にreturn
などを持ってくることで、コードのネストが減って読みやすくなります。
早期リターンという言葉の定義は結構曖昧な印象があります。
そのため何が早期リターンかどうか定義するのは難しいです`、「これ早期リターンっぽいな」と言うことはできます。
この際、以下の場合でも早期リターンかもしれません。
-
return
ではなくthrow
などでエラーをスローしている -
return
以外にいくつかの処理がある -
メイン処理がどうとかではなく、いろんな条件がたくさんある関数で
if
文をネストしない(例)
とりあえず、メイン処理をif
文の外に置いたりすることで、結果的にコードのネストを減らすテクニックがあるってことだけ知っていたらいいと思います。
if
文の詳細はMDNをご覧ください。
また、こちらにはif
文の解説のほかに比較に使える演算子の話もあります。
三項演算子
if
文と似たような役割の構文として、三項演算子があります。
三項演算子は条件によってどの値を使うか決められる式です。
// 条件がtrueなら値1、そうでないなら値2を使いたい
条件 ? 値1 : 値2
例えば、変数の値を条件に応じて変えるときに役立ちます。
const score = 55
const result = (score >= 60) ? '合格' : '不合格';
console.log(`テストの結果は${result}です`)
// テストの結果は不合格です
詳細はMDNをご覧ください。
また、こちらの記事もわかりやすいです。
三項演算子の問題
複雑な条件が続く場合に使いすぎると、コードが読みづらくなるという話があります。
例えば、以下のように2つの条件から3つの出力がある場合を想定します。
const result = mathScore === 100
? scienceScore === 100
? '非常に素晴らしいです!'
: '素晴らしいです!'
: '数学で100点を目指しましょう'
どうでしょうか。簡単に読めましたか?
以下にこのコードの図解を用意しましたが、その前に一度読み解いてみてください。
このコードはやたらと数学優位なメッセージをresult
に代入しています。
なので、もし理科で100点を取ったとしても「数学で100点を目指しましょう」が代入されます。
もし簡単に読めたという方でも、これ以上ネストが増えると読みづらくなってくると思います。
三項演算子はあまりネストしすぎず、そして大きな処理を書きすぎないようにしましょう。
複雑な処理が必要になりそうなら別の関数に分けてif
文で書き直すなどの対策をとったほうがいいです。
ちなみに私は三項演算子が便利すぎて、ついついネストしてしまいます。
しかし今思えば、あの時書いたコードもあのコードも、すでに読める気がしません(手遅れ)。