11 ECMAScript 语言:源码文本 (ECMAScript Language: Source Text)

11.1 源码文本 (Source Text)

语法 (Syntax)

SourceCharacter :: 任意 Unicode 码点 (any Unicode code point)

ECMAScript 源码文本 (ECMAScript source text) 是一串 Unicode 码点。所有从 U+0000 到 U+10FFFF 的 Unicode 码点值(包括代理项码点 surrogate code points)在 ECMAScript 语法允许的地方都可以出现在 ECMAScript 源码文本中。用于存储与交换 ECMAScript 源码文本的实际编码方式与本规范无关。无论外部源码的字符编码为何,符合规范的 ECMAScript 实现都按其等价的 SourceCharacter 序列来处理源码文本,每个 SourceCharacter 即一个 Unicode 码点。符合规范的实现不需要对源码文本进行任何规范化,也不需要表现得仿佛进行了规范化。

组合字符序列 (combining character sequence) 的各组成部分被分别当作单独的 Unicode 码点对待,即便用户可能把整个序列视为一个字符。

Note

在字符串字面量、正则表达式字面量、模板字面量与标识符中,任意 Unicode 码点也可以通过显式表示其数值的 Unicode 转义序列来书写。在注释中,这样的转义序列被视为注释的一部分而等效忽略。

在 Unicode 转义序列的行为上,ECMAScript 与 Java 编程语言不同。在 Java 程序中,如果 Unicode 转义序列 \u000A(例如)出现在单行注释内,它会被解释为行终止符(U+000A 是 LINE FEED (LF)),因此下一个码点不再属于该注释。同样地,如果 \u000A 出现在 Java 的字符串字面量中,它也被视为行终止符;行终止符不允许出现在字符串字面量内部——必须写作 \n 而不是 \u000A 才能使 LF 成为字符串值的一部分。在 ECMAScript 程序中,注释里的 Unicode 转义序列从不被解释,因此不会导致注释终止。类似地,ECMAScript 程序中字符串字面量里的 Unicode 转义序列始终贡献其字面意义,绝不会被解释成行终止符或可能终止字符串字面量的码点。

11.1.1 静态语义:UTF16EncodeCodePoint ( cp )

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

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

11.1.2 静态语义:CodePointsToString ( text )

The abstract operation 静态语义:CodePointsToString takes argument text (a sequence of Unicode code points) and returns a String. 将 text6.1.4 所述转换为一个 String 值。 It performs the following steps when called:

  1. result 为空字符串。
  2. text 的每个码点 cp,执行
    1. result 设为 result 与 UTF16EncodeCodePoint(cp) 的字符串连接。
  3. 返回 result

11.1.3 静态语义: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前导代理项 (leading surrogate) 且 trail 是尾随代理项 (trailing surrogate)。
  2. cp 为 (lead - 0xD800) × 0x400 + (trail - 0xDC00) + 0x10000。
  3. 返回码点 cp

11.1.4 静态语义: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). 按 6.1.4 所述将 string 解释为 UTF-16 编码的码点序列,并从索引 position 的代码单元开始读取单个码点。 It performs the following steps when called:

  1. sizestring 的长度。
  2. 断言:position ≥ 0 且 position < size
  3. firststring 中索引 position 的代码单元。
  4. cp 为数值等于 first 数值的码点。
  5. first 既不是前导代理项也不是尾随代理项,则
    1. 返回 Record { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: false }。
  6. first 是尾随代理项或 position + 1 = size,则
    1. 返回 Record { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }。
  7. secondstring 中索引 position + 1 的代码单元。
  8. second 不是尾随代理项,则
    1. 返回 Record { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }。
  9. cp 设为 UTF16SurrogatePairToCodePoint(first, second)。
  10. 返回 Record { [[CodePoint]]: cp, [[CodeUnitCount]]: 2, [[IsUnpairedSurrogate]]: false }。

11.1.5 静态语义:StringToCodePoints ( string )

