字句文法

このページでは、 JavaScript の字句文法について説明します。 ECMAScript スクリプトのソーステキストは、左から右へスキャンされ、入力要素、すなわちトークン、制御文字、行末、コメント、ホワイトスペースの並びに変換されます。 ECMAScript も、特定のキーワードとリテラルを定義しており、文を終了するにはセミコロンを自動挿入するためのルールがあります。

制御文字

制御文字は、視覚的表現を有していないものの、テキストの解釈を制御するために使用されます。

Unicode の書式制御文字
コードポイント 名称 略語 説明
U+200C ゼロ幅非接合子 <ZWNJ> 特定の言語において、合字に接合されることを防ぐために、文字の間に配置されます。(Wikipedia).
U+200D ゼロ幅接合子 <ZWJ> 特定の言語において、通常は接合されない文字を、接合した形を使用して文字を表示するために文字間に配置されます。 (Wikipedia)
U+FEFF バイトオーダーマーク <BOM> スクリプトの先頭において、 Unicode を使用することと、そのテキストのバイト順をマークします。 (Wikipedia).

ホワイトスペース

ホワイトスペースはソースのテキストの読みやすさを向上させ、トークンを互いに区別します。これらの文字は通常、コードの機能性には不要なものです。 Minification tools を使用して、転送する必要があるデータの量を削減するためにホワイトスペースを除去することがよく行われます。

ホワイトスペース文字
コードポイント 名称 略語 説明 エスケープシーケンス
U+0009 文字単位のタブ <HT> 水平タブ \t
U+000B 行単位のタブ <VT> 垂直タブ \v
U+000C フォームフィード <FF> 改ページの制御文字 (Wikipedia). \f
U+0020 空白 <SP> 通常の空白
U+00A0 ノーブレークスペース <NBSP> 通常の空白だが、改行を行ってよい位置ではない
Others 他の Unicode の空白文字 <USP> Spaces in Unicode on Wikipedia

行末文字

ホワイトスペース文字に加えて、行末文字もソースのテキストの読みやすさを改善するために使用されます。しかし、行末文字は JavaScript の実行に影響を与える場合があり、禁止されている場所もいくらかあります。行末文字は自動的なセミコロンの挿入の処理にも影響を与えます。行末文字は正規表現\s クラスに一致します。

以下の Unicode コードポイントのみが ECMAScript では行末文字として扱われ、他の改行文字はホワイトスペースとして扱われます (例えば、次の行、 NEL、 U+0085 はホワイトスペースと見なされます)。

行末文字
コードポイント 名称 略語 説明 エスケープシーケンス
U+000A ラインフィード <LF> UNIX システムでの改行文字です。 \n
U+000D キャリッジリターン <CR> コモドールと初期の Mac システムでの改行文字です。 \r
U+2028 ラインセパレーター <LS> Wikipedia
U+2029 改段落 <PS> Wikipedia

コメント

コメントは、ヒント、メモ、提案、警告を JavaScript のコードに追加するために使用されます。これにより、コードがより読みやすく、より理解しやすいものなります。また、コードが実行されないよう無効にするために使用することができます。これは、貴重なデバッグツールになることがあります。

JavaScript には、コード内にコメントを割り当てる方法が 2 つあります。

一番目の方法は // コメントです。つまり、これは同じ行にある、その後のすべてのテキストをコメントにします。例えば、

function comment() {
  // This is a one line JavaScript comment
  console.log('Hello world!');
}
comment();

二番目の方法は /* */ スタイルで、もっとずっと柔軟なものです。

例えば、単一行に利用した場合は次のようになります。

function comment() {
  /* This is a one line JavaScript comment */
  console.log('Hello world!');
}
comment();

複数行のコメントも下記のように作成することができます。

function comment() {
  /* This comment spans multiple lines. Notice
     that we don't need to end the comment until we're done. */
  console.log('Hello world!');
}
comment();

必要であれば、行の途中でコメントを使用することもできますが、これはコードが読みにくくなることがあるので注意が必要です。

function comment(x) {
  console.log('Hello ' + x /* insert the value of x */ + ' !');
}
comment('world');

