式と文
このトピックを終えると
式と文の違いを明確に理解し、「なぜこの場所でif文が使えないのか」という疑問を自分で解決できるようになります。
プログラミングの2つの単位
コードを書く際に、最も基本的な区別があります。
- 式 (expression):値を生成するコードの断片
- 文 (statement):動作を実行するコードの単位
この区別を理解することで、「なぜここにこのコードを入れるとエラーになるのか」という質問に対する答えがわかります。
式 — 値を生成する
式は、評価(evaluate)すると1つの値になるコードです。
// これらはすべて式です
5 // 数値リテラル → 5
"hello" // 文字列リテラル → "hello"
2 + 3 // 算術演算 → 5
x > 10 // 比較演算 → true または false
isValid ? "OK" : "X" // 三項演算子 → "OK" または "X"
myFunc(42) // 関数呼び出し → 戻り値式の主な特徴:変数に格納できます。
const result = 2 + 3; // ✅
const msg = isValid ? "OK" : "X"; // ✅
const val = myFunc(42); // ✅= の右側に置けるものは式です。
文 — 動作を実行する
文は、プログラムに何らかの動作をさせるための命令の単位です。
// これらはすべて文です
let x = 5; // 変数宣言
if (x > 3) { console.log("hi"); } // 条件文
for (let i = 0; i < 5; i++) {} // 繰り返し文
function greet() {} // 関数宣言
return x; // 戻り値文は値を生成しません。そのため、変数に格納することはできません。
const result = if (x > 3) { "yes" }; // ❌ SyntaxError!
const loop = for (let i = 0;;) {}; // ❌ SyntaxError!区別が重要な理由
JavaScriptには、**「式のみを入れられる場所」**があります。代表的な例がJSXの波括弧です。
// React JSX
<p>{isAdmin ? "管理者" : "一般ユーザー"}</p> // ✅ 三項演算子は式
<p>{if (isAdmin) { "管理者" }}</p> // ❌ if文は文JSXの{}の中には、式のみを入れることができます。if文は文であるため、入れることはできません。代わりに三項演算子(? :)を使用します。
// テンプレートリテラルでも同様
const msg = `状態: ${count > 0 ? "あり" : "なし"}`; // ✅
const msg = `状態: ${if (count > 0) "あり"}`; // ❌境界を超えるもの
いくつかのコードは、式でありながら文のように使用できます。
// 関数呼び出し — 式であるが、単独で文のように使用可能
console.log("hello"); // 式文
// 代入 — 式であるが、文のように使用
x = 5; // 代入式(値 = 5)
// 関数宣言 vs 関数式
function add(a, b) { return a + b; } // 関数宣言(文)
const add = function(a, b) { return a + b; }; // 関数式(式)
const add = (a, b) => a + b; // アロー関数(式)functionキーワードで始まる場合は文(宣言)、変数に格納する場合は式(表現)です。
実務でよく使われるパターン
文の代わりに式を使用する必要がある状況はよくあります。
// if/elseの代わりに三項演算子
const status = score >= 60 ? "合格" : "不合格";
// if/elseの代わりに論理演算子
const name = user.name || "匿名";
const display = isVisible && <Component />;
// switchの代わりにオブジェクトマッピング
const messages = {
success: "成功しました",
error: "エラーが発生しました",
loading: "ロード中..."
};
const msg = messages[status] || "不明な状態";即時実行関数式(IIFE)
関数を定義すると同時に実行するパターンです。関数宣言を括弧で囲むと、式になります。
// 関数宣言 — 文
function greet() { return "こんにちは"; }
// 即時実行関数式(IIFE) — 式
const result = (function() {
return "こんにちは";
})();
console.log(result); // "こんにちは"IIFEは、変数スコープを隔離するために使用されます。ES6のブロックスコープ(let、const)が登場したことで、使用頻度は減りましたが、ライブラリコードやモジュールパターンではまだ見かけることがあります。
アロー関数と式
アロー関数は、波括弧なしで書くと、式を自動的に返します。
// 波括弧 + return — 本文が文
const double = (x) => { return x * 2; };
// 波括弧なし — 本文が式(自動 return)
const double2 = (x) => x * 2;
// オブジェクトリテラルを返す場合は括弧が必要
const makeUser = (name) => ({ name, role: "user" });配列メソッドのチェーンで、この違いが実用的に現れます。
const prices = [100, 250, 50, 300];
// 式の本文 → 簡潔
const discounted = prices
.filter(p => p > 100)
.map(p => p * 0.9);一行判別法
| 質問 | 式 | 文 |
|---|---|---|
const x = ___ に入れられるか? | ✅ | ❌ |
| 値を生成するか? | ✅ | ❌ |
| セミコロンなしで他のコードの一部になるか? | ✅ | ❌ |
「このコードは値を生成するか?」—この質問だけで区別できます。値を生成する場合は式、動作だけを行う場合は文。
他の言語との違い
言語によって、式と文の境界が異なります。
# Python: ifは文、三項演算子は式status = "合格" if score >= 60 else "不合格" # 式# if score >= 60: print("合格") # 文
# Python: 代入は文(3.8+ walrus operatorは例外)if (n := len(data)) > 10: # := は式として代入 print(f"{n}個")// Rust: ifは式(値を返す)
let status = if score >= 60 { "合格" } else { "不合格" };JavaScriptは、ifが文で三項演算子が式である一方、Rustではif自体が式です。新しい言語を学ぶ際に、この境界を最初に把握しておくと、文法を迅速に理解できます。
テンプレートリテラルと式
バッククォート(`)を使用するテンプレートリテラルの${}の中にも、式のみを入れることができます。
const name = "鉄男";
const age = 25;
// ✅ 式
const greeting = `こんにちは、${name}! ${age >= 20 ? "成人" : "未成年"}ですね。`;
// ❌ 文は入れることはできません
// `${if (age >= 20) { "成人" }}` — SyntaxError式文 — 両方の性質を持つもの
式でありながら、同時に文であるコードもあります。
// 関数呼び出しは式でありながら、文として単独で使用可能
console.log("hello"); // 文として単独で使用
const x = console.log; // 式として値(関数)を返す
// 代入も式でありながら、文として使用
let a;
a = 5; // 文として単独で使用
const b = (a = 10); // 式として代入された値(10)を返すこの区別はJavaScriptだけでなく、ほとんどのプログラミング言語で同じです。React、テンプレートリテラル、配列メソッドなど、「値が必要な場所」でこの概念が登場します。