翻譯不完整。請協助 翻譯此英文文件

此篇介紹 Javascript 的lexical grammar。ECMAScript 的原始碼從左到右被掃描並被轉換成一系列的輸入元素也就是 token、控制字元、行終止字元、註解或是空白字元。ECMAScript 也定義了一些特定的關鍵字和實體語法還有用來自動插入分號來結束陳述式的規則。

控制字元

控制字元是用來控制對文本的解釋,但無法被顯示出來。

Unicode 格式的控制字元
編碼位置 名稱 縮寫 說明
U+200C 零寬不連字 <ZWNJ> 放置在兩個字元之間來避免在某些語言中這兩個字元被當成連字 (Wikipedia)
U+200D 零寬連字 <ZWJ> 放置在兩個通常不會發生連字的字元中間在某些語言
來讓他們成為連字 (Wikipedia)
U+FEFF 位元組順序記號 <BOM> 出現在腳本的開頭,用來標記此腳本是否為Unicode還有文本的位元組順序
 (Wikipedia)

空白字元

空白字元提升了程式碼的可讀性也能將 tokens 分開。這些字元通常對程式的執行是不必要的。壓縮源碼工具通常會移除不必要的空白來減少資料傳輸量。

空白字元
編碼位置 名稱 縮寫 說明 跳脫字元
U+0009 定位字元 <HT> 橫向定位字元 \t
U+000B 縱向定位字元 <VT> 縱向定位字元 \v
U+000C 換頁字元 <FF> 控制換頁字元 (Wikipedia) \f
U+0020 空格 <SP> 一般的空白字元  
U+00A0 不中斷空格 <NBSP> 一般的空白字元,但禁止自動換行或合併多個空白 (Wikipedia)  
其他 其他Unicode空白字元 <USP> Wikipedia  

行終止字元

除了空白字元之外,行終止字元也用來提升源碼可讀性。然而,在某些情況下行終止字元會影響 Javascript 程式的執行,所以有些地方是被禁止使用的。行終止字元同時也會影響自動插入分號的運作。在正規表達式中,行終止字元屬於 \s 的類別。

在 ECMAScript 中,只有以下的Unicode碼位被視為行終止字元,其他如 Next Line, NEL, U+0085 等的行終止字元被視為空白字元。

行終止字元
編碼位置 名稱 縮寫 說明 跳脫字元
U+000A 換行字元 <LF> 在 UNIX 類的系統中的換行字元 \n
U+000D 歸位字元 <CR> 在 Commodore 與早期的 Mac 系統中的換行字元 \r
U+2028 行分隔字元 <LS> Wikipedia  
U+2029 段分隔字元 <PS> Wikipedia  

註解

在 Javascript 程式中,註解通常被用來寫提示、註釋、建議或警告。這可以讓程式更好讀也更好理解,同時也是一個很好的除錯工具,可以讓一些程式碼不被執行。

Javascript 有兩種方式寫註解。

第一種是 //; 它將在它之後的文本變成註解。例如:

function comment() {
  // 這是一行 Javascript 註解
  console.log('Hello world!');
}
comment();

第二種更有彈性的方式是 /* */ 。

例如,你可以將它用在單行上:

function comment() {
  /* 這是一行 Javascript 註解 */
  console.log('Hello world!');
}
comment();

你也可以將它用來寫多行註解:

function comment() {
  /* 這個註解可以跨越多行。注意只有當我們要結束註解時才寫
     多行註解的終止符號 */
  console.log('Hello world!');
}
comment();

如果你想要你也可以把它插在一行的中央,雖然它會讓你的程式變得難讀所以請謹慎使用:

function comment(x) {
  console.log('Hello ' + x /* 插入 x 的值 */ + ' !');
}
comment('world');

此外,你也可以把一段程式用註解包起來讓它不被執行:

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

在這個情況, console.log() 永遠不會被呼叫因為它在註解裡面。任意行數的程式碼都可以用這個方法來使之失去作用。

保留字