また、コードをコメントで囲むことで、コードが実行されないよう無効にすることができます。

function comment() {
  /* console.log('Hello world!'); */
}
comment();

この場合、 console.log() の呼び出しはコメント内部にあるので、実行されることはありません。何行分のコードであっても、このようにして無効にすることができます。

ハッシュバンコメント

特殊な三番目のコメントの構文であるハッシュバンコメントは、 ECMAScript で標準化の途中にあるものです (Hashbang Grammar proposal を参照してください)。

ハッシュバンコメントは、ちょうど単一行コメント (//) のように動作しますが、 #! で始まり、スクリプトやモジュールの絶対的な開始位置にある場合のみ有効です。 #! の前にホワイトスペースも許されないことに注意してください。このコメントは #! の後から最初の行の末尾までのすべての文字で構成されます。このコメントは1つだけが許可されます。

ハッシュバンコメントは、スクリプトを実行したい特定の JavaScript インタープリターへのパスを指定します。例えば次のようになります。

#!/usr/bin/env node

console.log("Hello world");

メモ: JavaScript のハッシュバンコメントは、ファイルを正しいインタープリターで実行するために使用される UNIX のシバンを模倣したものです。

ハッシュバンコメントの前に BOM があってもブラウザーでは動作しますが、ハッシュバンのあるスクリプトで BOM を使用することは推奨されていません。 BOM は Unix/Linux でスクリプトを実行しようとすると動作しません。したがって、シェルから直接スクリプトを実行したい場合は BOM の付かない UTF-8 を使用してください。

#! の形のコメントは JavaScript インタープリターを指定するためにだけ使用してください。他の用途ではすべて // のコメント (または複数行コメント) を使用してください。

キーワード

ECMAScript 2015 における予約キーワード

今後の予約済みキーワード

以下のものは、 ECMAScript の仕様によって今後のキーワードとして予約されています。これらは現時点では特別な機能を持っていませんが、将来は持つ可能性があるので、識別子として使用することはできません。

以下のものは常に予約されています。

  • enum

以下のものは、 strict モードで遭遇した場合のみ予約語になります。

  • implements
  • interface
  • let
  • package
  • private
  • protected
  • public
  • static

以下のものは、モジュールコードで遭遇した場合のみ予約語になります。

  • await

旧仕様にあった今後の予約キーワード

以前の ECMAScript の仕様書 (ECMAScript 1 から 3 まで) では、以下のものが将来のキーワードとして予約されています。

  • abstract
  • boolean
  • byte
  • char
  • double
  • final
  • float
  • goto
  • int
  • long
  • native
  • short
  • synchronized
  • throws
  • transient
  • volatile

加えて、 null, true, false の各リテラルは、 ECMAScript では識別子として使用することができません。

予約語の使用

予約語は実際には (IdentifierName ではなく) 識別子にのみ適用されます。 es5.github.com/#A.1 に記載されているように、これらはすべてIdentifierName であり、ReservedWord を除外しません。

a.import
a['import']
a = { import: 'test' }.

一方、以下のものはIdentifier であり、IdentifierName から予約語を除外したものであるからです。識別子は、FunctionDeclaration,FunctionExpression,VariableDeclaration などのために使用されます。 Identifiers はFunctionDeclaration,FunctionExpression,VariableDeclaration などについて使用されます。IdentifierNamesMemberExpression,CallExpression などについて使用されます。

function import() {} // 違反

リテラル

Null リテラル

詳細については null をご覧ください。

null

真偽値リテラル

詳細について、 Boolean をご覧ください。

true
false

数値リテラル

Number および BigInt 型が数値リテラルを使用します。

10進数

1234567890
42

// 先頭にゼロがあるものを使用する場合は注意してください
0888 // 888 は10進数として解釈されます
0777 // 8進数として解釈され、10進数では 511 です。

なお、10進数リテラルはゼロ (0) から始め、他の10進数の数字を続けることができますが、 0 に続く数字がすべて8より小さい場合は、その数値が8進数として解釈されることに注意してください。 JavaScript では、この場合に例外が発生しませんので、 バグ 957513 をご覧ください。 parseInt() についてのページもご覧ください。

2進数

2進数の構文は、先頭のゼロに続いて小文字または大文字のラテン文字 "B" を使用します (0b または 0B)。この構文は ECMAScript 2015 の新しい構文なので、下記のブラウザー互換性表をご覧ください。 0b の後の数字が 0 または 1 でない場合は、 SyntaxError が "Missing binary digits after 0b" の内容で発生します。

var FLT_SIGNBIT  = 0b10000000000000000000000000000000; // 2147483648
var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607

8進数

8進数の構文は、先頭のゼロに続いて小文字または大文字のラテン文字"O" を使用します (0o または 0O)。この構文は ECMAScript 2015 の新しい構文なので、下記のブラウザー互換性表をご覧ください。 0o の後の数字が範囲 (01234567) 外の場合、 SyntaxError が "Missing octal digits after 0o" の内容で発生します。

var n = 0O755; // 493
var m = 0o644; // 420

// ゼロだけで始めることもできます (上記の10進数についてのメモを参照)
0755
0644

16進数

16進数の構文は、先頭のゼロに続いて小文字または大文字のラテン文字"X" を使用します (0x または 0X)。 0x の後の数字が範囲 (0123456789ABCDEF) 外の場合、 SyntaxError が "Identifier starts immediately after numeric literal" の内容で発生します。

0xFFFFFFFFFFFFFFFFF // 295147905179352830000
0x123456789ABCDEF   // 81985529216486900
0XA                 // 10

BigInt リテラル

BigInt 型は JavaScript のプリミティブな数値であり、自由な精度の整数を表すことができます。 BigInt リテラルは、整数の末尾に n を追加することで作成されます。

123456789123456789n     (10進数)
0o777777777777n         (8進数)
0x123456789ABCDEFn      ("hex" または16進数)
0b11101001010101010101n (2進数)

なお、先頭がゼロだけの8進数は BigInt では動作しません。

// 0755n
// SyntaxError: invalid BigInt syntax

8進数の BigInt 数値では、常にゼロの後に "o" (大文字でも小文字でも) を付けて使用してください。

0o755n

BigInt についての詳細な情報は、 JavaScript データ構造をご覧ください。

数値の区切り文字

数値リテラルの可読性を高めるために、アンダースコア (_, U+005F) を区切り文字として使用することができます。

// 10進数の区切り文字
1_000_000_000_000
1_050.95

// 2進数の区切り文字
0b1010_0001_1000_0101

// 8進数の区切り文字
0o2_2_5_6

// 16進数の区切り文字
0xA0_B0_C0

// BigInt の区切り文字
1_000_000_000_000_000_000_000n

なお、以下の制限があります。

// 連続して2つ以上のアンダースコアは許可されていません
100__000; // SyntaxError

// 数値リテラルの末尾に置くことは許可されていません
100_; // SyntaxError

// 先頭の 0 の後に使用することはできません
0_1; // SyntaxError

オブジェクトリテラル

詳細については、 Objectオブジェクト初期化子をご覧ください。

var o = { a: 'foo', b: 'bar', c: 42 };

// ES2015 で導入された短縮表記
var a = 'foo', b = 'bar', c = 42;
var o = {a, b, c};

// 以前の表記
var o = { a: a, b: b, c: c };

配列リテラル

詳細については Array をご覧ください。

[1954, 1974, 1990, 2014]

文字列リテラル

文字列リテラルは、単一引用符または二重引用符に囲まれた零個以上の Unicode コードポイントです。 Unicode コードポイントはエスケープシーケンスで表すこともできます。以下の引用符を閉じるコードポイントを除いて、すべてのコードポイントが文字列リテラルに現れることができます。

  • U+005C \ (バックスラッシュ)
  • U+000D <CR>,
  • and U+000A <LF>.

proposal to make all JSON text valid ECMA-262 より以前は、 U+2028 <LS> および U+2029 <PS> は文字列リテラル内にエスケープせずに現れることができませんでした。

すべてのコードポイントが、エスケープシーケンスの形で現れることができます。文字列リテラルは ECMAScript の文字列値として評価されます。これらの String の値を生成する際に、 Unicode コードポイントは UTF-16 エンコードされます。

'foo'
"bar"

16進エスケープシーケンス

16進エスケープシーケンスは \x に続いてちょうど2桁の16進数から成り、 0x0000 から 0x00FF までのコード単位またはコードポイントを表します。

'\xA9' // "©"

Unicode エスケープシーケンス

Unicode エスケープシーケンスは \u に続いてちょうど4桁の16進数から成ります。これで UTF-16 エンコーディングのコード単位を表します。コードポイント U+0000 から U+FFFF までは、コード単位とコードポイントは等しくなります。コードポイント U+10000 から U+10FFFF までは、2つのエスケープシーケンスで2つのコード単位 (サロゲートペア) を表す必要があります。サロゲートペアはコードポイントで区別されます。

See also String.fromCharCode() and String.prototype.charCodeAt().

'\u00A9' // "©" (U+A9)

Unicode コードポイントエスケープ

Unicode コードポイントエスケープは \u{ に続いて16進数のコードポイントが続き、 } が続きます。16進数の値は 0 から 0x10FFFF までの範囲に含まれている必要があります。 U+10000 から U+10FFFF までの範囲のコードポイントを、サロゲートペアとして表す必要はありません。コードポイントエスケープは ECMAScript 2015 (ES6) で JavaScript に追加されました。

String.fromCodePoint() または String.prototype.codePointAt() もご覧ください。

'\u{2F804}' // CJK COMPATIBILITY IDEOGRAPH-2F804 (U+2F804)

// the same character represented as a surrogate pair
'\uD87E\uDC04'

正規表現リテラル

詳細については RegExp を参照してください。

/ab+c/g

// 「空の」正規表現リテラル
// 単一行コメントと区別するために、空のキャプチャしない
// グループが必要です。
/(?:)/

テンプレートリテラル

詳細について、template strings をご覧ください。

`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tag `string text ${expression} string text`

自動セミコロン挿入

一部の JavaScript 文はセミコロンで終わる必要があります。したがって、自動セミコロン挿入 (ASI) の影響を受けます。:

  • 空の文
  • let, const, 変数定義
  • import, export, モジュール宣言
  • 式の文
  • debugger
  • continue, break, throw
  • return

ECMAScript 仕様書は、セミコロン挿入の3つの規則に言及しています。

1. 文法上許されない位置で行末文字または "}" に遭遇したとき、セミコロンが前に挿入されます。

{ 1 2 } 3

// 上記の文は、 ASI によって次のように変換されます

{ 1 2 ;} 3;

2. トークンの入力ストリームの終末が検出され、パーサーが単一の入力ストリームを完全なプログラムとして解釈できない場合、末尾にセミコロンが挿入されます。

ここで ++ は、変数 b に適用される 後置演算子としては扱われません。というのも、行末文字が b++ の間に見られるからです。

a = b
++c

// 上記の文は、 ASI によって次のように変換されます

a = b;
++c;

3. 文法上、成果が制限された文の直後に行末文字が来た時、末尾にセミコロンが挿入されます。以下の文が "no LineTerminator here" 規則を持っています。

  • 後置演算子 (++ および --)
  • continue
  • break
  • return
  • yield, yield*
  • module
return
a + b

// 上記の文は、 ASI によって次のように変換されます

return;
a + b;

仕様書

仕様書 状態 備考
ECMAScript (ECMA-262)
Lexical Grammar の定義
現行の標準
ECMAScript 2015 (6th Edition, ECMA-262)
Lexical Grammar の定義
標準 追加: 2進数リテラル と 8進数リテラル、 Unicode コードポイントエスケープ、テンプレート
ECMAScript 5.1 (ECMA-262)
Lexical Conventions の定義
標準
ECMAScript 1st Edition (ECMA-262) 標準 初回定義

ブラウザーの互換性

BCD tables only load in the browser

実装の進捗状況

この機能はまだブラウザー間の安定性が十分でないため、以下の図は、この機能の日々の実装状況を表しています。このデータは標準的な JavaScript のテストスイートである Test262 において、各ブラウザーの JavaScript エンジンの nightly build または最新リリースでこの機能の関連機能を実行することによって生成されています。

関連情報