JavaScriptにおいて、条件分岐はプログラムの論理構造を決定する最も基本的な要素です。
しかし、単純な条件分岐に対して毎回数行にわたるifブロックを記述することは、コードの縦の長さを増大させ、可読性を損なう原因にもなり得ます。
モダンなJavaScript開発では、コードを簡潔かつ直感的に記述することが求められます。
特に、関数の戻り値を決定する際や、ReactなどのUIフレームワークでコンポーネントの表示を切り替える際には、1行で条件分岐を記述する手法が非常に効果的です。
本記事では、三項演算子や短絡評価、そしてNull合体演算子などを用いて、if文をスマートに1行で記述する具体的なテクニックを詳しく解説します。
1. 基本的なif文の1行記述
JavaScriptでは、if文の後に実行する文が1つだけである場合、波括弧{}を省略して1行で記述することが可能です。
これが最も原始的な「1行のif文」です。
波括弧を省略する書き方
通常、複数行で書くif文は以下のようになります。
const isAdmin = true;
if (isAdmin) {
console.log("管理者としてログインしました");
}
これを1行にまとめると、以下のようになります。
const isAdmin = true;
if (isAdmin) console.log("管理者としてログインしました");
この記述方法は、デバッグ用のログ出力や、関数の冒頭でのガード句(条件不一致による早期リターン)でよく利用されます。
ガード句での活用例
ガード句とは、特定の条件を満たさない場合に直ちに処理を終了させる手法です。
function processData(data) {
if (!data) return; // データがない場合は何もしない
// 以降、データの処理が続く
console.log("データを処理中:", data);
}
processData(null);
processData("有効なデータ");
データを処理中: 有効なデータ
波括弧を省略する手法は簡潔ですが、複数の文を実行したい場合には対応できません。
また、プロジェクトのコーディング規約によっては「常に波括弧を付けること」が推奨されている場合もあるため、チームの方針を事前に確認しておくことが重要です。
2. 三項演算子による値の代入
条件によって変数に代入する値を変えたい場合、最も適しているのが三項演算子(条件演算子)です。
三項演算子の基本構文
三項演算子は、条件 ? 真の場合の式 : 偽の場合の式 という形式で記述します。
const age = 20;
const status = age >= 18 ? "成人" : "未成年";
console.log(status);
成人
通常のif文で書くと4〜5行必要になる処理が、三項演算子を使えばわずか1行で完結します。
特に、定数constに対して条件付きで値を代入したい場合には、三項演算子が不可欠です。
if文を使用すると再代入可能なletを使わざるを得ませんが、三項演算子ならイミュータブル(不変)な宣言が可能です。
三項演算子のネストとその注意点
三項演算子の中にさらに三項演算子を記述することで、3つ以上の条件分岐を1行で行うこともできます。
const score = 85;
const grade = score >= 90 ? "A" : score >= 80 ? "B" : "C";
console.log(grade);
B
ただし、ネストが深くなるとコードの可読性が著しく低下します。一般的には、2段階程度のネストまでが許容範囲とされており、それ以上に複雑になる場合は、素直にif-else if文やswitch文、あるいはオブジェクトマッピングを利用することを検討してください。
3. 論理演算子による短絡評価の活用
JavaScriptの論理演算子(&& や ||)には、短絡評価(ショートサーキット)という特性があります。
これを利用することで、if文を使わずに条件付きの処理を実行できます。
論理積(&&)による条件実行
A && B という式において、Aが偽(Falsy)であればBは評価されません。
逆に、Aが真(Truthy)であればBが実行されます。
これを利用して、「条件が真の時だけ関数を実行する」という記述が可能です。
const isLoaded = true;
// if (isLoaded) renderData(); と同等
isLoaded && console.log("データを表示します");
データを表示します
このパターンは、ReactのJSX内で特定の要素を表示・非表示にする際によく使われるテクニックです。
論理和(||)によるデフォルト値の設定
A || B という式において、Aが真であればAが返され、Aが偽であればBが返されます。
これを利用して、変数にデフォルト値を設定することができます。
function greet(name) {
const userName = name || "ゲスト";
console.log("こんにちは、" + userName + "さん");
}
greet("田中");
greet(""); // 空文字はFalsyなのでデフォルト値が使われる
こんにちは、田中さん
こんにちは、ゲストさん
Null合体演算子(??)による厳密な評価
論理和(||)には、0や空文字""も「偽」と判定してしまうという副作用があります。
これを解決するために導入されたのがNull合体演算子(??)です。
?? は、左辺が null または undefined の場合のみ右辺を返します。
const config = {
timeout: 0,
title: ""
};
const timeout = config.timeout ?? 3000;
const title = config.title ?? "無題";
console.log("Timeout:", timeout);
console.log("Title:", title);
Timeout: 0
Title: ""
もしここで || を使用していた場合、timeout は 3000 になり、title は “無題” になってしまいます。
数値の 0 や空文字を有効な値として扱いたい場合は、必ず ?? を使用しましょう。
4. 各手法の比較と使い分け
1行でif文を書く手法には複数の種類がありますが、状況に応じて適切なものを選択する必要があります。
以下の表に特徴をまとめました。
| 手法 | 構文 | 適したユースケース | 特徴 |
|---|---|---|---|
| if文 (省略形) | if (cond) func(); | 単一の副作用(実行) | シンプルだが拡張性に欠ける |
| 三項演算子 | cond ? a : b | 値の代入・返却 | 必須のelse処理がある場合に最適 |
| 論理積 (&&) | cond && func(); | 真の時のみ実行 | ReactのJSXなどで多用される |
| 論理和 (||) | val || default | デフォルト値の設定 | Falsyな値すべてを対象とする |
| Null合体 (??) | val ?? default | 厳密な初期値設定 | null/undefinedのみを対象とする |
スマートな使い分けの基準
- 値を返したいか、処理を実行したいか:値を返したいなら三項演算子、処理を実行するだけなら短絡評価が適しています。
- elseが必要か:条件が合わない時の処理も記述する必要があるなら三項演算子一択です。
- 値の厳密性:数値の0やfalseという値を保持したい場合は、論理和ではなくNull合体演算子を使用してください。
5. オプショナルチェイニングとの組み合わせ
モダンJavaScriptでは、オプショナルチェイニング(?.)と1行の条件分岐を組み合わせることで、深い階層にあるプロパティへのアクセスを安全かつ簡潔に行うことができます。
const user = {
profile: {
// nickname は未定義
}
};
// 従来の書き方
const nameOld = user && user.profile && user.profile.nickname ? user.profile.nickname : "匿名";
// モダンな書き方(オプショナルチェイニング + Null合体演算子)
const nameModern = user?.profile?.nickname ?? "匿名";
console.log(nameModern);
匿名
このように、複数のプロパティが存在するかを確認するif文の羅列も、演算子を組み合わせることで極めてスマートに1行に集約できます。
これはエラーを未然に防ぎつつ、コードの意図を明確にする非常に強力な手法です。
6. 実践:テンプレートリテラル内での活用
1行のif文(特に三項演算子)が最も威力を発揮するシーンの一つが、テンプレートリテラル内での動的な文字列生成です。
const tasks = ["宿題", "掃除"];
const message = `未完了のタスクは ${tasks.length > 0 ? tasks.length + "件です" : "ありません"}。`;
console.log(message);
未完了のタスクは 2件です。
テンプレートリテラル ${...} の中には、文(if文など)は書けませんが、式(三項演算子など)は書けるというルールがあります。
そのため、文字列の中に条件分岐を埋め込みたい場合は、三項演算子が唯一の選択肢となります。
7. 1行記述を避けるべきケースと可読性
「1行で書ける」からといって、あらゆる場所でこれらのテクニックを多用すべきではありません。
プログラミングにおいて最も優先されるべきは、「後で読む人が理解しやすいかどうか」です。
避けるべき例:複雑な副作用を持つ式
三項演算子の「真の場合」や「偽の場合」の部分に、複数の処理を詰め込んだり、複雑な計算式を記述したりするのは避けましょう。
// アンチパターン:読みづらい
const result = x > 10 ? (y = x * 2, z = y + 5, z) : x;
このようなコードは、一見スマートに見えてもバグの温床になりやすく、デバッグも困難です。
処理が複雑になる場合は、たとえ1行で書けたとしても、適切に改行し、波括弧を用いた通常のif文で記述することを強く推奨します。
Prettierなどのフォーマッタとの付き合い方
現代の開発環境では、Prettierなどのコードフォーマッタが自動的にコードを整形します。
自分が1行で書いたつもりでも、保存時に自動で複数行に分割されることがあります。
これは「1行にするよりも複数行の方が読みやすい」というフォーマッタの判断です。
ツールによって整形された結果、複数行になったとしても、無理に1行に戻そうとせず、ツールが提示する「読みやすい形」を受け入れることも大切です。
まとめ
JavaScriptでif文を1行で書く手法は、コードのノイズを減らし、ロジックを直感的に伝えるための強力な武器になります。
- 三項演算子は、条件によって異なる値を代入したい場合に最適です。
- 短絡評価(&&, ||)は、特定の条件下での実行や、デフォルト値の設定を簡潔にします。
- Null合体演算子(??)は、nullやundefinedを厳密に判定し、予期せぬ挙動を防ぎます。
- オプショナルチェイニング(?.)との組み合わせで、オブジェクトへのアクセスがより安全になります。
これらのテクニックを適切に使い分けることで、あなたのコードはよりモダンで、プロフェッショナルなものへと進化します。
ただし、常に「可読性」を最優先に考え、複雑すぎる1行記述は避けるというバランス感覚を忘れないようにしましょう。
簡潔なコードは、メンテナンス性の向上だけでなく、開発者自身の意図をより明確に他のメンバーへ伝える手段となります。
今回紹介した手法を、日々のコーディングにぜひ取り入れてみてください。
