此頁面由社群從英文翻譯而來。了解更多並加入 MDN Web Docs 社群。
Lexical grammar
此篇介紹 Javascript 的 lexical grammar。ECMAScript 的原始碼從左到右被掃描並被轉換成一系列的輸入元素也就是 token、控制字元、行終止字元、註解或是空白字元。ECMAScript 也定義了一些特定的關鍵字和實體語法還有用來自動插入分號來結束陳述式的規則。
In this article
控制字元
控制字元是用來控制對文本的解釋,但無法被顯示出來。
空白字元
空白字元提升了程式碼的可讀性也能將 tokens 分開。這些字元通常對程式的執行是不必要的。壓縮源碼工具通常會移除不必要的空白來減少資料傳輸量。
行終止字元
除了空白字元之外,行終止字元也用來提升源碼可讀性。然而,在某些情況下行終止字元會影響 Javascript 程式的執行,所以有些地方是被禁止使用的。行終止字元同時也會影響自動插入分號的運作。在正規表達式中,行終止字元屬於\s 的類別。
在 ECMAScript 中,只有以下的 Unicode 碼位被視為行終止字元,其他如 Next Line, NEL, U+0085 等的行終止字元被視為空白字元。
註解
在 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
以下關鍵字只有在嚴格模式底下才被保留:
implementsinterfaceletpackageprivateprotectedpublicstatic
以下關鍵字只有在出現在模組程式碼中時才被保留:
await
舊標準中的未來保留關鍵字
以下關鍵字在舊的 ECMAScript 規格中 (ECMAScript 1 到 3) 為未來保留關鍵:
abstractbooleanbytechardoublefinalfloatgotointlongnativeshortsynchronizedthrowstransientvolatile
此外,如null,true 與false 等實體語法 (literal) 在 ECMAScript 中不能被用作識別字。
保留字的使用
只有當用在識別字的時候保留關鍵字才會被保留 (相對於IdentifierNames) 。如es5.github.com/#A.1 所述,以下保留關鍵字的用法都屬於IdentifierNames 因此是合法的。
a.importa['import']a = { import: 'test' }.反之,以下用法不合法因為用在識別字上,識別字屬於IdentifierName 但不包含保留字。識別字用在FunctionDeclaration, FunctionExpression, VariableDeclaration 等等?。而IdentifierName 被用在MemberExpression, CallExpression 等等。
function import() {} // 不合法.實體語法
>Null
更多說明請參閱null 。
null布林值
更多說明請參閱Boolean 。
truefalse數值
十進制
123456789042// 謹慎使用前導零0888 // 888 被解析成十進制0777 // 被解析成八進制, 十進制值為 511數值的實體語法可以可以以零 (0) 為首再街上其他十進制數字。然而一但零後面的的數字都小於 8 時,這個數值會被解讀成八進制數字,這個行為不會丟出例外,請參閱Firefox bug 957513。也請參閱parseInt()。
二進制
二進制數字的語法為一個起首零加上小寫或大小的拉丁字元「B」(0b 或0B)。因為這個語法是在 ECMAScript 2015 才新增的,請參閱底下的瀏覽器相容表。如果0b 之後的數字不是 0 或 1,「0b 之後找不到二進制數字」的SyntaxError 會被丟出。
0b10000000000000000000000000000000 // 21474836480b01111111100000000000000000000000 // 21390950400B00000000011111111111111111111111 // 8388607八進制
八進制數字的語法為一個起首零加上小寫或大小的拉丁字元「O」(0o 或0O)。因為這個語法是在 ECMAScript 2015 才新增的,請參閱底下的瀏覽器相容表。如果0o 之後的數字不是(01234567)其中之一,「0o 之後找不到八進制數字」的 SyntaxError 會被丟出。
0O755 // 4930o644 // 420十六進制
十六進制數字的語法為一個起首零加上小寫或大小的拉丁字元"X" (0x 或0X)。如果0x 之後的數字不是 (0123456789ABCDEF) 其中之一,"識別字緊接在數值實體語法後"的 SyntaxError 會被丟出。
0xFFFFFFFFFFFFFFFFF // 2951479051793528300000x123456789ABCDEF // 819855292164869000XA // 10物件
更多說明請參閱Object 及Object initializer。
var o = { a: "foo", b: "bar", c: 42 };// 簡短表示法 (ES2015 新增)var a = "foo", b = "bar", c = 42;var o = { a, b, c };// ES2015 以前必須這樣寫var o = { a: a, b: b, c: c };陣列
更多說明請參閱Array 。
[1954, 1974, 1990, 2014]字串
'foo'"bar"十六進制跳脫序列
"\xA9" // "©"Unicode 跳脫序列
一個 Unicode 跳脫序列由\u 接上 4 個十六進制的數值所組成。每一個十六進制的數值表示一個 UTF-16 編碼的 2 位元組字元。對於編碼位置在 0~FFFF 之間的字元,其 Unicode 表示法與編碼位置相同。而更高的編碼位置需要兩個跳脫序列來表示,又稱為代理對(surrogate pair),代理對表示的數值與編碼位置不同 (代理對計算規則 wiki)。
"\u00A9" // "©"Unicode 跳脫編碼位置
ECMAScript 2015 新增。使用 Unicode 跳脫編碼位置表示法,即可使用與編碼位置完全相同的表示法 (最高到0x10FFFF) 而不受編碼位置高於 FFFF 需用代理對表示的限制。
更多說明請參閱String.fromCodePoint() 或String.prototype.codePointAt()。
"\u{2F804}"// 等價於代理對表示法"\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 statements 必須以分號作結,因此會受到自動插入分號 (ASI) 規則影響。
- 空運算式
let,const, 變數宣告import,export, 模組宣告- 運算式
debuggercontinue,break,throwreturn
ECMAScript 規格闡明自動插入分號的三個規則。
1. 如果行終止字元 或 "}" 出現在不符文法的地方,一個分號會被自動插入在其之前。
{ 1 2 } 3// 會被 ASI 轉換成{ 1 2 ;} 3;2. 當一個 token 輸入流到了結尾而解析器仍然無法將其解析為一個完整的程式,一個分號會被自動插入於其後。
在這裡++ 並不會被當作作用於變數b的後綴運算元,因為行終止字元出現在b 和++之間。
a = b++c// 會被 ASI 轉換成a = b;++c;3. 當一個運算式中出現 restricted productions 後面接著一個行終止元,一個分號會被自動插入於行終止元之前。以下這些陳述式有"不允許出現行終止元"規則:
- 後綴運算式 (
++and--) continuebreakreturnyield,yield*module
returna + b// 會被 ASI 轉換成return;a + b;規格
| Specification |
|---|
| ECMAScript® 2026 Language Specification> |