javascriptのifやswitchは式ではない
javascriptのifやswitchは式ではなく文です。
要するに、それ自体が値を返すことが出来ません。
関数型言語はifが式のものも多いですが(kotlinとか)
javascriptは後方互換性が重視されるタイプの言語なのでクラシカルな文形式です。
と言うわけで、コードを固い方向に寄せるためになるべくconstを使おうとしたりすると
すぐ問題にぶち当たります。
例えば、以下のようなコードは通りません。
const hoge;
if(fuga){
hoge = "fuga";
}else{
hoge = "piyo";
}
constの初期化時に条件に応じて異なる値を入れるというようなありふれたケースにすらjavascriptのifは対応できないわけです。
当然、switch文も同様です。妥協してletやvarを使うのも手ですが、なるべくそれは避けたいですし、
React+JSXにおける{}
の中など単純にそれだけで逃げられないケースもあります。
三項演算子
一番手軽な解決策は三項演算子です。
演算子は値を返すので問題はありません。
const hoge = fuga ? "fuga" : "piyo";
条件部分や返すべき結果が短い場合は上記のようにいい感じになります。
しかし、常にそううまく行くわけではありません。
例えばcaseがいくつも連なるswitch文やifの条件部分が長いものまで三項演算子で書くのはどうでしょうか。
const hoge = fuga ? "fuga" : piyo ? "piyo" : hogehoge ? "hogehoge" :"hogePiyo"
短めのものを3つつなげただけでこれなので、相当気持ち悪いコードになることは間違いありません。
縦はともかく右方向に長いコードは可読性がかなり低くなります。
言語を問わず三項演算子を蛇蝎のごとく嫌う人がたまにいますが、おそらくこういうコードで苦しんだことがあるんでしょう。
関数に切り出す
function decideFugaOrPiyo(fuga) {
if(fuga){
return "fuga";
}
return "piyo";
}
const hoge = decideFugaOrPiyo(fuga);
そういう場合に有効な手段が、関数への切り出しです。
関数に切り出せば複雑な条件やswitch文があろうと問題ありません。
命名が適切ならば可読性もむしろ上がるケースが多いでしょう。
しかし、大した長さでは無かったり、再利用する予定のない場合はいちいち切り出した方が読みにくい場合もあります。
即時関数を使う
const hoge = (() => {
if(fuga){
return "fuga";
}
return "piyo";
})();
わざわざ切り出すほど複雑ではなくかといって三項演算子を使うにはちょっと…と言うようなケースには即時関数が便利です。
少々括弧が多くなりますが、思いの外インデントも深くならない(せいぜい1段下がるだけ)なので可読性の点でもそこまで悪くないと思います。
まとめ
- 短い・シンプル=>三項演算子
- 長い・複雑・再利用する=>関数切り出し
- 中間くらい=>即時関数