?um/p1-90`
ECMAScript
在若干情形下,词法输入元素的识别会依赖于消费这些输入元素的语法文法上下文。
这就要求词法文法具有多个
使用多个词法目标可确保不存在会影响自动分号插入的词法歧义。例如,不存在同
时允许前导除法或除法赋值,以及前导
a = b
/hi/g.exec(c).map(d);
其中,在
a = b / hi / g.exec(c).map(d);
Unicode 格式控制字符(即 Unicode 字符数据库中“Cf”类别的字符,例如 LEFT-TO-RIGHT MARK 或 RIGHT-TO-LEFT MARK)是控制码,用于在缺少更高层协 议(如标记语言)时控制一段文本的格式。
允许源文本中出现格式控制字符有助于编辑和显示。所有格式控制字符都可用于注 释内部,以及字符串字面量、模板字面量和正则表达式字面量内部。
U+FEFF(ZERO WIDTH NO-BREAK SPACE)是一种格式控制字符,主要用于文本开
头,将其标记为 Unicode,并允许检测文本的编码和字节序。用于此目的的
<ZWNBSP> 字符有时也可能出现在文本开始之后,例如作为文件拼接的结果。
在
空白码点用于提升源文本可读性,并将记号(不可再分的词法单元)彼此分隔开
来,但除此之外并无意义。空白码点可以出现在任意两个记号之间,也可以出现在输
入的开头或结尾。空白码点可以出现在
ECMAScript 的空白码点列于
| 码点 | 名称 | 缩写 |
|---|---|---|
U+0009
|
CHARACTER TABULATION | <TAB> |
U+000B
|
LINE TABULATION | <VT> |
U+000C
|
FORM FEED (FF) | <FF> |
U+FEFF
|
ZERO WIDTH NO-BREAK SPACE | <ZWNBSP> |
| “Space_Separator” 一般类别中的任意码点 | <USP> |
U+0020(SPACE)和 U+00A0(NO-BREAK SPACE)码点属于 <USP> 的一部 分。
除
与空白码点一样,行终止符码点也用于提升源文本可读性,并将记号(不可再分的
词法单元)彼此分隔开来。但是,与空白码点不同,行终止符会对语法文法的行为产
生某些影响。通常,行终止符可以出现在任意两个记号之间,但也有少数地方被语法
文法禁止出现。行终止符还会影响自动分号插入过程(
行终止符可以出现在
行终止符被包含在正则表达式中 \s 类所匹配的空白码点集合内。
ECMAScript 的行终止符码点列于
| 码点 | Unicode 名称 | 缩写 |
|---|---|---|
U+000A
|
LINE FEED (LF) | <LF> |
U+000D
|
CARRIAGE RETURN (CR) | <CR> |
U+2028
|
LINE SEPARATOR | <LS> |
U+2029
|
PARAGRAPH SEPARATOR | <PS> |
只有
注释可以是单行注释,也可以是多行注释。多行注释不能嵌套。
由于单行注释可以包含除 // 标记开始
到该行末尾的所有码点构成。然而,行末的
注释的行为类似空白,并会被丢弃;不过,如果一个
本节中的若干产生式在
Hashbang 注释对位置敏感,并且像其他类型的注释一样,会从语法文法的输入元素 流中被丢弃。
本标准规定了特定的码点补充:U+0024(DOLLAR SIGN)和 U+005F
(LOW LINE)允许出现在
非终结符
非终结符 _。
具有 Unicode 属性 “ID_Start” 和 “ID_Continue” 的码点集合,分别包 含具有 Unicode 属性 “Other_ID_Start” 和 “Other_ID_Continue” 的码点。
在 \ 不贡献任
何码点。\
根据 Unicode 标准,两个规范等价的
The syntax-directed operation IdentifierCodePoints takes no arguments and returns 一个码点列表. It is defined piecewise over the following productions:
The syntax-directed operation IdentifierCodePoint takes no arguments and returns 一个码点. It is defined piecewise over the following productions:
关键字是一个匹配 fixed width
字体)出现在某个语法产生式中。ECMAScript 的关键字包括 if、while、
async、await 以及许多其他关键字。
保留字是一个不能用作标识符的
if 和 while 是保留字。await 只在 async 函数和模块内部
保留。async 不是保留字;它可以不受限制地用作变量名或语句标签。
本规范结合语法产生式和await 和 yield 之
外,都是无条件保留的。对于 await 和 yield 的例外,在
始终允许作为标识符,且不是关键字的,例如 Math、window、
toString 和 _;
永远不允许作为标识符的,即下方列出的 await
和 yield;
在上下文中允许作为标识符的,即 await 和 yield;
在let、static、
implements、interface、package、private、protected 和
public;
始终允许作为标识符,但也会在某些不允许 as、async、from、get、meta、of、set
和 target。
术语条件关键字,或 上下文关键字,有时用来指最后三 类关键字,因此它们可以在某些上下文中用作标识符,而在另一些上下文中用作关键 字。
根据 \
\ els\u{65} 来声明变量。位于
enum 目前在本规范中并未用作关键字。它是一个未来保留字,
为将来语言扩展中作为关键字使用而预留。
同样地,implements、interface、package、private、
protected 和 public 在
紧跟在
例如:3in 是错误,而不是两个输入元素 3 和 in。
数值字面量表示一个
The syntax-directed operation NumericValue takes no arguments and returns 一个 Number 或一个 BigInt. It is defined piecewise over the following productions:
字符串字面量是由单引号或双引号包围的 0 个或多个 Unicode 码点。Unicode
码点也可以由转义序列表示。除闭合引号码点、U+005C(REVERSE SOLIDUS)、
U+000D(CARRIAGE RETURN)和 U+000A(LINE FEED)之外,所有码点都可以在
字符串字面量中直接出现。任意码点都可以以转义序列形式出现。字符串字面量求
值为 ECMAScript String 值。在生成这些 String 值时,Unicode 码点会按照
非终结符
<LF> 和 <CR> 不能出现在字符串字面量中,除非它们作为
\n 或 \u000A 这样的
转义序列。
字符串字面量有可能出现在 Use Strict Directive 之前,而该指令会使外
层代码进入
function invalid() { "\7"; "use strict"; }
The syntax-directed operation SV takes no arguments and returns 一个 String.
字符串字面量表示一个
| 转义序列 | 码元值 | Unicode 字符名称 | 符号 |
|---|---|---|---|
\b
|
0x0008
|
BACKSPACE | <BS> |
\t
|
0x0009
|
CHARACTER TABULATION | <HT> |
\n
|
0x000A
|
LINE FEED (LF) | <LF> |
\v
|
0x000B
|
LINE TABULATION | <VT> |
\f
|
0x000C
|
FORM FEED (FF) | <FF> |
\r
|
0x000D
|
CARRIAGE RETURN (CR) | <CR> |
\"
|
0x0022
|
QUOTATION MARK |
"
|
\'
|
0x0027
|
APOSTROPHE |
'
|
\\
|
0x005C
|
REVERSE SOLIDUS |
\
|
下面的产生式描述了正则表达式字面量的语法,并被输入元素扫描器用来查找正则
表达式字面量的结束位置。构成
实现可以扩展
正则表达式字面量不能为空;表示为空正则表达式字面量的码元序列 // 会启
动一个单行注释。要指定一个空正则表达式,请使用:/(?:)/。
The syntax-directed operation BodyText takes no arguments and returns 源文本. It is defined piecewise over the following productions:
The syntax-directed operation FlagText takes no arguments and returns 源文本. It is defined piecewise over the following productions:
The syntax-directed operation TV takes no arguments and returns 一个 String 或
The syntax-directed operation TRV takes no arguments and returns 一个 String. 模板字面量组成部分会被 TRV 解释为一个
大多数 ECMAScript 语句和声明都必须以分号终止。这类分号总是可以显式写在 源文本中。不过,为了方便,在某些情况下,这类分号可以从源文本中省略。这些情 况通过以下方式描述:在这些情况下,分号会被自动插入源代码记号流中。
在以下规则中,“token” 指的是使用当前词法
分号插入有三条基本规则:
当从左到右解析源文本时,遇到一个任何文法产生式都不允许的记号(称为 违规记号)时,如果满足下列一个或多个条件,则会在该违规记号之前 自动插入一个分号:
}。
),并且插入的分号会被解析为 do-while 语句
(
不过,对上述规则还有一个额外的优先条件:如果该分号插入后会被解析为空语
句,或者该分号会成为 for 语句头部中的两个分号之一(见
文法中唯一的受限产生式如下:
这些受限产生式的实际效果如下:
++ 或 -- 记号,并且解析器会将其视为后缀运算符,而前一
个记号与该 ++ 或 -- 记号之间至少出现了一个 ++ 或 -- 记号之前自动插入一个分号。
continue、break、return、throw 或 yield 记
号,并且在下一个记号之前遇到了一个 continue、break、return、throw 或 yield 记号之后自动插
入一个分号。
=> 记号之前跟着一个 async 记号之后在 function 或 ( 记号
之前跟着一个 async
记号不会被视为与后续记号属于同一个表达式或类元素的一部分。
async 记号之后在 * 记号之前跟着一个 对 ECMAScript 程序员的实际建议如下:
++ 或 -- 运算符应与其操作数位于同一行。
return 或 throw 语句中的 yield 表达式中的
return、throw 或 yield 记号位于
同一行起始。
break 或 continue 语句中的 break 或
continue 记号位于同一行。
=> 应位于同一行。
async 记号应与其后紧跟的记号位于同一行。
以下源代码
{ 1 2 } 3
不是一个有效的 ECMAScript 文法句子,即使应用自动分号插入规则也是如此。 相比之下,以下源代码
{ 1
2 } 3
同样不是一个有效的 ECMAScript 句子,但它会被自动分号插入转换为以下形 式:
{ 1
;2 ;} 3;
这就是一个有效的 ECMAScript 句子。
以下源代码
for (a; b
)
不是一个有效的 ECMAScript 句子,并且不会被自动分号插入修改,因为该分号
是 for 语句头部所必需的。自动分号插入绝不会插入 for 语句头部中的两个分
号之一。
以下源代码
return
a + b
会被自动分号插入转换为以下形式:
return;
a + b;
表达式 a + b 不会被当作 return 语句要返回的值,因为一个
return 分隔开了。
以下源代码
a = b
++c
会被自动分号插入转换为以下形式:
a = b;
++c;
记号 ++ 不会被当作施加于变量 b 的后缀运算符,因为 b 和 ++
之间出现了一个
以下源代码
if (a > b)
else c = d
不是一个有效的 ECMAScript 句子,并且不会在 else 记号之前通过自动分号
插入进行修改,即使此处没有任何文法产生式适用,因为自动插入的分号将会被解析
为空语句。
以下源代码
a = b + c
(d + e).print()
不会被自动分号插入转换,因为第二行开始的带括号表达式可以被解释 为函数调用的参数列表:
a = b + c(d + e).print()
在赋值语句必须以左圆括号开头的情况下,程序员最好在前一条语句的末尾显式写 出分号,而不要依赖自动分号插入。
ECMAScript 程序可以通过依赖自动分号插入而采用一种几乎不写分号的风格。 正如上文所述,分号并不会在每一个换行处插入,自动分号插入还可能依赖跨越行终 止符的多个记号。
随着新的语法特性被加入 ECMAScript,可能还会增加新的文法产生式,从而导致 那些依赖于其前方自动分号插入的代码行在解析时落入不同的文法产生式。
就本节而言,如果一个自动分号插入案例中,分号是否会被插入取决于其前面的源 文本,那么该案例就被认为是有趣的。本节剩余部分描述了本版 ECMAScript 中若干 自动分号插入的有趣情形。
在
()。如果没有分号,这两行会
一起被当作一个 [)。如果没有分号,这两行
会一起被当作属性访问,而不是 `)。如果没有分号,这两
行会一起被解释为一个带标签的 Template
(+ 或 -。如果没有分
号,这两行会一起被解释为相应二元运算符的一次使用。/
ECMAScript 包含若干文法产生式,其中带有 “[no
本节剩余部分描述了本版 ECMAScript 中若干使用 “[no