三項演算子とは、if文とおなじように、
条件が truthy だったらこう、 falsy だったらこう という命令を書ける構文です。
条件 ? /* truthyのときの分岐 */ : /* falsyのときの分岐 */ ;
使う目的が似ているので、初学者ならだれでも使い分け方が気になるとおもいますが
if文と三項演算子の違いを調べると「if文は文で、三項演算子は式である」みたいな、
だからなんやねんって話がよく出てくるので、
実際にJavaScriptで三項演算子を使うとき、どういう違いがあるのかという話だけをまとめました。
if文
分岐条件が複雑なときも読みやすい
何重にも条件分岐するときや、else if で続いていく処理を書くときはif文のほうが向いてます。(読みやすいので)
if( 条件1 ) {
// 条件1 が true のときに処理する内容
if( 条件2 ) {
// 条件1 が true で さらに 条件2 も true のときに処理する内容
}
} else if( 条件1 ) {
// 条件1 が false のときに処理する内容
if( 条件2 ){
// 条件1 が false で さらに 条件2 が true のときに処理する内容
}
}
これが三項演算子だった場合、地獄のコードになります。
※ ただし三項演算子に比べれば読みやすいというだけです。そもそも分岐条件が複雑な時点で読みづらいので、基本的にこのような書き方にならないように設計することが大事です。
何行も処理が書ける
あとで説明しますが、三項演算子の分岐処理には複数行にわたる処理を書くことはできません。
そのため、条件の結果によって実行したい処理が2行以上になるなら、if文がおすすめです。
if( 条件 ){
// ここの処理が
// 何行になっても
// 問題なし!
}
スコープができる
if文も、関数と同じで波括弧{}
があるので、
スコープができます。
(スコープ…{}
の中で作った変数は、{}
の中でしか使えないというルールのこと)
if( 条件 ){ const 変数 = '条件OK'; }
// if文の外で a を使おうとしても、 a は if文のスコープの中で定義されているので、使えない。
console.log( 変数 ); // エラーがでます。
ちなみに if文の中の処理が1行ですむ処理の場合 波括弧{}
を省略できるというルールがありますが、
その書き方をつかった場合、スコープはできませんでした。
( ただし、const
や let
を使おうとするとエラーがでるようになります。 var
であればエラーが出ずに定義できましたが、予測できないトラブルが起きる可能性を否めないので、使わないほうがいいでしょう。)
変数定義や条件式の途中に組み込むことができない
if文は三項演算子と違い、変数定義や条件式の途中にねじこむような書き方はできず、
独立させて使う必要があります。
たとえば条件によって変数に代入する値を変えたい場合も、
if文を変数定義に組み込むことはできず、独立させる必要があるため、
変数を再代入するような書き方になります。
( 再代入をする必要があるということは、const
ではなくlet
を使う必要がある )
let 変数;
if( 条件 ){
変数 = '条件OK';
} else {
変数 = '条件NG';
}
三項演算子
短く書ける
if文と違い、短く書けます。
条件 ? /* trythyのときの分岐 */ : /* falsyのときの分岐 */ ;
処理は1行分(ワンライン)しか書けない
三項演算子は、条件がtrue/falseだったときの処理を何行も書くことはできません。
ちなみに、こういうときに言う「1行分」というのは、
コードを改行しているかどうかという話だけじゃなく、
「本来セミコロンで区切られるようなひとまとまりの処理」という意味もあるので、
改行しなければたくさんの処理ができる、というわけではないです。
// このような複数の処理は、たとえ改行しなかったとしても、できない。
条件 ?
変数 = '条件OK'
console.log( 変数 )
:
変数 = '条件NG'
console.log( 変数 )
;
もちろん、複数の処理を関数にわけておいて、それを実行するだけなら
三項演算子の部分は1行ですむので、実行できます。
function OK(){ 変数 = '条件OK'; console.log( 変数 ); }
function NG(){ 変数 = '条件NG'; console.log( 変数 ); }
// 1行ですむなら実行できる
条件 ? OK() : NG() ;
※ 記事を読みやすくするためにOK()
やNG()
の関数の中身を改行せずに書きましたが、改行してあっても実行できます。
条件に合致しないときの処理も必ず書く必要がある
if文であれば、else文(条件に合致しないときの処理)を省略することができますが、
三項演算子は ? : ;
で1つのセットなので、
条件に合致しないときの処理を省略することはできません。
もちろん条件に合致しないときは何も起きないようにと書くことはできますが、
そういうときに三項演算子を使うのはおかしい、という話になるとおもいます。
// 一致しないときは null とする等、なにもおきないように書くこともできる
条件 ? console.log(変数) : null ;
// でもif文のほうがいいよね
if( 条件 ) console.log(変数);
変数定義や条件式の途中に組み込むことができる
ここが三項演算子の一番重要な点です。
「三項演算子は式である」みたいな説明されるのも、ここを一番伝えたいからなんだと思います。
三項演算子は、コードの途中にねじこむ書き方ができます。
たとえば 変数
という名前の変数を定義することは決まりきっていて、
そのなかの値だけ条件によって変わる場合、
下記のように、変数を宣言する const
のあとに三項演算子をねじこむような書き方ができます。
const 変数 = 条件 ? '条件OK' : '条件NG' ;
さきほどのif文の例だと、下記のような書き方になるのでコードが長くなるし、
let での定義になるので、定数にできない点がすこし気になりますよね。
let 変数;
if( 条件 ){
変数 = '条件OK';
} else {
変数 = '条件NG';
}
ちなみに、「条件式に組み込む」というのは下記のような書き方の話ですが
あくまで、条件式に限らず、いろんなところにねじこめるという説明をしたいだけです。
if( 条件 ? 条件OKのときに条件式につかう値 : 条件NGのときに条件式につかう値 ){
// 「条件OKのときに条件式につかう値」がtruthyだったときの処理
} else {
// 「条件NGのときに条件式につかう値」がfalsyだったときの処理
}
※ このように、セミコロンが使えないところ(ワンラインで書くと決まっているところ)にねじこむときは、セミコロンを省略してもOK。
かなり読みづらい書き方だとおもうので、
こういう使い方をおすすめするわけではないです。
スコープができない
波括弧{}
を使わない書き方なので、if文と違ってスコープができないという特徴があります。
ただし、三項演算子のなかで const
や let
を使おうとするとエラーがでるので、
どういうときに便利なのかという具体例を説明するのは難しいのですが。
細かい話はいいから、どう使い分ればいいか知りたい
下記のような考え方で使えば、トラブルになることは少ないと思う。
三項演算子
ある条件がtruethyであってもfalsyであっても、同じ名前の変数を定義したい。
だけど、変数の中身は条件によって変えたい。
そんなときは三項演算子。
const 変数 = 条件 ? '条件OK' : '条件NG' ;
ただし、チームで開発するならば、
この書き方が読みやすいと多くの人達が共感してくれることが条件。
if文
それ以外のとき。