Multipage preference

11 ECMAScript 语言:源文本

11.1 源文本

语法

SourceCharacter :: any Unicode code point

ECMAScript source text 是一系列 Unicode 码点。从 U+0000 到 U+10FFFF 的所有 Unicode 码点值,包括代理码点,都可以在 ECMAScript 语法允许的位置出现在 ECMAScript 源文本中。用于存储和交换 ECMAScript 源文本的实际编码与本规范无关。无论外部源文本编码如何,符合规范的 ECMAScript 实现都会像处理等价的 SourceCharacter 值序列一样处理源文本,其中每个 SourceCharacter 都是一个 Unicode 码点。符合规范的 ECMAScript 实现不要求对源文本执行任何规范化,也不要求表现得仿佛正在执行源文本规范化。

组合字符序列的组成部分会被当作单独的 Unicode 码点处理,即使用户可能认为整个序列是单个字符。

Note

在字符串字面量、正则表达式字面量、模板字面量和标识符中,任何 Unicode 码点也可以使用显式表示码点数值的 Unicode 转义序列表达。在注释内,这种转义序列实际上会作为注释的一部分被忽略。

ECMAScript 在 Unicode 转义序列的行为上不同于 Java 编程语言。例如,在 Java 程序中,如果 Unicode 转义序列 \u000A 出现在单行注释内,它会被解释为行终止符(Unicode 码点 U+000A 是 LINE FEED (LF)),因此下一个码点不是注释的一部分。类似地,如果 Unicode 转义序列 \u000A 出现在 Java 程序的字符串字面量内,它同样会被解释为行终止符,而这是字符串字面量中不允许的——必须写成 \n 而不是 \u000A,才能使 LINE FEED (LF) 成为字符串字面量值的一部分。在 ECMAScript 程序中,出现在注释内的 Unicode 转义序列永远不会被解释,因此不能促成注释的终止。类似地,出现在 ECMAScript 程序的字符串字面量内的 Unicode 转义序列始终会构成该字面量的一部分,且永远不会被解释为行终止符或可能终止该字符串字面量的码点。

11.1.1 Static Semantics: UTF16EncodeCodePoint ( codePoint )

The abstract operation UTF16EncodeCodePoint takes argument codePoint (a Unicode code point) and returns a String. It performs the following steps when called:

  1. 断言:0 ≤ codePoint ≤ 0x10FFFF。
  2. 如果 codePoint ≤ 0xFFFF,则返回由数值为 codePoint 的代码单元组成的 String 值。
  3. 令 cu1 为数值为 floor((codePoint - 0x10000) / 0x400) + 0xD800 的代码单元。
  4. 令 cu2 为数值为 ((codePoint - 0x10000) modulo 0x400) + 0xDC00 的代码单元。
  5. 返回 cu1 和 cu2 的字符串连接。

11.1.2 Static Semantics: CodePointsToString ( text )

The abstract operation CodePointsToString takes argument text (a sequence of Unicode code points) and returns a String. 它将 text 转换为 String 值,如 6.1.4 中所述。 It performs the following steps when called:

  1. 令 result 为空 String。
  2. 对 text 的每个码点 codePoint,执行:
    1. 将 result 设置为 result 和 UTF16EncodeCodePoint(codePoint) 的字符串连接。
  3. 返回 result。

11.1.3 Static Semantics: UTF16SurrogatePairToCodePoint ( lead, trail )

The abstract operation UTF16SurrogatePairToCodePoint takes arguments lead (a code unit) and trail (a code unit) and returns a code point. 将形成 UTF-16 代理对的两个代码单元转换为一个码点。 It performs the following steps when called:

  1. 断言:lead 是前导代理,且 trail 是后尾代理。
  2. 令 codePoint 为 (lead - 0xD800) × 0x400 + (trail - 0xDC00) + 0x10000。
  3. 返回码点 codePoint。

11.1.4 Static Semantics: CodePointAt ( string, position )

The abstract operation CodePointAt takes arguments string (a String) and position (a non-negative integer) and returns a Record with fields [[CodePoint]] (a code point), [[CodeUnitCount]] (a positive integer), and [[IsUnpairedSurrogate]] (a Boolean). 它将 string 解释为 UTF-16 编码码点序列,如 6.1.4 中所述,并从索引 position 处的代码单元开始读取一个码点。 It performs the following steps when called:

  1. 令 size 为 string 的长度。
  2. 断言:position ≥ 0 且 position < size。
  3. 令 first 为 string 内索引 position 处的代码单元。
  4. 令 codePoint 为其数值是 first 的数值的码点。
  5. 如果 first 既不是前导代理也不是后尾代理,则
    1. 返回 Record { [[CodePoint]]: codePoint, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: false }。
  6. 如果 first 是后尾代理,或 position + 1 = size,则
    1. 返回 Record { [[CodePoint]]: codePoint, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }。
  7. 令 second 为 string 内索引 position + 1 处的代码单元。
  8. 如果 second 不是后尾代理,则
    1. 返回 Record { [[CodePoint]]: codePoint, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }。
  9. 将 codePoint 设置为 UTF16SurrogatePairToCodePoint(first, second)。
  10. 返回 Record { [[CodePoint]]: codePoint, [[CodeUnitCount]]: 2, [[IsUnpairedSurrogate]]: false }。

