JavaScriptの条件分岐JavaScript初心者ECMAScriptはじめに未経験からNode.jsの現場に配属された2019年新卒エンジニアが、学習の振り返りとしてJavaScriptの基礎の基礎をまとめます。過去のJavaScript基礎シリーズ↓JavaScriptでvarが推奨されない理由を整理してみた今回は、多くの書き方が存在するJavaScriptの条件分岐に関して、よりすっきりとした書き方を考えていきます。Goal思考停止のelseやswitchから離れる可読性やリファクタリングのしやすさの観点から、JavaScriptの条件分岐を使いこなすまず「すっきり」を定義する本記事で目指したい「すっきり」を、以下のように定義します。コードの可読性が高いことバグが生まれにくいこと後からリファクタリングがしやすいことコードの可読性が高いことプロジェクトとして複数人で開発をする際に、可読性の高いコードを書くことはとても重要です。「可読性」という言葉の意味するところは本記事では割愛しますが、こちらの記事がわかりやすくとても参考になるので、詳しく掘り下げたい方は併せてお読みください。可読性については、一人で自習ばかりしているとおろそかになってしまいがちな考え方なので、常に考えておく癖をつけておきたいですね。バグが生まれにくいことこれは、書き忘れや書き間違いによるバグが発生しにくい、といった意味合いです。期待していない動作の場合に、エラーとして表示される等でバグに気づきやすい書き方は、未然にバグを防げます。後からリファクタリングがしやすいこと後から仕様の追加や変更があった際に、対応しやすいコーディングを指します。こない方はこちらの記事が、リファクタリングの重要性を分かりやすくまとめていただいていますので、ぜひお読みください。JavaScriptの条件分岐をおさらいということで、「可読性が高く」「バグが生まれにくく」「後からリファクタリングがしやすい」条件分岐の書き方を考えていきたいと思うのですが、その前にまず、JavaScriptの条件分岐に用いられる基本的な構文を整理します。ログの出力結果は"true"多くのプログラミング教材で最初に習う条件分岐が、おそらくこの構文ではないかと思われます。if文で条件に合致した場合の式が実行され、合致しなかった場合はelseが実行されます。条件に合致しない場合はif文以下の実行が無視されるだけなので、上の例のような単純な真偽判定のみであれば、以下のようにelseを省略することが可能です。出力結果は"false"こちらも、初歩的な条件分岐としてよく出てきますね。3つ以上の条件分岐が必要な場合に活用する構文です。if」構文というものはありません。実際の挙動としてはelse文の中でさらにif節とelse節のネストが生成されているのと等しいようです。この書き方でもelseの省略が可能です。以下のコードは上記の例と同様の実行結果となります。出力結果は"イーブイ"こちらも、複数の分岐が発生する条件式における定番の書き方です。○○:で条件を分岐させ、いずれのcaseにも一致しなかった場合はdefaultの式が実行されます。注意すべき点は、case節やdefault節で条件分岐の処理を書いた後のbreakの有無によって、switchの実行が異なるという点です。switch文は、処理の中でbreakが入力されていた場合に条件の判定をやめ、switch文を抜けて次の文から実行を続けます。breakが入力されていないと条件に合致したcase節があってもswitch文が継続されてしまうのです。breakが無い場合の挙動は以下のようになります。上の例では、test関数を利用して、引数pokemonを正規表現によって判定する関数を実行しているのですが、breakを書かなかったせいで、手前のcaseに合致する場合でも全てのcaseで判定が行われ、意図しない結果が出力されてしまっています。breakを書けばこのバグは防ぐことができます。breakしないswitchの書き方というのもあるようですが、基本的にswitchを使うならbreakを忘れずに書いた方が安心ではないかと思います。case節で直接return文を書き、条件に一致したcase以降の式を読み取らせないようにするのが良いでしょう。三項演算子ifを用いない条件分岐の書き方として、三項演算子というものがあります。これは、if文でブロックを分けたくない場合に、コンパクトに条件分岐を書くことができるとても便利な構文です。構文は以下の通りです。条件がfalseの場合の処理たとえば以下のように、変数に代入する値を条件分岐で決めたい時に使われることが多いです。出力結果は"サニーゴはゴーストタイプです"三項演算子を使わずにこれを記述すると、以下のようになります。出力結果は"サニーゴはゴーストタイプです"else文だと、コードのブロックが増えていたり、関数の上部でletを宣言してから再代入をするような書き方を余儀なくされたり、少し「すっきり」ではなくなっている、という感覚を掴んでいただけるかと思います。(論理OR)といった論理演算子を用いたショートカットの構文も、条件分岐の一種として活用することができます。構文は以下の通りです。空文字列(""))だった場合に、必ず"イーブイ"を戻り値にする関数が実行されています。条件がfalsyだった場合、デフォルトの返り値を短いコードで表現する際に、よく用いられる書き方です。この書き方が見慣れない方は、以下のコードを見てもらえば挙動のイメージがつくかと思います。pokemon;};ちなみに、短絡演算子ではfalsyな値を全て一律に評価するので、たとえば引数がundefinedの時のみデフォルトを返すようにしたい、というような場合は、以下のように書く必要があります。出力結果はnullすっきりな条件分岐を考えるJavaScriptの主な条件分岐の書き方をおさらいしたところで、ここから「可読性が高く」、「バグが生まれにくく」、「後からリファクタリングがしやすい」、すっきりした条件分岐の書き方を追求します。結論から言うと、本記事の主張は以下の3点です。ショートカット演算子は使いどころをきちんと定め、多用しないようにする実践のコーディングでelseは使わなくてよい複数の条件分岐はswitch以外の書き方も覚えておくこと何でもショートカット演算子、ではNG三項演算子や短絡演算子は、一行で条件分岐が記述できる便利な構文のため、つい多用してしまいがちになりますが、何にでも使えばいいというわけではなく、かえって可読性を下げてしまう場面もあります。上記のコードでは、引数sunnygoのtypeプロパティが"ゴースト"という文字列か空文字だった場合はtrueを、それ以外の場合はtypeの値を"みず・いわ"にする、というような関数を無理やりショートカット演算子で1行にして記述していますが、何が返ってくる関数なのかが一目で分かりづらいことになっていますね。(実際にこんなコードを書く人はいないと思いますが、あくまで「やろうと思えばこういうことが出来てしまう」という悪い例なので大目に見てください......。)入り組んだ条件分岐は、素直にifで書きましょう。出力結果は「みず・いわ」``elseって必要?個人的に、elseは使わなくても良い、と考えています。私は実務のコーディングでelseを書いたことがありませんが、その理由がelseがどうしても必要になる場面がないからです。elseは分岐の条件を書かないため、else節の処理の意味がつかみづらくなるという短所があります。「if節の条件がfalseの場合」を強調したいなら三項演算子で良く、そうでなくとも、if節でreturn文を書いてif節の外でデフォルトの値をreturnする、という風に書けば良いので、ブロックを増やしてまでelse節を記述する必要はないのです。ifとそれ以外、という条件の分け方を行う場合、else節は無くても大丈夫です。ifを使いたい場面では、たいていswitch文を使うか、ifをひとつずつ書いていく方が「すっきり」する場合が多いです。else文はコーディングの勉強で活用するにとどめ、実践ではelseを書かないクセをつけると良いかと思います。switchばかり使うのは危険?複数の条件分岐を書こうというときにswitch文は非常に便利な構文ですが、switchしか解決法を持っていないと、しばしば困る場面も訪れます。先述のとおり、switchはbreakの仕様のおかげで、気をつけないとバグを生んでしまう構文です。3~4ケースの条件分岐ならあまり気になりませんが、分岐が100ケースを超えたりすると、switchだと非常に読みづらいです。}};上記は、ポケモンの名前に応じた図鑑ナンバーを返すプログラムを書こうとしているところなのですが、switchで151ケース(default含めると152ケース)の条件分岐を行うことがいかに無謀なことなのかは、何となくお分かりいただけるかと思います。この書き方だとポケモンに少し詳しい人じゃないと図鑑ナンバーのことを言っていることが伝わりづらい。した時のために、switch以外で複数の条件分岐を書く術も、いくつかあると良いでしょう。私がよく使っているのが、find関数を用いた条件分岐です。)これは、配列の要素それぞれに対してコールバック関数を実行し、最初にtrueな値を返すという関数です。本来は配列を扱うための関数なのですが、これを活用することで、たとえば以下のように条件分岐を書くことができます。//出力結果は52;上記のコードでは、配列pokemonListに分岐の対象となっているポケモンの名前と図鑑ナンバーのセットを格納し、関数pokemonIndexで、引数に指定したポケモンの名前とpokemonListに格納されたnameが一致するまで配列内で検索を行い、配列で最初に一致した値を返しています。switchで書く場合と比較して、objectとして要素を扱うのでコピペがしやすかったり、ページ内検索がかけやすかったりするため、リファクタリングのしやすさが格段に上がっていることがお分かりいただけたら幸いです。これなら、ある日突然、全国図鑑になったとしても充分に対応できます。三項演算子:変数の代入でサクッと条件分岐したいときに使おう短絡演算子:デフォルトの値を明示したいときに使おうfind関数は良いぞJavaScriptには色々な構文がありますが、それぞれの長所・短所を踏まえつつ、すっきりしたコーディングを目指していけると良いのかな、と思います。間違い、不足点の指摘などあれば、コメントをお願いいたします。requestStockLike146大樹@taiju_suzukiJavaScript大好きな文系出身19卒エンジニアです。システム内製支援事業。問い合わせフォームをご利用ください。upLoginユーザーは見つかりませんでした。