ECMAScript 2015 保留關鍵字

未來保留關鍵字

根據 ECMAScript 的規格,以下的關鍵字被保留供未來使用。他們目前沒有功用但未來可能有,所以不能將他們用作識別字。

以下關鍵字將永遠被保留:

  • enum

以下關鍵字只有在嚴格模式底下才被保留:

  • 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 等實體語法 (literal) 在 ECMAScript 中不能被用作識別字。

保留字的使用

只有當用在識別字的時候保留關鍵字才會被保留 (相對於 IdentifierNames) 。如 es5.github.com/#A.1 所述,以下保留關鍵字的用法都屬於IdentifierNames 因此是合法的。

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

反之,以下用法不合法因為用在識別字上,識別字屬於 IdentifierName 但不包含保留字。識別字用在 FunctionDeclaration, FunctionExpression, VariableDeclaration 等等?。而 IdentifierName 被用在 MemberExpression, CallExpression 等等。

function import() {} // 不合法.

實體語法

Null

更多說明請參閱 null

null

布林值

更多說明請參閱 Boolean

true
false

數值

十進制

1234567890
42

// 謹慎使用前導零
0888 // 888 被解析成十進制
0777 // 被解析成八進制, 十進制值為 511

數值的實體語法可以可以以零 (0) 為首再街上其他十進制數字。然而一但零後面的的數字都小於8時,這個數值會被解讀成八進制數字,這個行為不會丟出例外,參閱 bug 957513。也請參閱 parseInt()

二進制

二進制數字的語法為一個起首零加上小寫或大小的拉丁字元"B"  (0b or 0B)。因為這個語法是在 ECMAScript 2015 才新增的,請參閱底下的瀏覽器相容表。如果 0b 之後的數字不是0或1,"0b之後找不到二進制數字"的 SyntaxError 會被丟出。

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

Octal

Octal number syntax uses a leading zero followed by a lowercase or uppercase Latin letter "O" (0o or 0O). Because this syntax is new in ECMAScript 2015, see the browser compatibility table, below. If the digits after the 0o are outside the range (01234567), the following SyntaxError is thrown:  "Missing octal digits after 0o".

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

// Also possible with just a leading zero (see note about decimals above)
0755
0644

Hexadecimal

Hexadecimal number syntax uses a leading zero followed by a lowercase or uppercase Latin letter "X" (0x or 0X). If the digits after 0x are outside the range (0123456789ABCDEF),  the following SyntaxError is thrown: "Identifier starts immediately after numeric literal".

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

Object literals

See also Object and Object initializer for more information.

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

// shorthand notation. New in ES2015
var a = 'foo', b = 'bar', c = 42;
var o = {a, b, c};

// instead of
var o = { a: a, b: b, c: c };

Array literals

See also Array for more information.

[1954, 1974, 1990, 2014]

String literals

'foo'
"bar"

Hexadecimal escape sequences

'\xA9' // "©"

Unicode escape sequences

The Unicode escape sequences consist of exactly four hexadecimal digits following \u. Each one specifies a two-byte character in the UTF-16 encoding. For codepoints between 0 and FFFF, the digits are identical to the codepoint. Higher codepoints require two escape sequences representing the surrogate pair used to encode the character; the surrogate pair is distinct from the codepoint.

'\u00A9' // "©"

Unicode code point escapes

New in ECMAScript 2015. With Unicode code point escapes, any character can be escaped using hexadecimal numbers so that it is possible to use Unicode code points up to 0x10FFFF. With simple Unicode escapes it is often necessary to write the surrogate halves separately to achieve the same.

See also String.fromCodePoint() or String.prototype.codePointAt().

'\u{2F804}'

// the same with simple Unicode escapes
'\uD87E\uDC04'

Regular expression literals

See also RegExp for more information.

/ab+c/g

// An "empty" regular expression literal
// The empty non-capturing group is necessary 
// to avoid ambiguity with single-line comments.
/(?:)/

Template literals

See also template strings for more information.

