式文

式文は、文を記述すべき場所で使用する式です。式は評価され、その結果は捨てられます。したがって、関数の実行や変数の更新など、副次的な効果のある式にのみ意味があります。

構文

js
expression;
expression

評価する任意のです。他の文と紛らわしい特定の式は曖昧ですので禁止されています。

解説

文専用の構文とは別に、ほとんどすべてのをそれ自体で文として使用することもできます。式の構文では、終わりにセミコロンが必要ですが、セミコロンがないために構文が不正になる場合は、自動セミコロン挿入で挿入されることがあります。

式は発生した後に破棄されるため、式の結果は利用できません。したがって、式が有益なものとなるためには、式に何か副次的な効果がある必要があります。式文は一般的に次のものです。

他にも副次的な効果がある場合があるものとして、ゲッターの呼び出しや型変換の実行があります。

禁止されている式

式を文として使用するためには、他の文の構文とあいまいであってはいけません。したがって、式は以下のいずれかのトークンで始めてはいけません。

従って、以下のものは全て不正です。

js
function foo() {
  console.log("foo");
}(); // SyntaxError: Unexpected token '('

// 何らか理由で、`let` という変数を作った
var let = [1, 2, 3];
let[0] = 4; // SyntaxError: Invalid destructuring assignment target

{
  foo: 1,
  bar: 2, // SyntaxError: Unexpected token ':'
};

さらに危険なことに、たまたま有効な構文であったとしても、意図しないコードになってしまうこともあります。

js
// 何らか理由で、`let` という変数を作った
var let = [1, 2, 3];

function setIndex(index, value) {
  if (index >= 0) {
    // 配列 `let` に割り当てるつもりが、余計な変数を作成してしまう!
    let[index] = value;
  }
}

setIndex(0, [1, 2]);
console.log(let); // [1, 2, 3]

// これはオブジェクトリテラルではなくブロック文となり、
// `foo` はラベル、`1` は式文になる
// コンソールで起こることが多い
{ foo: 1 };

このような問題を避けるために、括弧を使用することで、一義的に式文となるようにすることができます。

js
(function foo() {
  console.log("foo");
})();

制御フロー文の回避

制御フロー文の使用は、式文を使ってほとんど避けることができます。例えば、if...else三項演算子論理演算子に置き換えることができます。forfor...of のような反復処理文は、配列メソッドに置き換えることができます。

js
// 制御フロー文の使用
function range(start, end) {
  if (start > end) {
    [start, end] = [end, start];
  }
  const result = [];
  for (let i = start; i < end; i++) {
    result.push(i);
  }
  return result;
}

// 式文の使用
function range2(start, end) {
  start > end && ([start, end] = [end, start]);
  return Array.from({ length: end - start }, (_, i) => start + i);
}

警告: これは、言語の能力の一端を示すに過ぎません。制御フロー文の代用として式文を過剰に使用すると、コードの可読性が大幅に低下する可能性があります。

仕様書

Specification
ECMAScript Language Specification
# sec-expression-statement

関連情報