11.1.5 Static Semantics: StringToCodePoints ( string )

The abstract operation StringToCodePoints takes argument string (a String) and returns a List of code points. 它返回将 string 按 6.1.4 中所述解释为 UTF-16 编码 Unicode 文本所得的 Unicode 码点序列。 It performs the following steps when called:

  1. 令 codePoints 为新的空 List。
  2. 令 size 为 string 的长度。
  3. 令 position 为 0。
  4. 重复,当 position < size 时,
    1. 令 codePoint 为 CodePointAt(string, position)。
    2. 将 codePoint.[[CodePoint]] 追加到 codePoints。
    3. 将 position 设置为 position + codePoint.[[CodeUnitCount]]。
  5. 返回 codePoints。

11.1.6 Static Semantics: ParseText ( sourceText, goalSymbol )

The abstract operation ParseText takes arguments sourceText (a String or a sequence of Unicode code points) and goalSymbol (a nonterminal in one of the ECMAScript grammars) and returns a Parse Node or a non-empty List of SyntaxError objects. It performs the following steps when called:

  1. 如果 sourceText 是 String,则将 sourceText 设置为 StringToCodePoints(sourceText)。
  2. 尝试使用 goalSymbol 作为目标符号解析 sourceText,并分析解析结果以查找任何早期错误条件。解析和早期错误检测可以以实现定义的方式交错进行。
  3. 如果解析成功且未发现早期错误,则返回由解析产生的解析树根部的 Parse Node(goalSymbol 的实例)。
  4. 返回一个包含一个或多个 SyntaxError 对象的 List,这些对象表示解析错误和/或早期错误。如果存在多个解析错误或早期错误,则列表中错误对象的数量和顺序是实现定义的,但至少必须存在一个。
Note 1

考虑一段文本,它在某个特定位置有早期错误,并且在稍后位置也有语法错误。先执行解析遍历再执行早期错误遍历的实现,可能会报告语法错误而不继续进行早期错误遍历。将这两项活动交错进行的实现,可能会报告早期错误而不继续查找语法错误。第三种实现可能会报告两个错误。所有这些行为都符合规范。

Note 2

另请参见条款 17。

11.2 源代码的类型

ECMAScript 代码有四种类型:

Note 1

Function code 通常作为函数定义(15.2)、箭头函数定义(15.3)、方法定义(15.4)、生成器函数定义(15.5)、异步函数定义(15.8)、异步生成器函数定义(15.6)以及异步箭头函数(15.9)的函数体提供。Function code 也从 Function 构造函数(20.2.1.1)、GeneratorFunction 构造函数(27.6.1.1)、AsyncFunction 构造函数(27.10.1.1)以及 AsyncGeneratorFunction 构造函数(27.7.1.1)的实参派生而来。

Note 2

将 BindingIdentifier 包含在 function code 中的实际效果是:严格模式代码的 Early Errors 会应用于一个 BindingIdentifier,该 BindingIdentifier 是函数体包含 Use Strict Directive 的函数的名称,即使周围代码不是严格模式代码。

11.2.1 指令序言和 Use Strict 指令

Directive Prologue 是出现在 FunctionBody、ScriptBody 或 ModuleBody 的初始 StatementListItem 或 ModuleItem 位置上的最长 ExpressionStatement 序列,并且该序列中的每个 ExpressionStatement 都完全由一个 StringLiteral token 后跟分号组成。分号可以显式出现,也可以由自动分号插入(12.10)插入。Directive Prologue 可以是空序列。

Use Strict Directive 是 Directive Prologue 中的一个 ExpressionStatement,其 StringLiteral 恰好是码点序列 "use strict" 或 'use strict'。Use Strict Directive 不得包含 EscapeSequence 或 LineContinuation。

Directive Prologue 可以包含多个 Use Strict Directive。不过,如果发生这种情况,实现可以发出警告。

Note

Directive Prologue 的 ExpressionStatement 会在对包含它的产生式求值期间正常求值。实现可以为不是 Use Strict Directive 且出现在 Directive Prologue 中的 ExpressionStatement 定义实现特定含义。如果存在适当的通知机制,则当实现遇到 Directive Prologue 中不是 Use Strict Directive 且没有由实现定义含义的 ExpressionStatement 时,应当发出警告。

11.2.2 严格模式代码

ECMAScript 句法单元可以使用不受限模式或严格模式语法和语义(4.3.2)处理。在以下情形中,代码会被解释为 strict mode code:

不是 strict mode code 的 ECMAScript 代码称为 non-strict code。

11.2.2.1 Static Semantics: IsStrict ( parseNode )

The abstract operation IsStrict takes argument parseNode (a Parse Node) and returns a Boolean. It performs the following steps when called:

  1. 如果 parseNode 匹配的源文本是 strict mode code,则返回 true。
  2. 返回 false。

11.2.3 非 ECMAScript 函数

ECMAScript 实现可以支持对函数异质对象的求值,这些对象的求值行为以某种宿主定义的、非 ECMAScript 源文本的可执行代码形式表示。一个函数对象是在 ECMAScript 代码中定义的,还是内置函数,从调用或被这种函数对象调用的 ECMAScript 代码角度来看是不可观察的。