`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tag `string text ${expression} string text`

Automatic semicolon insertion

Some JavaScript statements must be terminated with semicolons and are therefore affected by automatic semicolon insertion (ASI):

  • Empty statement
  • let, const, variable statement
  • import, export, module declaration
  • Expression statement
  • debugger
  • continue, break, throw
  • return

The ECMAScript specification mentions three rules of semicolon insertion.

1.  A semicolon is inserted before, when a Line terminator or "}" is encountered that is not allowed by the grammar.

{ 1 2 } 3 

// is transformed by ASI into 

{ 1 2 ;} 3;

2.  A semicolon is inserted at the end, when the end of the input stream of tokens is detected and the parser is unable to parse the single input stream as a complete program.

Here ++ is not treated as a postfix operator applying to variable b, because a line terminator occurs between b and ++.

a = b
++c

// is transformend by ASI into

a = b;
++c;

3. A semicolon is inserted at the end, when a statement with restricted productions in the grammar is followed by a line terminator. These statements with "no LineTerminator here" rules are:

  • PostfixExpressions (++ and --)
  • continue
  • break
  • return
  • yield, yield*
  • module
return
a + b

// is transformed by ASI into

return;
a + b;

Specifications

Specification Status Comment
ECMAScript 1st Edition (ECMA-262) Standard Initial definition.
ECMAScript 5.1 (ECMA-262)
The definition of 'Lexical Conventions' in that specification.
Standard  
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Lexical Grammar' in that specification.
Standard Added: Binary and Octal Numeric literals, Unicode code point escapes, Templates
ECMAScript Latest Draft (ECMA-262)
The definition of 'Lexical Grammar' in that specification.
Draft  

Browser compatibility

FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Array literals ([1, 2, 3]) Yes Yes Yes Yes Yes Yes
Binary numeric literals (0b)411225 ?289
Boolean literals (true/false) Yes Yes Yes Yes Yes Yes
Decimal numeric literals (1234567890) Yes Yes Yes Yes Yes Yes
Hexadecimal escape sequences ('\0xA9') Yes Yes Yes Yes Yes Yes
Hexadecimal numeric literals (0xAF) Yes Yes Yes Yes Yes Yes
Null literal (null) Yes Yes Yes Yes Yes Yes
Octal numeric literals (0o)411225 ?289
Regular expression literals (/ab+c/g) Yes Yes Yes Yes Yes Yes
String literals ('Hello world') Yes Yes Yes Yes Yes Yes
Unicode escape sequences ('\u00A9') Yes Yes Yes Yes Yes Yes
Unicode point escapes (\u{})441240 No319
Shorthand notation for object literals431233 No309
Template literals411234 No289
Trailing commas Yes Yes Yes Yes Yes Yes
FeatureAndroid webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
Array literals ([1, 2, 3]) Yes Yes Yes Yes Yes Yes ?
Binary numeric literals (0b)4141122528 Yes ?
Boolean literals (true/false) Yes Yes Yes Yes Yes Yes ?
Decimal numeric literals (1234567890) Yes Yes Yes Yes Yes Yes ?
Hexadecimal escape sequences ('\0xA9') Yes Yes Yes Yes Yes Yes ?
Hexadecimal numeric literals (0xAF) Yes Yes Yes Yes Yes Yes ?
Null literal (null) Yes Yes Yes Yes Yes Yes ?
Octal numeric literals (0o)4141122528 Yes ?
Regular expression literals (/ab+c/g) Yes Yes Yes Yes Yes Yes ?
String literals ('Hello world') Yes Yes Yes Yes Yes Yes ?
Unicode escape sequences ('\u00A9') Yes Yes Yes Yes Yes Yes ?
Unicode point escapes (\u{})4444124031 ? ?
Shorthand notation for object literals4343123330 ? ?
Template literals4141123428 ? ?
Trailing commas Yes Yes Yes Yes Yes Yes ?

See also

文件標籤與貢獻者

 此頁面的貢獻者: leowu
 最近更新: leowu,