The abstract operation 静态语义:StringToCodePoints takes argument string (a String) and returns a List of code points. 返回将 string6.1.4 作为 UTF-16 编码 Unicode 文本解释后得到的 Unicode 码点序列。 It performs the following steps when called:

  1. codePoints 为一个新的空 List
  2. sizestring 的长度。
  3. position 为 0。
  4. position < size 循环:
    1. cp 为 CodePointAt(string, position)。
    2. cp.[[CodePoint]] 追加到 codePoints
    3. position 设为 position + cp.[[CodeUnitCount]]
  5. 返回 codePoints

11.1.6 静态语义: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,并分析解析结果中的任何提前错误 (early error) 条件。解析与提前错误检测可按实现自定义方式交错进行。
  3. 若解析成功且未发现提前错误,返回解析生成的 parse tree 根部的 Parse Node(goalSymbol 的一个实例)。
  4. 否则,返回一个包含一个或多个 SyntaxError 对象的 List,表示语法错误和/或提前错误。若存在多个错误,其数量与顺序由实现定义,但至少要有一个。
Note 1

考虑某段文本在某处有一个提前错误,在其后又有语法错误。一个先解析后检测提前错误的实现可能只报告语法错误而未继续提前错误阶段。一个交错实现可能报告提前错误而不再寻找语法错误。第三种实现可能两者都报告。以上行为都符合规范。

Note 2

另见 17 条款。

11.2 源码类型 (Types of Source Code)

ECMAScript 代码有四种类型:

Note 1

函数代码通常以函数定义 (15.2)、箭头函数定义 (15.3)、方法定义 (15.4)、生成器函数定义 (15.5)、异步函数定义 (15.8)、异步生成器函数定义 (15.6) 以及异步箭头函数 (15.9) 的函数体形式提供。函数代码还来自 Function 构造器 (20.2.1.1)、GeneratorFunction 构造器 (27.3.1.1)、AsyncFunction 构造器 (27.7.1.1) 与 AsyncGeneratorFunction 构造器 (27.4.1.1) 的参数。

Note 2

BindingIdentifier 包含在函数代码中的实际作用是:即便外围代码不是严格模式,只要函数体内含有 "use strict" 指令,该函数名的 BindingIdentifier 也会应用严格模式早期错误规则

11.2.1 指令序言与 Use Strict 指令 (Directive Prologues and the Use Strict Directive)

指令序言 (Directive Prologue) 是出现在 FunctionBodyScriptBodyModuleBody 起始位置处、作为初始 StatementListItemModuleItem 的最长 ExpressionStatement 序列,并且序列中每个 ExpressionStatement 完全由一个 StringLiteral 标记及其后紧随的分号组成。该分号可以显式出现,也可由自动分号插入 (12.10) 插入。指令序言可以是空序列。

Use Strict 指令 (Use Strict Directive) 是指令序言中的一个 ExpressionStatement,其 StringLiteral 精确为代码点序列 "use strict"'use strict'。Use Strict 指令不允许包含 EscapeSequenceLineContinuation

指令序言可包含多个 Use Strict 指令;实现可以在发生这种情况时发出警告。

Note

指令序言中的 ExpressionStatement 在包含它的产生式求值时会被正常求值。实现可以为指令序言中出现、且不是 Use Strict 指令的 ExpressionStatement 定义实现特定的含义。如果存在合适的通知机制,实现若在指令序言中遇到既不是 Use Strict 指令又没有实现定义语义的 ExpressionStatement,应发出警告。

11.2.2 严格模式代码 (Strict Mode Code)

一个 ECMAScript 语法单元可以用不受限模式或严格模式语法与语义处理 (4.3.2)。以下情况中代码被解释为 严格模式代码 (strict mode code)

不是严格模式代码的 ECMAScript 代码称为 非严格代码 (non-strict code)

11.2.2.1 静态语义:IsStrict ( node )

The abstract operation 静态语义:IsStrict takes argument node (a Parse Node) and returns a Boolean. It performs the following steps when called:

  1. node 匹配的源码文本是严格模式代码,返回 true;否则返回 false

11.2.3 非 ECMAScript 函数 (Non-ECMAScript Functions)

ECMAScript 实现可以支持求值其执行行为以宿主自定义的非 ECMAScript 可执行代码形式表达的函数特异对象。一个函数对象是否在 ECMAScript 代码中定义或是否是内置函数,对调用或被其调用的 ECMAScript 代码而言不可观察。