JavaScript

式文

 JavaScriptは、文(Statement)と式(Expression)から構成されています。

 式(Expression)を簡潔に述べると、値を生成し、変数に代入できるものを言います。

 42 のようなリテラルや foo といった変数、関数呼び出しが式です。また、1 + 1 のような式と演算子の組み合わせも式と呼びます。

 式の特徴として、式を評価すると結果の値を得ることができます。この結果の値を評価値と呼びます。

 評価した結果を変数に代入できるものは式であるという理解で問題ありません。


// 1という式の評価値を表示
console.log(1);   // => 1

// 1 + 1という式の評価値を表示
console.log(1 + 1);   // => 2

// 式の評価値を変数に代入
const total = 1 + 1;

// 関数式の評価値(関数オブジェクト)を変数に代入
const fn = function() {
	return 1;
};

// fn() という式の評価値を表示
console.log(fn());   // => 1

 文(Statement)を簡潔に述べると、処理する1ステップが1つの文と言えます。JavaScriptでは、文の末尾にセミコロン( ; )を置くことで文と文に区切りをつけます。

 ソースコードとして書かれた文を上から処理していくことで、プログラムが実行されます。


処理する文;
処理する文;
処理する文;

例えば、if文や for文などが文と呼ばれるものです。次のように、文の処理の一部として式を含むことがあります。


const isTrue = true;

// isTrueという式が if文の中に出てくる
if (isTrue) {
}

 一方、if文などは文であり式にはなれません。

 式ではないため、if文を変数へ代入することはできません。次のようなコードは構文として問題があるため、構文エラー(SyntaxError)となります。


// 構文として間違っているため、SyntaxErrorが発生する
var forIsNotExpression = if (true) { /* ifは分であるため式にはなれない */}

式文

 一方で、式(Expression)は文(Statement)になれます。文となった式のことを式文と呼びます。基本的に文が書ける場所には式を書けます。

 その際に、式文(Expression statement)は文の一種であるため、セミコロンで文を区切っています。


// 式文であるためセミコロンをつけている
式;

 式は文になれますが、先ほどの if文のように文は式になれません。

 JavaScript で最も簡単な文は、副作用を伴う式です(しかし、副作用のない重要な式文もあります)。


greeting = "Hello" + name;
i *= 3;

 インクリメント演算子( ++ )やデクリメント演算子( -- )を使った式も副作用を持ちます。この 2つの演算子は、代入処理と同じように、副作用として変数の値を変更します。例を以下に示します。


counter++;

 delete演算子には、オブジェクトのプロパティを削除する、という重要な副作用があります。したがって、delete演算子は、長い式の一部で使われるというよりは、単独で式文として使われるのが普通です。次に例を示します。


delete o.x;

 関数呼び出しも式文の仲間です。次の例を見てください。


alert(greeting);
window.close();

 上記のクライアントサイド JavaScript の関数呼び出しは、厳密には式ですが、Web ブラウザを制御するという副作用があるので、これも文の仲間に入ります。関数に副作用がない場合は、関数を代入文などの長い式の一部として使わない限り、ただ呼び出すだけでは意味がありません。例えば、余弦の計算だけをして、その結果を破棄することは、実際にはありえないはずです。次の例を見てください。


Math.cos(x);

 実際には、この式が単独で使われるのではなく、以下に示すように、求めた値を変数に代入するはずです。


cx = Math.cos(x);

 もう一度注意しておきますが、ここまでの例でも示したように、文の最後にはセミコロン( ; )を記述するようにしてください。

ブロック文

 次のような、文を { と } で囲んだ部分をブロックと言います。ブロックには、複数の文が書けます。


{
	文;
	文;
}

 ブロック文は単独でも書けますが、基本的には if文や for文など他の構文と組み合わせて書くことがほとんどです。次のコードでは、if文とブロック文を組み合わせることで、if文の処理内容に複数の文を書いています。


// if文とブロック文の組み合わせ
if (true) {
	console.log("文1");
	console.log("文2");
}

 文の末尾にはセミコロンをつけるとしていましたが、例外としてブロックで終わる文の末尾には、セミコロンが不要となっています。


// ブロックで終わらない文なので、セミコロンが必要
if (true) console.log(true);

// ブロックで終わる文なので、セミコロンが不要
if (true) {
	console.log(true);
}

function宣言(文)と function式

 functionキーワードから文を開始する関数宣言と、変数へ関数式を代入する方法があります。

 関数宣言(文)と関数式は、どちらも functionというキーワードを利用しています。


// learn関数を宣言する関数宣言文
function learn() {
}

// 関数式をread変数へ代入
const read = function() {
};

 この文と式の違いを見ると、関数宣言文にはセミコロンがなく、関数式にはセミコロンがあります。このような、違いがなぜ生まれるのかは、ここまでの内容から説明できます。

 関数宣言(文)で定義した learn関数には、セミコロンがありません。これは、ブロックで終わる文にはセミコロンが不要であるためです。

 一方、関数式を read変数へ代入したものには、セミコロンがあります。

 「ブロックで終わる関数であるためセミコロンが不要なのでは?」と思うかもしれません。

 しかし、この匿名関数は式であり、この処理は変数を宣言する文の一部であることがわかります。つまり、次のように置き換えても同じと言えるため、末尾にセミコロンが必要となります。


function fn() {}

// fn(式)の評価値を代入する変数宣言の文
const read = fn;