Draft ECMA-262 / September 16, 2025

ECMAScript® 2026 语言规范

关于本规范

位于 https://tc39.es/ecma262/ 的文档是最准确且最新的 ECMAScript 规范。它包含了最近年度快照的内容,以及自该快照以来所有已完成的 提案(即已在 提案流程中达到第 4 阶段,并且已在多个实现中落地、将在下一次实际修订中包含的提案)。

本文件可作为单页多页形式获取。

如何参与规范制定

本规范在 GitHub 上由 ECMAScript 社区协作开发。您可以通过以下几种方式参与本规范的制定:

更多关于本文件创建方式的信息请参阅 colophon

简介

本 Ecma 标准定义了 ECMAScript 2026 语言,这是 ECMAScript 语言规范的第十七版。自1997年第一版发布以来,ECMAScript已发展为全球使用最广泛的通用编程语言之一。它最著名的应用是在网页浏览器中嵌入的语言,但也在服务器和嵌入式应用中被广泛采用。

ECMAScript 基于多种起源技术,其中最知名的是 JavaScript(Netscape)和 JScript(Microsoft)。该语言由 Brendan Eich 在 Netscape 发明,并首次出现在该公司 Navigator 2.0 浏览器中。随后,Netscape 的所有浏览器以及 Microsoft 从 Internet Explorer 3.0 起的所有浏览器均支持该语言。

ECMAScript 语言规范的开发始于 1996 年 11 月。该 Ecma 标准的第一版由 Ecma 大会在 1997 年 6 月通过。

该 Ecma 标准按快速通道程序提交至 ISO/IEC JTC 1,并于 1998 年 4 月获批为国际标准 ISO/IEC 16262。Ecma 大会于 1998 年 6 月批准了 ECMA-262 的第二版,以确保其与 ISO/IEC 16262 完全一致。第一版与第二版之间的更改仅为编辑性质。

标准的第三版引入了强大的正则表达式、更好的字符串处理、新的控制语句、try/catch 异常处理、更严格的错误定义、数字输出格式,以及为未来语言发展做出的细微调整。第三版由 Ecma 大会于 1999 年 12 月通过,并作为 ISO/IEC 16262:2002 于 2002 年 6 月发布。

第三版发布后,ECMAScript 在万维网环境下得到广泛采用,成为几乎所有浏览器支持的编程语言。曾有大量工作投入到 ECMAScript 第四版的开发中,但该工作最终未完成并未以第四版发布,部分内容被融入到第六版的开发中。

ECMAScript 第五版(作为 ECMA-262 第 5 版发布)规范化了已成为浏览器实现间通用的语言解释方式,并加入了自第三版发布以来出现的新特性。这些特性包括访问器属性、对象的反射创建与检查、属性特性程序控制、更多数组操作函数、对 JSON 对象编码格式的支持,以及增强错误检查和程序安全性的严格模式。第五版由 Ecma 大会于 2009 年 12 月通过。

第五版按快速通道程序提交至 ISO/IEC JTC 1,并获批为国际标准 ISO/IEC 16262:2011。ECMAScript 标准第 5.1 版包含了细微修正,与 ISO/IEC 16262:2011 的文本一致。5.1 版由 Ecma 大会于 2011 年 6 月通过。

第六版的集中开发始于 2009 年,在第五版准备发布期间。但在此之前,自 1999 年第三版发布起,已进行了大量实验和语言增强设计。实际上,第六版的完成是十五年努力的结晶。本版目标包括更好地支持大型应用、库创建,以及将 ECMAScript 作为其他语言编译目标。主要增强包括模块、类声明、词法块作用域、迭代器和生成器、异步编程的 Promise、解构模式和尾调用优化。内置库扩展以支持更多数据抽象,如 Map、Set 和二进制数值数组,并进一步支持字符串和正则表达式中的 Unicode 补充字符。内置对象也可以通过子类化进行扩展。第六版为语言和库的常规、增量性增强奠定了基础。第六版由 2015 年 6 月的大会通过。

ECMAScript 2016 是 Ecma TC39 新的年度发布节奏和开放开发流程下发布的首个 ECMAScript 版本。基础文档由 ECMAScript 2015 的源文档转换成纯文本格式,并在 GitHub 上持续开发。在本标准开发期间,提交了数百个拉取请求和问题,修复了数千个错误、编辑问题和其他改进。此外,开发了许多软件工具以支持此过程,包括 Ecmarkup、Ecmarkdown 和 Grammarkdown。ES2016 还新增了指数运算符和 Array.prototypeincludes 方法。

ECMAScript 2017 引入了异步函数、共享内存和原子操作,以及多项语言和库的增强、错误修复和编辑更新。异步函数通过提供 Promise 返回函数的语法改善了异步编程体验。共享内存和原子操作引入了新的内存模型,使多代理程序可以使用原子操作进行通信,即使在并行 CPU 上也能确保有序执行。还新增了 Object 的静态方法:Object.valuesObject.entriesObject.getOwnPropertyDescriptors

ECMAScript 2018 引入了通过异步迭代器协议和异步生成器实现的异步迭代支持。还新增了四种正则表达式特性:dotAll 标志、命名捕获组、Unicode 属性转义和后行断言。最后还包括对象剩余和展开属性。

ECMAScript 2019 新增了几种内置函数:用于数组扁平化的 Array.prototype 上的 flatflatMap,用于直接将 Object.entries 的返回值转为新对象的 Object.fromEntries,以及作为更合理命名替代的 String.prototype 上的 trimStarttrimEnd(替代广泛实现但未标准化的 String.prototype.trimLefttrimRight)。此外还包括对语法和语义的细微更新。语法更新包括可选的 catch 绑定参数以及在字符串字面量中允许 U+2028(行分隔符)和 U+2029(段分隔符),以与 JSON 保持一致。其他更新包括要求 Array.prototype.sort 必须为稳定排序,要求 JSON.stringify 无论输入如何都返回格式正确的 UTF-8,以及明确要求 Function.prototype.toString 返回相应的原始源代码或标准占位符。

ECMAScript 2020,第 11 版,引入了字符串的 matchAll 方法,可通过全局正则表达式生成所有匹配对象的迭代器;import(),一种可动态指定异步导入模块的语法;BigInt,用于任意精度整数的新数值原语;Promise.allSettled,一种不会短路的 Promise 组合器;globalThis,一种通用访问全局 this 的方式;模块内专用的 export * as ns from 'module' 语法;for-in 枚举顺序的标准化提升;模块内由宿主环境填充的 import.meta 对象,可包含关于模块的上下文信息;以及为“空值”(undefinednull) 增强体验的新语法特性:空值合并运算符和可选链运算符,分别用于值选择和属性访问/函数调用时遇到空值自动短路。

ECMAScript 2021,第 12 版,引入了字符串的 replaceAll 方法;Promise.any,一种在输入值满足条件时短路的 Promise 组合器;AggregateError,用于同时表示多个错误的新错误类型;逻辑赋值运算符(??=, &&=, ||=);WeakRef,用于引用目标对象但不阻止其被垃圾回收,以及 FinalizationRegistry,用于注册和注销在目标对象被垃圾回收时执行的清理操作;数字字面量分隔符(如 1_000);并且 Array.prototype.sort 更加精确,减少了实现定义排序结果的情况。

ECMAScript 2022,第 13 版,引入了顶层 await,允许在模块顶层使用该关键字;新增类元素:公有和私有实例字段、静态字段、私有实例方法和访问器、私有静态方法和访问器;类中的静态块,用于每个类的初始化;#x in obj 语法,用于检测对象上的私有字段是否存在;正则表达式匹配索引(通过 /d 标志),可提供匹配子字符串的起止索引;错误对象的 cause 属性,可用于记录错误因果链;字符串、数组和 TypedArrayat 方法,实现相对索引;以及 Object.hasOwn,作为更方便的 Object.prototype.hasOwnProperty 替代方案。

ECMAScript 2023,第 14 版,在 Array.prototypeTypedArray.prototype 上新增了 toSortedtoReversedwithfindLastfindLastIndex 方法,并在 Array.prototype 上新增了 toSpliced 方法;支持文件开头的 #! 注释,以更好地支持可执行 ECMAScript 文件;允许在弱集合中使用大多数 Symbol 作为键。

ECMAScript 2024,第 15 版,增加了 ArrayBuffer 和 SharedArrayBuffer 的动态调整大小和转移功能;新增了用于处理字符串集合的高级特性的新正则表达式 /v 标志;引入了便捷构造 Promise 的 Promise.withResolvers 方法,数据聚合的 Object.groupByMap.groupBy 方法,异步等待共享内存变更的 Atomics.waitAsync 方法,以及用于检测和保证字符串仅包含格式正确 Unicode 的 String.prototype.isWellFormedString.prototype.toWellFormed 方法。

ECMAScript 2025,第 16 版,新增了带有相关静态方法和原型方法的全局 Iterator,用于迭代器操作;为 Set.prototype 增加了常用集合操作方法;支持导入 JSON 模块,以及声明导入模块属性的语法;新增了用于安全处理字符串的 RegExp.escape 方法;支持在正则表达式中内联启用和禁用修饰符标志的语法;新增了用于处理可能返回 Promise 或非 Promise 的函数并确保返回值始终是 Promise 的 Promise.try 方法;并新增了新的 Float16Array 类型数组及相关的 DataView.prototype.getFloat16DataView.prototype.setFloat16Math.f16round 方法。

有数十位代表众多机构的个人在 Ecma TC39 中为本版及以往版本的开发做出了重要贡献。此外,支持 TC39 ECMAScript 工作的社区也日益活跃。该社区审查了大量草案,提交了成千上万个错误报告,进行了实现实验,贡献了测试套件,并向全球开发者介绍 ECMAScript。遗憾的是,无法逐一列举和感谢每一位做出贡献的个人和机构。

Allen Wirfs-Brock
ECMA-262,第 6 版项目编辑

Brian Terlson
ECMA-262,第 7–10 版项目编辑

Jordan Harband
ECMA-262,第 10–12 版项目编辑

Shu-yu Guo
ECMA-262,第 12–16 版项目编辑

Michael Ficarra
ECMA-262,第 12–16 版项目编辑

Kevin Gibbons
ECMA-262,第 12–16 版项目编辑

1 范围

本标准定义了 ECMAScript 2026 通用编程语言。

2 一致性

符合规范的 ECMAScript 实现必须提供并支持本规范中描述的所有类型、值、对象、属性、函数,以及程序的语法和语义。

符合规范的 ECMAScript 实现必须按照最新版 Unicode 标准和 ISO/IEC 10646 的要求解释源文本输入。

符合规范的 ECMAScript 实现如果提供支持不同语言和国家的语言习惯和文化规范的应用程序编程接口(API),则必须实现与本规范兼容的最新版 ECMA-402 所定义的接口。

符合规范的 ECMAScript 实现可以提供本规范未描述的其他类型、值、对象、属性和函数。特别地,符合规范的 ECMAScript 实现可以为本规范所描述的对象提供未在本规范中描述的属性,以及这些属性的值。

符合规范的 ECMAScript 实现可以支持本规范未描述的程序和正则表达式语法。特别地,符合规范的 ECMAScript 实现可以支持使用本规范 12.7.2 分条中所述任何“未来保留字”的程序语法。

符合规范的 ECMAScript 实现不得实现本规范 17.1 分条中列为禁止扩展的任何扩展。

符合规范的 ECMAScript 实现不得重新定义任何非实现自定义、非近似实现或非宿主自定义的机制。

符合规范的 ECMAScript 实现可以选择实现或不实现 规范性可选 子条款,除非另有说明。通常情况下,网页浏览器要求实现所有规范性可选子条款。(参见附录 B。)如果实现了任何规范性可选行为,则必须实现包含该行为的所有规范性可选条款。规范性可选条款在本规范中以彩色框显示“规范性可选”字样,如下所示。

Normative Optional

2.1 规范性可选条款标题示例

条款内容示例。

符合规范的 ECMAScript 实现必须实现 遗留 子条款,除非它们也被标记为规范性可选。遗留子条款中指定的所有语言特性和行为都具有一个或多个不理想的特性,但由于现有应用仍在使用,无法从规范中移除这些特性。这些特性不属于 ECMAScript 语言核心。编程人员在编写新的 ECMAScript 代码时不应使用或假定这些特性和行为的存在。

Legacy

2.2 遗留条款标题示例

条款内容示例。

Normative Optional, Legacy

2.3 遗留规范性可选条款标题示例

条款内容示例。

3 规范性引用文件

下列引用文件对于本文件的应用是不可或缺的。对于有日期的引用,仅适用于所引用的版本;对于无日期的引用,适用于引用文件的最新版本(包括任何修订)。

IEEE 754-2019,《浮点数运算标准》。

Unicode 标准。
https://unicode.org/versions/latest

ISO/IEC 10646,《信息技术——通用多字节编码字符集(UCS)》,包括修订1:2005、修订2:2006、修订3:2008、修订4:2008,以及更多修订和勘误,或后续版本。

ECMA-402,《ECMAScript 国际化 API 规范》,特别是与本规范版本相对应的年度版本。
https://www.ecma-international.org/publications-and-standards/standards/ecma-402/

ECMA-404,《JSON 数据交换格式》。
https://www.ecma-international.org/publications-and-standards/standards/ecma-404/

4 概述

本节包含 ECMAScript 语言的非规范性概述。

ECMAScript 是一种面向对象的编程语言,用于在宿主环境中进行计算和操作计算对象。本规范中的 ECMAScript 并不旨在具备完全自给自足的计算能力;实际上,本规范未为外部数据输入或计算结果输出提供规定。而是预期 ECMAScript 程序的计算环境不仅提供本规范描述的对象和其他机制,还提供某些特定于环境的对象,其描述和行为超出本规范范围,仅说明它们可以提供可访问的属性和可从 ECMAScript 程序调用的函数。

ECMAScript 最初设计为脚本语言,但现已广泛用作通用编程语言。脚本语言是用于操作、定制和自动化现有系统功能的编程语言。在此类系统中,实用功能通常通过用户界面提供,脚本语言则是让程序能够控制这些功能的机制。这样,现有系统就提供了对象和机制组成的宿主环境,补足了脚本语言的能力。脚本语言面向专业和非专业程序员。

ECMAScript 最初设计为Web 脚本语言,用于在浏览器中为 Web 页面赋予动态行为,并在基于 Web 的客户端-服务器架构中执行服务器端计算。如今,ECMAScript 被用于为多种宿主环境提供核心脚本能力。因此,核心语言在本文件中独立于任何特定宿主环境进行描述。

ECMAScript 的使用已超越简单脚本,现在在许多环境和规模下用于各类编程任务。随着 ECMAScript 应用范围的扩大,其所提供的特性和机制也不断丰富。ECMAScript 现已成为功能完备的通用编程语言。

4.1 Web 脚本

网页浏览器为客户端计算提供 ECMAScript 宿主环境,例如用于表示窗口、菜单、弹窗、对话框、文本区域、锚点、框架、历史、Cookie 和输入/输出的对象。此外,宿主环境提供了将脚本代码绑定到事件的方法,如焦点变化、页面和图片加载、卸载、错误和中断、选择、表单提交和鼠标操作。脚本代码出现在 HTML 内,显示的页面是用户界面元素与固定及计算文本和图片的结合。脚本代码响应用户交互,无需主程序。

Web 服务器则为服务端计算提供不同的宿主环境,包括用于表示请求、客户端和文件的对象,以及锁定与共享数据的机制。通过结合浏览器端和服务器端脚本,可以在客户端和服务器间分布计算,同时为 Web 应用提供定制化用户界面。

支持 ECMAScript 的每个 Web 浏览器和服务器都提供自己的宿主环境,完善了 ECMAScript 的执行环境。

4.2 宿主和实现

为便于将 ECMAScript 集成到宿主环境中,本规范将某些机制(如抽象操作)全部或部分定义留给规范外部的来源。本规范在编辑上区分如下几种委托方式。

实现指的是进一步定义附件 D 列举的机制,或被标记为实现自定义实现近似的机制的外部来源。在非正式用法中,实现通常指某个具体产物,如某个网页浏览器。

实现自定义指将某个机制的定义无附加限定地委托给外部来源。本规范未对具体行为做任何建议,符合规范的实现可在规范约束范围内自由选择行为。

实现近似指将某个机制的定义委托给外部来源,同时建议理想行为。符合规范的实现可在规范约束范围内自由选择行为,但鼓励尽量接近理想。例如部分数学操作,如 Math.exp,采用实现近似方式。

宿主指进一步定义附件 D 所列机制,但不进一步定义其他实现自定义或近似机制的外部来源。在非正式用法中,宿主指以相同方式通过附件 D 与本规范接口的所有实现集合,如所有网页浏览器。宿主通常是外部规范,如 WHATWG HTML(https://html.spec.whatwg.org/)。换句话说,宿主自定义机制常在外部规范中进一步定义。

宿主钩子是由外部来源全部或部分定义的抽象操作。所有宿主钩子须列于附件 D宿主钩子须至少满足以下要求:

宿主自定义指无附加限定地将机制定义委托给外部来源,并列于附件 D。非宿主的实现也可为宿主自定义机制提供定义。

宿主环境指对所有宿主自定义机制的具体定义选择。宿主环境通常包括一些对象或函数,通过全局对象的宿主自定义属性实现输入输出。

本规范在编辑上始终采用最具体术语。例如,如果某机制为宿主自定义,不应称其为实现自定义

宿主和实现都可通过本规范定义的语言类型、规范类型、抽象操作、语法产生式、内在对象和内在符号与本规范接口。

4.3 ECMAScript 概览

以下是 ECMAScript 的非正式概览,未描述语言的所有部分。本概览不是标准正文的一部分。

ECMAScript 是基于对象的:基本语言机制和宿主机制由对象提供,ECMAScript 程序是一组相互通信的对象。在 ECMAScript 中,对象是包含零个或多个属性的集合,每个属性具有特性,这些特性决定属性的使用方式——例如,当属性的 Writable 特性为 false 时,任何 ECMAScript 代码尝试为该属性赋新值都将失败。属性是用来保存其他对象、原始值函数的容器。原始值属于以下内建类型之一:UndefinedNullBooleanNumberBigIntStringSymbol;对象属于内建类型 Object;函数是可调用的对象。通过属性与对象关联的函数称为方法

ECMAScript 定义了一组内建对象,补充了 ECMAScript 实体的定义。这些内建对象包括全局对象;与语言运行时语义密切相关的对象,如 ObjectFunctionBooleanSymbol 及各类 Error 对象;用于表示和操作数值的对象,如 MathNumberDate;用于文本处理的对象 StringRegExp;用于值索引集合的对象,如 Array 以及具有特定数值表示的九种 Typed Array;用于键值集合的 MapSet;用于结构化数据的对象,如 JSONArrayBufferSharedArrayBufferDataView;用于控制抽象的对象,如生成器函数和 Promise;以及用于反射的对象,如 ProxyReflect

ECMAScript 还定义了一组内建运算符。ECMAScript 运算符包括各类一元运算、乘法运算、加法运算、位移运算、关系运算、相等运算、二元位运算、二元逻辑运算、赋值运算和逗号运算。

大型 ECMAScript 程序通过模块得到支持,允许将程序划分为多个语句和声明序列。每个模块明确标识需要由其他模块提供的声明,以及哪些声明可供其他模块使用。

ECMAScript 的语法有意与 Java 语法相似。ECMAScript 的语法较为宽松,便于其作为易用的脚本语言。例如,变量无需声明类型,属性也无类型约束,定义的函数无需在调用前出现在文本中。

4.3.1 对象

尽管 ECMAScript 包含类定义语法,但 ECMAScript 对象本质上不是 C++、Smalltalk 或 Java 那样的类基础对象。对象可以通过多种方式创建,包括字面量方式或通过构造函数创建对象并执行初始化代码为属性赋初值。每个构造函数都是一个函数,拥有名为 "prototype" 的属性,用于实现基于原型的继承共享属性。对象可通过 new 表达式使用构造函数创建,例如 new Date(2009, 11) 创建一个新的 Date 对象。直接调用构造函数而不使用 new 的行为取决于构造函数,例如 Date() 返回当前日期和时间的字符串而不是对象。

每个由构造函数创建的对象都隐式引用(称为对象的原型)其构造函数"prototype" 属性。此外,原型还可以非 null 地隐式引用其原型,依此类推;这被称为原型链。访问对象属性时,查找的是原型链中第一个包含该属性的对象。即,首先检查直接引用的对象是否有该属性,若有则访问该属性,若无则检查该对象的原型,依此类推。

Figure 1: 对象/原型关系
一个包含许多方框和箭头的图示。

在基于类的面向对象语言中,状态通常由实例承载,方法由类承载,继承仅限结构和行为。而在 ECMAScript 中,状态和方法都由对象承载,结构、行为和状态都可继承。

所有未直接拥有其原型属性的对象共享该属性及其值。图1对此进行了说明:

CF 是一个构造函数(也是一个对象)。通过 new 表达式创建了五个对象:cf1cf2cf3cf4cf5。每个对象都包含名为 "q1""q2" 的属性。虚线表示隐式原型关系;例如,cf3 的原型是 CFp构造函数 CF 自身有两个属性,分别为 "P1""P2",这些属性对 CFpcf1cf2cf3cf4cf5 不可见。CFp"CFP1" 属性被 cf1cf2cf3cf4cf5 共享(但不包括 CF),以及 CFp 的隐式原型链上除 "q1""q2""CFP1" 外的所有属性。注意 CFCFp 之间没有隐式原型链接。

与多数基于类的对象语言不同,可以通过为对象赋值动态添加属性。即,构造函数无需为所有或任何构造对象的属性命名或赋值。在上述图示中,可以通过为 CFp 属性赋新值,为 cf1cf2cf3cf4cf5 新增共享属性。

虽然 ECMAScript 对象本质上不是类基础,但基于通用的构造函数、原型对象和方法模式定义类式抽象通常很方便。ECMAScript 的内建对象本身也遵循此类模式。从 ECMAScript 2015 起,ECMAScript 语言包含类定义语法,允许程序员简洁地定义符合内建对象所用类式抽象模式的对象。

4.3.2 ECMAScript 的严格模式变体

ECMAScript 语言考虑到部分用户可能希望限制语言中的某些特性使用。这样做可能出于安全考虑、避免易出错特性、获得更强的错误检查或其他原因。为此,ECMAScript 定义了语言的严格模式变体。严格模式变体排除了常规 ECMAScript 语言中的部分特定语法和语义特性,并对部分特性进行了详细语义修改。严格模式还规定了在非严格模式下不视为错误的情况下必须抛出错误异常的额外错误条件。

ECMAScript 的严格模式变体通常被称为语言的严格模式。严格模式的选择及语法和语义的使用在单个 ECMAScript 源文本单元级进行,如 11.2.2 所述。由于严格模式在语法源文本单元级选择,严格模式仅在该单元内产生局部影响。严格模式不会限制或修改必须跨多个源文本单元一致运行的 ECMAScript 语义。完整的 ECMAScript 程序可以包含严格模式和非严格模式的源文本单元。此时,严格模式仅在实际执行定义于严格模式源文本单元的代码时生效。

为符合本规范,ECMAScript 实现必须实现本规范定义的完整的非受限 ECMAScript 语言和严格模式变体,并支持将非受限和严格模式源文本单元组合为单一复合程序。

4.4 术语和定义

本文件的目的所涉及的术语和定义如下。

4.4.1 实现近似

实现近似机制由外部来源全部或部分定义,但本规范推荐理想行为

4.4.2 实现自定义

实现自定义机制由外部来源全部或部分定义

4.4.3 宿主自定义

实现自定义

Note

编辑说明,见 4.2 条款。

4.4.4 类型

6 条款所定义的数据值集合

4.4.5 原始值

属于 Undefined、Null、Boolean、Number、BigInt、Symbol 或 String 类型之一,如 6 条款所定义

Note

原始值是由语言实现直接在最低层级表示的数据项。

4.4.6 对象

属于 Object 类型的成员

Note

对象是属性集合,并且有唯一的原型对象。原型可以为 null

4.4.7 构造函数

用于创建和初始化对象的函数对象

Note

构造函数"prototype" 属性值是实现继承和共享属性所用的原型对象。

4.4.8 原型

为其他对象提供共享属性的对象

Note

构造函数创建对象时,该对象隐式引用构造函数"prototype" 属性以解析属性引用。构造函数"prototype" 属性可通过程序表达式 constructor.prototype 访问,向原型添加属性,通过继承,所有共享该原型的对象都可访问这些属性。或者,可以通过 Object.create 内建函数创建具有指定原型的新对象。

4.4.9 普通对象

具有所有对象必须支持的基本内部方法默认行为的对象

4.4.10 特殊对象

在一个或多个基本内部方法上不具有默认行为的对象

Note

任何非普通对象都是特殊对象

4.4.11 标准对象

其语义由本规范定义的对象

4.4.12 内建对象

由 ECMAScript 实现指定并提供的对象

Note

标准内建对象由本规范定义。ECMAScript 实现可以指定和提供其他类型的内建对象。

4.4.13 undefined 值

在变量未赋值时使用的原始值

4.4.14 Undefined 类型

其唯一值为 undefined 的类型

4.4.15 null 值

表示有意无对象值的原始值

4.4.16 Null 类型

其唯一值为 null 的类型

4.4.17 Boolean 值

属于 Boolean 类型的成员

Note

只有两个 Boolean 值,truefalse

4.4.18 Boolean 类型

由原始值 truefalse 组成的类型

4.4.19 Boolean 对象

属于 Object 类型且为标准内建 Boolean 构造函数实例的成员

Note

Boolean 对象通过在 new 表达式中使用 Boolean 构造函数并传递 Boolean 值参数创建。生成的对象有一个内部插槽,值为 Boolean 值。Boolean 对象可被强制转换为 Boolean 值。

4.4.20 String 值

有限有序的零个或多个 16 位无符号整数值序列的原始值

Note

String 值属于 String 类型。序列中的每个整数值通常表示一个 UTF-16 文本的 16 位单元。但 ECMAScript 不对这些值做任何限制或要求,仅要求其为 16 位无符号整数。

4.4.21 String 类型

所有可能的 String 值的集合

4.4.22 String 对象

属于 Object 类型且为标准内建 String 构造函数实例的成员

Note

String 对象通过在 new 表达式中使用 String 构造函数并传递 String 值参数创建。生成的对象有一个内部插槽,值为 String 值。String 对象可通过将 String 构造函数作为函数调用(22.1.1.1)被强制转换为 String 值。

4.4.23 Number 值

与双精度 64 位二进制格式 IEEE 754-2019 值对应的原始值

Note

Number 值属于 Number 类型,是数字的直接表示。

4.4.24 Number 类型

所有可能的 Number 值集合,包括 NaN(非数字)、+∞𝔽(正无穷)、-∞𝔽(负无穷)

4.4.25 Number 对象

属于 Object 类型且为标准内建 Number 构造函数实例的成员

Note

Number 对象通过在 new 表达式中使用 Number 构造函数并传递 Number 值参数创建。生成的对象有一个内部插槽,值为 Number 值。Number 对象可通过将 Number 构造函数作为函数调用(21.1.1.1)被强制转换为 Number 值。

4.4.26 Infinity

为正无穷值的 Number 值

4.4.27 NaN

IEEE 754-2019 NaN(非数字)值的 Number 值

4.4.28 BigInt 值

对应于任意精度整数值的原始值

4.4.29 BigInt 类型

所有可能的 BigInt 值集合

4.4.30 BigInt 对象

属于 Object 类型且为标准内建 BigInt 构造函数实例的成员

4.4.31 Symbol 值

表示唯一、非 String 对象属性键的原始值

4.4.32 Symbol 类型

所有可能的 Symbol 值集合

4.4.33 Symbol 对象

属于 Object 类型且为标准内建 Symbol 构造函数实例的成员

4.4.34 函数

属于 Object 类型,可作为子程序调用的成员

Note

函数除具有属性外,还包含可执行代码和状态,决定调用时的行为。函数代码可能用 ECMAScript 编写,也可能不是。

4.4.35 内建函数

为函数的内建对象

Note

内建函数示例包括 parseIntMath.exp宿主或实现可提供未在本规范描述的其他内建函数。

4.4.36 内建构造函数

构造函数的内建函数

Note

内建构造函数示例包括 ObjectFunction宿主或实现可提供未在本规范描述的其他内建构造函数

4.4.37 属性

对象的一部分,将键(String 值或 Symbol 值)与值关联

Note

根据属性形式,值可以直接表示为数据值(原始值、对象或函数对象),也可以通过一对访问器函数间接表示。

4.4.38 方法

作为属性值的函数

Note

当函数作为对象的方法调用时,该对象作为 this 值传递给函数。

4.4.39 内建方法

为内建函数的方法

Note

标准内建方法由本规范定义。宿主或实现可提供未在本规范描述的其他内建方法。

4.4.40 特性

定义属性某些特性的内部值

4.4.41 自身属性

直接由对象包含的属性

4.4.42 继承属性

不是对象自身属性但属于对象原型(自身或继承)的属性

4.5 本规范的结构

本规范余下内容组织如下:

5 条款定义了贯穿规范的符号约定。

610 条款定义了 ECMAScript 程序运行的执行环境。

1117 条款定义了实际的 ECMAScript 编程语言,包括语法编码和所有语言特性的执行语义。

1828 条款定义了 ECMAScript 标准库,包含 ECMAScript 程序执行时可用的所有标准对象定义。

29 条款描述了对 SharedArrayBuffer 支持的内存一致性模型以及 Atomics 对象的方法。

5 符号约定

5.1 句法和词法文法

5.1.1 上下文无关文法

上下文无关文法由若干产生式组成。每个产生式都有一个抽象符号,称为非终结符,作为其左部,以及由零个或多个非终结符和终结符组成的序列,作为其右部。对于每个文法,终结符来自指定的字母表。

链式产生式是指其右部恰好只有一个非终结符和零个或多个终结符的产生式。

从一个仅包含单一特殊非终结符的句子开始,称为目标符号,给定的上下文无关文法定义了一个语言,即通过不断将序列中的任意非终结符替换为以该非终结符为左部的某个产生式的右部,最终可能得到的所有终结符序列的集合(可能是无限的)。

5.1.2 词法和正则表达式文法

ECMAScript 的词法文法12。该文法的终结符是符合 11.1SourceCharacter 规则的 Unicode 码点。它定义了一组产生式,从目标符号 InputElementDivInputElementTemplateTailInputElementRegExpInputElementRegExpOrTemplateTailInputElementHashbangOrRegExp 开始,描述了这些码点序列如何转换为输入元素序列。

除空白和注释外的输入元素构成 ECMAScript 句法文法的终结符,被称为 ECMAScript 标记。这些标记包括 ECMAScript 语言的保留字、标识符、字面量和标点符号。此外,行终止符虽然不是标记,但也成为输入元素流的一部分,引导自动分号插入过程(12.10)。简单空白和单行注释会被丢弃,不会出现在句法文法的输入元素流中。MultiLineComment(即形如 /**/ 的注释,无论是否跨越多行)如果不包含行终止符,则同样被丢弃;但若包含一个或多个行终止符,则被替换为一个单一行终止符,后者成为句法文法输入元素流的一部分。

ECMAScript 的正则表达式文法22.2.1。该文法的终结符同样为 SourceCharacter 所定义的码点。它定义了一组产生式,从目标符号 Pattern 开始,描述了码点序列如何转换为正则表达式模式。

词法和正则表达式文法的产生式以两个冒号“::”作为分隔标志。词法文法和正则表达式文法共享部分产生式。

5.1.3 数值字符串文法

数值字符串文法7.1.4.1。其终结符为 SourceCharacter,用于将字符串从目标符号 StringNumericLiteral 开始转换为数值(与 数值字面量的词法文法 类似但不同)。

数值字符串文法的产生式以三个冒号“:::”为标点,并从不用于解析源文本。

5.1.4 句法文法

ECMAScript 的句法文法1316。该文法的终结符为词法文法定义的 ECMAScript 标记(5.1.2)。它定义了一组产生式,从两个备选目标符号 ScriptModule 开始,描述了标记序列如何组成语法正确的 ECMAScript 程序独立组件。

当要将码点流解析为 ECMAScript 的 ScriptModule 时,首先通过反复应用词法文法,将其转换为输入元素流;然后该输入元素流通过一次句法文法解析。若输入元素流中的标记无法解析为一个目标非终结符(ScriptModule)的实例,且没有剩余标记,则输入流存在语法错误。

解析成功时会构建一个解析树,即以根为起点的树结构,每个节点为一个解析节点。每个解析节点是文法符号的一个实例,表示可由该符号导出的源文本片段。解析树的根节点,代表整个源文本,是解析目标符号的一个实例。当解析节点是非终结符的实例时,也是以该非终结符为左部的某个产生式的实例。此外,它有零个或多个子节点,每个对应产生式右部的一个符号:每个子节点是相应符号的解析节点实例。

每次解析器调用都会实例化新的解析节点,即使解析的源文本完全相同,解析节点也不会复用。只有当解析节点代表同一源文本片段、是同一文法符号的实例且来源于同一次解析器调用时,才认为它们是同一个解析节点

Note 1

多次解析同一个字符串会得到不同的解析节点。例如:

let str = "1 + 1;";
eval(str);
eval(str);

每次调用 eval 都会将 str 的值转换为 ECMAScript 源文本,并进行独立解析,生成各自独立的解析节点树。即使每次解析的源文本都来自同一个字符串值,树结构也是不同的。

Note 2
解析节点是规范中的抽象实体,具体实现无需采用类似的数据结构。

句法文法的产生式以单个冒号“:”作为标点。

1316 条款中呈现的句法文法并未完全覆盖所有可作为正确 ECMAScript ScriptModule 被接受的标记序列。额外接受的标记序列包括那些仅需在某些位置(如行终止符前)添加分号即可被文法描述的序列。此外,某些文法描述的标记序列若在某些“特殊”位置出现行终止符,则不被接受。

为避免歧义,句法文法在某些情况下使用了广义产生式,允许不形成有效 ECMAScript ScriptModule 的标记序列。例如,对象字面量和对象解构模式采用此技术。在这些情况下,会提供更严格的补充文法以进一步限制可接受的标记序列。一般情况下,早期错误规则会规定,在某些上下文中,“P 必须覆盖 N”,其中 P 是解析节点(广义产生式的实例),N 是补充文法中的非终结符。这表示:

  1. P 最初匹配的标记序列,以 N 作为目标符号再次解析。如果 N 有文法参数,则使用 P 最初解析时的参数值。
  2. 如果标记序列能作为 N 的唯一实例解析,且无剩余标记,则:
    1. 我们称该实例(唯一对应于某个 P 的解析节点)为“P覆盖N”。
    2. 所有对 N 及其派生产生式的早期错误规则也适用于 P 所覆盖的 N
  3. 否则(解析失败),则为早期语法错误。

5.1.5 文法记号

5.1.5.1 终结符号

在 ECMAScript 文法中,部分终结符以 等宽字体 展示。这些符号应在源文本中完全按原样出现。此类终结符指定的所有码点均应理解为基本拉丁区(Basic Latin block)中对应的 Unicode 码点,不包括其他 Unicode 区段中外观相似的码点。终结符中的码点不能用 \ UnicodeEscapeSequence 表示。

在以单个 Unicode 码点为终结符的文法(即词法、正则和数值字符串文法)中,产生式中连续出现的多个等宽码点是一种简写,表示同样顺序的独立终结符。

例如如下产生式:

HexIntegerLiteral :: 0x HexDigits

是如下写法的简写:

HexIntegerLiteral :: 0 x HexDigits

而在句法文法中,连续的等宽码点则视为单一终结符。

终结符还可以有两种形式:

5.1.5.2 非终结符号和产生式

非终结符以斜体展示。非终结符的定义(也称“产生式”)由被定义的非终结符名称后跟一个或多个冒号引出。(冒号数量表明该产生式属于哪种文法。)随后为该非终结符的一个或多个备选右部。例如,句法定义:

WhileStatement : while ( Expression ) Statement

说明非终结符 WhileStatement 表示标记 while,后跟左括号标记,再跟 Expression,再跟右括号标记,最后跟 Statement。其中 ExpressionStatement 本身也是非终结符。另一个例子,句法定义:

ArgumentList : AssignmentExpression ArgumentList , AssignmentExpression

说明 ArgumentList 可以表示单个 AssignmentExpression,或 ArgumentList 后跟逗号,再跟 AssignmentExpression。该定义是递归的,即用自身定义自身。因此 ArgumentList 可包含任意数量且大于零的参数,每个参数表达式为 AssignmentExpression,参数间以逗号分隔。此类递归定义很常见。

5.1.5.3 可选符号

下标后缀“opt”用于终结符或非终结符之后,表示该符号为可选。包含可选符号的备选实际上指定了两个右部:一个省略可选元素,一个包含可选元素。即:

VariableDeclaration : BindingIdentifier Initializeropt

是如下写法的简写:

VariableDeclaration : BindingIdentifier BindingIdentifier Initializer

同理:

ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement

是如下写法的简写:

ForStatement : for ( LexicalDeclaration ; Expressionopt ) Statement for ( LexicalDeclaration Expression ; Expressionopt ) Statement

进一步简写为:

ForStatement : for ( LexicalDeclaration ; ) Statement for ( LexicalDeclaration ; Expression ) Statement for ( LexicalDeclaration Expression ; ) Statement for ( LexicalDeclaration Expression ; Expression ) Statement

所以在此例中,非终结符 ForStatement 实际有四个备选右部。

5.1.5.4 文法参数

产生式可以通过下标标注“[参数]”进行参数化,该标注可作为产生式定义的非终结符后缀。“参数”可以是单个名称或以逗号分隔的名称列表。参数化产生式是对一组产生式的简写,定义了所有参数名称组合,组合名以下划线为前缀,附加到参数化非终结符后。即:

StatementList[Return] : ReturnStatement ExpressionStatement

是如下写法的简写:

StatementList : ReturnStatement ExpressionStatement StatementList_Return : ReturnStatement ExpressionStatement

同理:

StatementList[Return, In] : ReturnStatement ExpressionStatement

是如下写法的简写:

StatementList : ReturnStatement ExpressionStatement StatementList_Return : ReturnStatement ExpressionStatement StatementList_In : ReturnStatement ExpressionStatement StatementList_Return_In : ReturnStatement ExpressionStatement

多个参数会生成组合数量的产生式,但完整文法中并不一定全部引用。

产生式右部对非终结符的引用也可以参数化。例如:

StatementList : ReturnStatement ExpressionStatement[+In]

等价于:

StatementList : ReturnStatement ExpressionStatement_In

而:

StatementList : ReturnStatement ExpressionStatement[~In]

等价于:

StatementList : ReturnStatement ExpressionStatement

非终结符引用可以同时有参数列表和“opt”后缀。例如:

VariableDeclaration : BindingIdentifier Initializer[+In]opt

简写为:

VariableDeclaration : BindingIdentifier BindingIdentifier Initializer_In

在右部非终结符引用上用“?”作为参数名前缀,使该参数取值依赖于当前产生式左部符号引用是否出现该参数。例如:

VariableDeclaration[In] : BindingIdentifier Initializer[?In]

是如下写法的简写:

VariableDeclaration : BindingIdentifier Initializer VariableDeclaration_In : BindingIdentifier Initializer_In

如果右部备选以“[+参数]”为前缀,表示仅当引用产生式非终结符时使用了该参数名才可用该备选。如果以“[~参数]”为前缀,则仅在未使用该参数名时可用该备选。即:

StatementList[Return] : [+Return] ReturnStatement ExpressionStatement

简写为:

StatementList : ExpressionStatement StatementList_Return : ReturnStatement ExpressionStatement

同理:

StatementList[Return] : [~Return] ReturnStatement ExpressionStatement

简写为:

StatementList : ReturnStatement ExpressionStatement StatementList_Return : ExpressionStatement

5.1.5.5 one of

当“one of”出现在文法定义中的冒号后,表示后续每个终结符都是一个备选定义。例如 ECMAScript 的词法文法包含如下产生式:

NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9

实际上是如下简写:

NonZeroDigit :: 1 2 3 4 5 6 7 8 9

5.1.5.6 [empty]

如果“[empty]”出现在产生式右部,表示该产生式右部不包含任何终结符或非终结符。

5.1.5.7 前瞻限制

若“[lookahead = seq]”出现在产生式右部,表示只有当标记序列 seq 是紧跟输入标记序列的前缀时,才能使用该产生式。同理,“[lookahead ∈ set]”,其中 set有限非空标记序列集合,表示只有当集合中的某个元素是紧跟输入标记序列的前缀时才能使用该产生式。为了方便,也可以将集合写为非终结符,此时表示该非终结符可能扩展到的所有标记序列。若非终结符能扩展为无限多种不同标记序列,则视为编辑错误。

这些条件可以取反。“[lookahead ≠ seq]”表示只有当 seq 不是紧跟输入标记序列的前缀时才能使用该产生式,而“[lookahead ∉ set]”表示只有当集合中无元素是紧跟输入标记序列的前缀时才能使用该产生式。

例如,给定如下定义:

DecimalDigit :: one of 0 1 2 3 4 5 6 7 8 9 DecimalDigits :: DecimalDigit DecimalDigits DecimalDigit

则如下定义:

LookaheadExample :: n [lookahead ∉ { 1, 3, 5, 7, 9 }] DecimalDigits DecimalDigit [lookahead ∉ DecimalDigit]

匹配字符 n 后跟一个或多个十进制数字,且首位为偶数,或匹配一个十进制数字且后面不再有十进制数字。

注意,这些短语用于句法文法时,可能无法明确识别紧跟的标记序列,因为确定后续标记需要知道后续使用哪个词法目标符号。因此,在句法文法中使用这些短语时,若前缀标记序列 seq 的词法目标符号选择会影响其是否作为结果标记序列前缀,则视为编辑错误。

5.1.5.8 [此处无 LineTerminator]

若“[no LineTerminator here]”出现在句法文法产生式右部,表示该产生式为受限产生式:若在指定位置的输入流中出现 LineTerminator,则不能使用该产生式。例如如下产生式:

ThrowStatement : throw [no LineTerminator here] Expression ;

表示若在脚本中的 throw 标记和 Expression 之间出现 LineTerminator,则不能使用该产生式。

除非受限产生式禁止出现 LineTerminator,否则在输入元素流的任意两个连续标记之间可以出现任意数量的 LineTerminator,不会影响脚本的语法合法性。

5.1.5.9 but not

产生式右部可用“but not”短语指定某些扩展不允许。例如如下产生式:

Identifier :: IdentifierName but not ReservedWord

表示非终结符 Identifier 可替换为可替换 IdentifierName 的任何码点序列,但不能替换为可替换 ReservedWord 的同一序列。

5.1.5.10 描述性短语

最后,少数非终结符用无衬线字体描述性短语来说明,当枚举所有备选项不切实际时使用:

SourceCharacter :: 任意 Unicode 码点

5.2 算法约定

规范经常使用编号列表来指定算法步骤。这些算法用于精确定义 ECMAScript 语言结构所需的语义。算法并不意味着必须采用任何特定的实现技术。实际应用中,可能有更高效的算法可用于实现某个特性。

算法可以显式使用有序、逗号分隔的别名序列进行参数化,在算法步骤中可以通过这些别名引用对应位置传入的参数。可选参数用括号([ , name ])标记,在算法步骤中与必选参数没有区别。参数列表末尾可以出现剩余参数,用前置省略号(, ...name)标记。剩余参数会将所有必选和可选参数之后传入的参数收集到一个 List 中。如果没有额外参数,则该 List 为空。

算法步骤可以细分为顺序子步骤。子步骤缩进显示,并且自身可以进一步划分为缩进子步骤。大纲编号用于标识子步骤:第一层使用小写字母,第二层使用小写罗马数字。如需超过三层,则第四层用数字编号。例如:

  1. 顶层步骤
    1. 子步骤。
    2. 子步骤。
      1. 子子步骤。
        1. 子子子步骤
          1. 子子子子步骤
            1. 子子子子子步骤

某个步骤或子步骤可以写成“if”条件,控制其子步骤。此时,只有条件为真时才执行子步骤。如果步骤或子步骤以“else”开头,则表示该条件是同级前一个“if”条件的否定。

步骤可以指定对子步骤的迭代应用。

以“Assert:”开头的步骤表示断言该算法的不变条件。这样的断言用于显式表达本应隐含的算法不变量,不增加语义要求,因此实现无需检查。它们仅用于澄清算法。

算法步骤可以用“Let x be someValue”声明命名别名。这些别名类似引用,即 xsomeValue 都引用相同的数据,对任一的修改都可见。若算法步骤希望避免引用行为,应显式复制右侧值:“Let x be a copy of someValue”会创建 someValue 的浅复制。

别名声明后可在后续步骤引用,但不可在声明前引用。别名可用“Set x to someOtherValue”进行赋值。

5.2.1 抽象操作

为便于在规范多个部分中使用,部分算法(称为抽象操作)采用命名并参数化的函数形式书写,以便在其他算法中通过名称引用。抽象操作通常以函数调用形式引用,如 OperationName(arg1, arg2)。有些抽象操作作为类似类的规范抽象的多态分派方法对待,这类方法通常以 someValue.OperationName(arg1, arg2) 形式引用。

5.2.2 语法导向操作

语法导向操作是指以名称定义、由若干算法组成,并与 ECMAScript 某个文法中的一个或多个产生式关联的操作。具有多个备选定义的产生式通常为每个备选定义关联一个独立算法。若算法与某个文法产生式关联,则可将产生式备选中的终结符和非终结符视为算法参数进行引用。以此方式使用时,非终结符引用实际为解析源文本时匹配的具体备选定义。某个文法产生式或其派生的解析节点所匹配的源文本是指从第一个参与匹配的终结符开始到最后一个终结符结束的源文本片段。

当算法与产生式备选关联时,备选一般不带“[ ]”文法标注。这些标注仅影响备选的句法识别,对备选相关语义无影响。

语法导向操作通过解析节点和可选参数调用,具体调用方式见以下算法的 134 步骤:

  1. Let status be SyntaxDirectedOperation of SomeNonTerminal.
  2. Let someParseNode be the parse of some source text.
  3. Perform SyntaxDirectedOperation of someParseNode.
  4. Perform SyntaxDirectedOperation of someParseNode with argument "value".

除非另有说明,所有链式产生式都隐含定义了对该产生式左部非终结符可应用的所有操作的隐含定义。隐含定义即对链式产生式唯一右部非终结符以相同参数重复应用同一操作,返回结果。例如,假设某算法有如下步骤:“Return Evaluation of Block”且有如下产生式:

Block : { StatementList }

但 Evaluation 操作未与该产生式关联算法,则此时 Evaluation 操作隐含如下关联:

运行时语义:Evaluation

Block : { StatementList }
  1. Return Evaluation of StatementList.

5.2.3 运行时语义

指定运行时必须调用的语义的算法称为运行时语义。运行时语义通过抽象操作语法导向操作定义。

5.2.3.1 Completion ( completionRecord )

The abstract operation Completion takes argument completionRecord (a Completion Record) and returns a Completion Record. It performs the following steps when called:

  1. Assert: completionRecordCompletion Record
  2. Return completionRecord.

5.2.3.2 抛出异常

算法步骤如:

  1. Throw a TypeError exception.

与如下语句含义相同:

  1. Return ThrowCompletion(a newly created TypeError object).

5.2.3.3 ReturnIfAbrupt

算法步骤如:

  1. ReturnIfAbrupt(argument).

与如下语句含义相同:

  1. Assert: argumentCompletion Record
  2. 如果 argument异常完成,则返回 Completion(argument)。
  3. 否则,将 argument 设为 argument.[[Value]]

算法步骤如:

  1. ReturnIfAbrupt(AbstractOperation()).

与如下语句含义相同:

  1. Let hygienicTemp be AbstractOperation().
  2. Assert: hygienicTempCompletion Record
  3. 如果 hygienicTemp异常完成,则返回 Completion(hygienicTemp)。
  4. 否则,将 hygienicTemp 设为 hygienicTemp.[[Value]]

其中 hygienicTemp 仅在 ReturnIfAbrupt 相关步骤中可见且为临时变量。

算法步骤如:

  1. Let result be AbstractOperation(ReturnIfAbrupt(argument)).

与如下语句含义相同:

  1. Assert: argumentCompletion Record
  2. 如果 argument异常完成,则返回 Completion(argument)。
  3. 否则,将 argument 设为 argument.[[Value]]
  4. Let result be AbstractOperation(argument)。

5.2.3.4 ReturnIfAbrupt 简记法

抽象操作语法导向操作调用前加 ? 表示应对返回的 Completion Record 应用 ReturnIfAbrupt。例如:

  1. ? OperationName().

等价于:

  1. ReturnIfAbrupt(OperationName()).

类似地,方法调用风格:

  1. someValue.OperationName().

等价于:

  1. ReturnIfAbrupt(someValue.OperationName()).

类似地,前缀 ! 表示后续抽象或语法导向操作的调用不会返回异常完成,结果应取 Completion Record[[Value]] 字段作为操作的返回值。例如:

  1. Let val be ! OperationName().

等价于:

  1. Let val be OperationName()。
  2. Assert: val正常完成
  3. Set val to val.[[Value]]

运行时语义语法导向操作会通过在操作调用前加 !? 使用此简记法:

  1. Perform ! SyntaxDirectedOperation of NonTerminal

5.2.3.5 隐式正常完成

对于声明为返回 Completion Record抽象操作算法以及所有内建函数,其返回值会先传递给 NormalCompletion,再使用结果。该规则不适用于 Completion 算法内部或返回值明确标为 Completion Record 的步骤;包括:

如果通过其他方式从此类抽象操作返回 Completion Record,则属于编辑错误。例如,在这些抽象操作中,

  1. Return true.

与如下语句含义相同:

  1. Return NormalCompletion(true)。

  1. Let completion be NormalCompletion(true)。
  2. Return Completion(completion)。

  1. Return Completion Record { [[Type]]: normal, [[Value]]: true, [[Target]]: empty }。

注意,通过 ReturnIfAbrupt 展开,以下写法允许,因为在展开步骤中,异常情况直接返回 Completion,正常情况在解包后隐式应用 NormalCompletion

  1. Return ? completion

以下示例则属于编辑错误,因为返回 Completion Record 时未在该步骤标注。

  1. Let completion be NormalCompletion(true)。
  2. Return completion

5.2.4 静态语义

上下文无关文法无法表达所有判断输入元素流是否能组成可求值的有效 ECMAScript ScriptModule 的规则。在某些情况下需补充规则,可用 ECMAScript 算法约定或散文要求表达。这些规则总是与某个文法产生式关联,称为该产生式的静态语义

静态语义规则有名称,通常用算法定义。命名静态语义规则与文法产生式关联,具有多个备选定义的产生式通常为每个备选和每个适用的命名静态语义规则定义独立算法。

一种特殊的静态语义规则是早期错误规则早期错误规则定义了与特定文法产生式关联的早期错误条件(见 17 条款)。大多数早期错误规则的判断不会在规范算法中显式调用。符合规范的实现必须在首次求值 ScriptModule 之前,验证用于解析该 ScriptModule 的所有产生式的早期错误规则。如果有任何早期错误规则被违反,则该 ScriptModule 无效且不可求值。

5.2.5 数学运算

规范涉及以下数值类型:

  • 数学值:任意实数,作为默认数值类型。
  • 扩展数学值数学值加上 +∞ 和 -∞。
  • NumbersIEEE 754-2019 binary64(双精度浮点数)值。
  • BigIntsECMAScript 语言值,一一对应表示任意整数。

在规范语言中,不同数值类型通过下标后缀区分。下标 𝔽 表示 Numbers,下标 表示 BigInts。无下标后缀的数值表示数学值。规范多数数值以十进制表示,也用 0x 加数字 0-9 或 A-F 表示十六进制。

一般来说,规范提及数值时,如“y 的长度”或“四个十六进制数字表示的整数”,未显式说明数值类型时,指的是数学值。指明 Number 或 BigInt 时会明确标注,如“表示代码点数量的 Number 值”或“表示某值的 BigInt 值”。

规范中的integer指数学上的整数,除非另有说明。integral Number数学值为整数的有限 Number 值。

如 +、×、=、≥ 等数值运算符,具体操作取决于操作数类型。用于数学值时为常规数学运算,扩展数学值时为扩展实数运算(不定义不定型,规范中出现为编辑错误),用于 Number 时为 IEEE 754-2019 运算,BigInt 时为 BigInt 的数学值运算。混合类型操作数(如 Number 与数学值)不定义,规范中出现为编辑错误。

数学值与 Number 或 BigInt 间转换均为显式。数学值扩展数学值 x 转 Number 表示为“x 的 Number 值”或 𝔽(x),见 6.1.6.1。整数 x 转 BigInt 表示为“xBigInt 值”或 ℤ(x)。Number 或 BigInt x数学值表示为“x数学值”或 ℝ(x)+0𝔽-0𝔽数学值为 0,非有限值的数学值不定义。x 的扩展数学值 对于有限值为数学值+∞𝔽-∞𝔽 分别为 +∞ 和 -∞,NaN 不定义。

数学函数 abs(x) 返回 x 的绝对值,即当 x < 0 时为 -x,否则为 x

数学函数 min(x1, x2, … , xN)x1xN 中最小值,max(x1, x2, ..., xN) 取最大值,定义域和值域为扩展数学值

记号“xy”(y 必须为有限且非零)计算与 y 同号或为零的值 k,满足 abs(k) < abs(y) 且 x - k = q × y,其中 q 为整数。

“将 x 限制在 lowerupper 之间”(x扩展数学值lowerupper 为满足 lowerupper数学值)表示若 x < lower,则取 lower,若 x > upper,则取 upper,否则取 x

数学函数 floor(x) 返回不大于 x 的最大整数(最接近 +∞)。

Note

floor(x) = x - (x 模 1)

数学函数 truncate(x) 通过向零舍入移除 x 的小数部分,当 x < 0 时为 -floor(-x),否则为 floor(x)

数学函数 minmaxabsfloortruncate 不用于 Numbers 和 BigInts,对非数学值参数使用这些方法属于编辑错误。

区间从下界 a 到上界 b,是同一数值类型的可能无限或空的数值集合。每个边界描述为闭或开,不可兼有。区间分为四种:

  • a(闭)到 b(闭),亦称闭区间,包含所有满足 axb 的同类型值 x
  • a(闭)到 b(开),包含所有满足 ax < b 的同类型值 x
  • a(开)到 b(闭),包含所有满足 a < xb 的同类型值 x
  • a(开)到 b(开),包含所有满足 a < x < b 的同类型值 x

例如,1(闭)到 2(开)区间包含所有 1 到 2 之间的数学值,包括 1 不包括 2。定义区间时,-0𝔽 < +0𝔽,因此下界为 +0𝔽闭区间包含 +0𝔽 但不包含 -0𝔽NaN 永不包含在区间内。

5.2.6 值记号

本规范中,ECMAScript 语言值粗体 显示,如 nulltrue"hello"。这与 ECMAScript 源文本(如 Function.prototype.applylet n = 42;)区分开。

5.2.7 同一性

本规范中,规范值和 ECMAScript 语言值都可进行相等性比较。比较时,值分为两类。无同一性的值,若所有固有特性相同(如整数的大小或序列的长度)则彼此相等。无同一性值可通过完全描述其特性直接表现,无需先前引用。相比之下,有同一性的值是唯一的,仅与自身相等。有同一性的值除了拥有无同一性值的特性,还具有不可猜测、不可变、全局唯一的特性,称为同一性。对现有有同一性的值的引用不能仅通过描述其特性表现,同一性本身无法描述,必须显式传递。有同一性的值有些可变,可原地改变其特性(除了同一性),所有持有者都能观察到新特性。无同一性值永远不等于有同一性值。

在规范角度,“is”用于比较两个值是否相等,例如“If bool is true, then ...”;“contains”用于在列表中用相等性比较查找值,如“If list contains a Record r such that r.[[Foo]] is true, then ...”。规范值的规范同一性决定了这些比较结果,是规范中的公理。

ECMAScript 语言角度,语言值通过 SameValue 抽象操作及其递归调用比较相等性。这些比较算法决定 ECMAScript 语言值语言同一性

规范值中,无规范同一性的例子包括但不限于:数学值扩展数学值;ECMAScript 源文本、代理对、指令序言等;UTF-16 码元;Unicode 码点;枚举抽象操作(包括语法导向操作宿主钩子等);有序对。有规范同一性的例子包括但不限于:各种记录(包括属性描述符、PrivateElements 等);解析节点;列表;集合与关系;抽象闭包;数据块;私有名称;执行上下文及上下文栈;代理标识符;WaiterList 记录。

对所有 ECMAScript 语言值,除由 Symbol.for 生成的 Symbol 外,规范同一性与语言同一性一致。无规范同一性且无语言同一性的 ECMAScript 语言值包括 undefinednullBooleanStringNumberBigInt。有规范同一性和语言同一性的 ECMAScript 语言值包括 Symbol(非 Symbol.for 生成)和 Object。由 Symbol.for 生成的 Symbol 有规范同一性但无语言同一性。

6 ECMAScript 数据类型和值

本规范中的算法操作的值都具有相关的类型。可能的值类型正是本条款中定义的类型。类型进一步分为 ECMAScript 语言类型和规范类型。

6.1 ECMAScript 语言类型

ECMAScript 语言类型对应于 ECMAScript 编程人员可直接通过 ECMAScript 语言操作的值。ECMAScript 语言类型包括 Undefined、Null、Boolean、String、Symbol、Number、BigInt 和 Object。ECMAScript 语言值是指具有 ECMAScript 语言类型特征的值。

6.1.1 Undefined 类型

Undefined 类型只有一个值,称为 undefined。任何尚未赋值的变量,其值均为 undefined

6.1.2 Null 类型

Null 类型只有一个值,称为 null

6.1.3 Boolean 类型

Boolean 类型表示一个逻辑实体,具有两个值,分别为 truefalse

6.1.4 String 类型

String 类型是所有有序的零个或多个 16 位无符号整数值(“元素”)序列的集合,最大长度为 253 - 1 个元素。String 类型通常用于表示 ECMAScript 程序中的文本数据,此时每个元素都被视为一个 UTF-16 码元值。每个元素被认为在序列中占据一个位置,这些位置用非负整数索引。第一个元素(如果有)索引为 0,第二个元素索引为 1,依此类推。String 的长度即其包含的元素(即 16 位值)数。空字符串长度为零,因此不含任何元素。

未解释字符串内容的 ECMAScript 操作不施加进一步语义。解释字符串值的操作则将每个元素视为单个 UTF-16 码元。然而,ECMAScript 不限制这些码元的值或相互关系,因此进一步将字符串内容解释为 UTF-16 编码的 Unicode 码点序列时,必须考虑不规范的子序列。此类操作会对数值在闭区间 0xD800 到 0xDBFF 的码元(Unicode 标准定义为 前导代理,或正式称为 高代理码元)以及闭区间 0xDC00 到 0xDFFF 的码元(定义为 后导代理,或正式称为 低代理码元)做如下处理:

可使用 String.prototype.normalize(见 22.1.3.15)显式规范化字符串值。String.prototype.localeCompare(见 22.1.3.12)会在内部规范化字符串值,但其它操作不会隐式规范化其操作的字符串。操作结果除非另有说明,否则不具备语言或区域敏感性。

Note

该设计的理由是使字符串实现尽量简单且高效。如果 ECMAScript 源文本为标准化形式 C,则字符串字面量也一定是标准化的,只要其中不包含 Unicode 转义序列。

在本规范中,“the string-concatenation of A, B, ...”(每个参数为字符串值、码元或码元序列)表示顺序连接每个参数的码元后得到的字符串值。

“the substring of S from inclusiveStart to exclusiveEnd”(S 为字符串值或码元序列,inclusiveStartexclusiveEnd 为整数)表示从索引 inclusiveStart 到紧邻索引 exclusiveEnd 之前的顺序码元组成的字符串值(当 inclusiveStart = exclusiveEnd 时为空字符串)。若省略 "to" 后缀,则 exclusiveEndS 的长度。

the ASCII word characters”表示如下字符串值,仅包含 Unicode 基本拉丁区的所有字母和数字以及 U+005F(下划线):
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"
出于历史原因,在多种算法中具有特殊意义。

6.1.4.1 StringIndexOf ( string, searchValue, fromIndex )

The abstract operation StringIndexOf takes arguments string (a String), searchValue (a String), and fromIndex (a non-negative integer) and returns a non-negative integer or not-found. It performs the following steps when called:

  1. lenstring 的长度。
  2. 如果 searchValue 是空字符串且 fromIndexlen,返回 fromIndex
  3. searchLensearchValue 的长度。
  4. 对每个满足 fromIndexilen - searchLen 的整数 i,按升序执行
    1. candidatestringii + searchLen 的子串。
    2. 如果 candidate 等于 searchValue,返回 i
  5. 返回 not-found
Note 1

如果 searchValue 是空字符串且 fromIndexstring 的长度,则返回 fromIndex。空字符串在字符串的每个位置都可找到,包括最后一个码元之后。

Note 2

如果 fromIndex + searchValue 的长度大于 string 的长度,则本算法总是返回 not-found

6.1.4.2 StringLastIndexOf ( string, searchValue, fromIndex )

The abstract operation StringLastIndexOf takes arguments string (a String), searchValue (a String), and fromIndex (a non-negative integer) and returns a non-negative integer or not-found. It performs the following steps when called:

  1. lenstring 的长度。
  2. searchLensearchValue 的长度。
  3. Assert: fromIndex + searchLenlen
  4. 对每个满足 0 ≤ ifromIndex 的整数 i,按降序执行
    1. candidatestringii + searchLen 的子串。
    2. 如果 candidate 等于 searchValue,返回 i
  5. 返回 not-found
Note

如果 searchValue 是空字符串,则算法返回 fromIndex。空字符串在字符串的每个位置都可找到,包括最后一个码元之后。

6.1.5 Symbol 类型

Symbol 类型是所有可用作对象属性键的非字符串值的集合(6.1.7)。

每个 Symbol 都是唯一且不可变的。

每个 Symbol 都有一个不可变的 [[Description]] 内部槽,其值为字符串或 undefined

6.1.5.1 知名 Symbol

知名 Symbol 是规范算法明确引用的内建 Symbol 值。它们通常用作属性键,这些属性的值作为规范算法的扩展点。除非另有说明,知名 Symbol 在所有 realm9.3)间共享。

在本规范中,知名 Symbol 使用标准的 内在记号引用,其中内在对象为 Table 1 所列值之一。

Note
规范的早期版本采用 @@name 记号,而本版本采用 %Symbol.name%。具体包括:@@asyncIterator、@@hasInstance、@@isConcatSpreadable、@@iterator、@@match、@@matchAll、@@replace、@@search、@@species、@@split、@@toPrimitive、@@toStringTag 和 @@unscopables。
Table 1: 知名 Symbol
规范名称 [[Description]] 值及用途
%Symbol.asyncIterator% "Symbol.asyncIterator" 返回对象默认异步迭代器的方法。由 for-await-of 语句语义调用。
%Symbol.hasInstance% "Symbol.hasInstance" 判断构造函数对象是否识别某对象为其实例的方法。由 instanceof 运算符语义调用。
%Symbol.isConcatSpreadable% "Symbol.isConcatSpreadable" 一个布尔属性,若为 true 则 Array.prototype.concat 会将对象按数组元素展开。
%Symbol.iterator% "Symbol.iterator" 返回对象默认迭代器的方法。由 for-of 语句语义调用。
%Symbol.match% "Symbol.match" 正则表达式方法,用于匹配字符串。由 String.prototype.match 方法调用。
%Symbol.matchAll% "Symbol.matchAll" 正则表达式方法,返回迭代器,用于遍历字符串的所有匹配项。由 String.prototype.matchAll 方法调用。
%Symbol.replace% "Symbol.replace" 正则表达式方法,用于替换字符串中的匹配子串。由 String.prototype.replace 方法调用。
%Symbol.search% "Symbol.search" 正则表达式方法,返回匹配字符串的索引。由 String.prototype.search 方法调用。
%Symbol.species% "Symbol.species" 一个函数属性,是用于创建派生对象的构造函数
%Symbol.split% "Symbol.split" 正则表达式方法,用于在匹配索引处分割字符串。由 String.prototype.split 方法调用。
%Symbol.toPrimitive% "Symbol.toPrimitive" 将对象转换为对应原始值的方法。由 ToPrimitive 抽象操作调用。
%Symbol.toStringTag% "Symbol.toStringTag" 用于创建对象默认字符串描述的字符串属性。通过内建方法 Object.prototype.toString 访问。
%Symbol.unscopables% "Symbol.unscopables" 一个对象属性,其自身和继承的属性名是关联对象的 with 环境绑定中被排除的属性名

6.1.6 数值类型

ECMAScript 有两种内建数值类型:Number 和 BigInt。以下抽象操作定义于这些数值类型之上。“结果”列显示返回类型,同时指明部分调用可能返回异常完成

Table 2: 数值类型操作
操作 示例源码 在...的求值语义中调用 结果
Number::unaryMinus -x 一元 - 运算符 (Unary - Operator) Number
BigInt::unaryMinus BigInt
Number::bitwiseNOT ~x 按位取反运算符 (Bitwise NOT Operator ~) Number
BigInt::bitwiseNOT BigInt
Number::exponentiate x ** y 幂运算符 (Exponentiation Operator) and Math.pow ( base, exponent ) Number
BigInt::exponentiate 返回正常完成的 BigInt 或抛出完成
Number::multiply x * y 乘法类运算符 (Multiplicative Operators) Number
BigInt::multiply BigInt
Number::divide x / y 乘法类运算符 (Multiplicative Operators) Number
BigInt::divide 返回正常完成的 BigInt 或抛出完成
Number::remainder x % y 乘法类运算符 (Multiplicative Operators) Number
BigInt::remainder 返回正常完成的 BigInt 或抛出完成
Number::add x ++
++ x
x + y
后缀自增运算符 (Postfix Increment Operator), 前缀自增运算符 (Prefix Increment Operator), and 加法运算符 (The Addition Operator +) Number
BigInt::add BigInt
Number::subtract x --
-- x
x - y
后缀自减运算符 (Postfix Decrement Operator), 前缀自减运算符 (Prefix Decrement Operator), and 减法运算符 (The Subtraction Operator -) Number
BigInt::subtract BigInt
Number::leftShift x << y 左移运算符 (The Left Shift Operator <<) Number
BigInt::leftShift BigInt
Number::signedRightShift x >> y 带符号右移运算符 (The Signed Right Shift Operator >>) Number
BigInt::signedRightShift BigInt
Number::unsignedRightShift x >>> y 无符号右移运算符 (The Unsigned Right Shift Operator >>>) Number
BigInt::unsignedRightShift 抛出完成
Number::lessThan x < y
x > y
x <= y
x >= y
关系运算符 (Relational Operators), via IsLessThan ( x, y, LeftFirst ) Boolean 或 undefined(用于无序输入)
BigInt::lessThan Boolean
Number::equal x == y
x != y
x === y
x !== y
相等运算符 (Equality Operators), via IsStrictlyEqual ( x, y ) Boolean
BigInt::equal
Number::sameValue Object.is(x, y) 对象内部方法, via SameValue ( x, y ), 用于测试精确值相等性 Boolean
Number::sameValueZero [x].includes(y) via SameValueZero ( x, y ), 用于测试值相等性,忽略 +0𝔽-0𝔽 的区别,如 Array、Map 和 Set 方法 Boolean
Number::bitwiseAND x & y 二元按位运算符 (Binary Bitwise Operators) Number
BigInt::bitwiseAND BigInt
Number::bitwiseXOR x ^ y Number
BigInt::bitwiseXOR BigInt
Number::bitwiseOR x | y Number
BigInt::bitwiseOR BigInt
Number::toString String(x) 多种表达式和内建函数,via ToString ( argument ) String
BigInt::toString

由于数值类型通常无法在不丢失精度或截断的情况下进行转换,ECMAScript 语言不提供这些类型之间的隐式转换。程序员必须显式调用 NumberBigInt 函数来在调用需要另一种类型的函数时进行类型转换。

Note

ECMAScript 的第一版及后续版本为某些运算符提供了可能丢失精度或截断的隐式数值转换。为了兼容旧代码,这些传统的隐式转换仍然保留,但对于 BigInt 不再提供,以最大程度减少程序员出错的机会,并为将来版本支持更广泛的 值类型 留下空间。

6.1.6.1 Number 类型

Number 类型一共有 18,437,736,874,454,810,627 个值(即 264 - 253 + 3),表示 IEEE 754-2019 binary64 双精度浮点数值,遵循 IEEE 二进制浮点运算标准。不同于 IEEE 标准的 9,007,199,254,740,990 个 NaN 值(即 253 - 2),ECMAScript 将这些 NaN 都表示为一个特殊的 NaN 值。(注意,NaN 值可由表达式 NaN 得到。)在某些实现中,外部代码可能能区分不同的 NaN,但这种行为由实现定义;对于 ECMAScript 代码,所有 NaN 都无法区分。

Note

将 Number 值存入 ArrayBuffer(参见 25.1)或 SharedArrayBuffer(参见 25.2)后观察到的比特模式,不一定与 ECMAScript 内部表示该 Number 值的方式一致。

还有两个特殊值,称为 正无穷负无穷。为了简便,分别用符号 +∞𝔽-∞𝔽 表示。(注意,这两个无限值可由表达式 +Infinity(或简写为 Infinity)和 -Infinity 得到。)

其余 18,437,736,874,454,810,624 个值(即 264 - 253)称为 有限数值。这些数值一半为正,一半为负,对于每一个有限的正数,都有一个相同绝对值的负数。

注意,存在 正零负零。为了简便,分别用符号 +0𝔽-0𝔽 表示。(注意,这两个零值可由表达式 +0(或简写为 0)和 -0 得到。)

18,437,736,874,454,810,622 个有限非零值(即 264 - 253 - 2)分为两类:

其中 18,428,729,675,200,069,632 个(即 264 - 254)是规格化的,形式为:

s × m × 2e

其中 s 为 1 或 -1,m区间 [252, 253) 内的整数,e 为 [-1074, 971] 间的整数。

剩下的 9,007,199,254,740,990 个值(即 253 - 2)是非规格化的,形式为:

s × m × 2e

其中 s 为 1 或 -1,m 是 (0, 252) 区间的整数,e 等于 -1074。

注意,所有绝对值不超过 253 的正负整数都能用 Number 类型表示。整数 0 在 Number 类型中有两种表示:+0𝔽-0𝔽

有限数值如果非零且表达式中的整数 m 为奇数,则称其为 奇有效数字;否则为 偶有效数字

在本规范中,“x 的 Number 值”表示 x 是某个精确的数学实数(甚至可能是无理数如 π),其 Number 值按如下方式选取:取所有有限 Number 类型值的集合,去掉 -0𝔽 并加上两个 Number 类型不可表示的值,即 21024(即 +1 × 253 × 2971)和 -21024(即 -1 × 253 × 2971)。选取与 x 最接近的集合成员。如果有两个值一样接近,则选有效数字为偶数的那个;这时额外的两个值 21024-21024 被认为是偶有效数字。最后,如果选中 21024,则用 +∞𝔽 替换;如果选中 -21024,则用 -∞𝔽 替换;如果选中 +0𝔽,则仅当 x < 0 时替换为 -0𝔽;其他选中的值不变。结果就是 x 的 Number 值。(此过程与 IEEE 754-2019 的 roundTiesToEven 模式完全一致。)

+∞ 的 Number 值为 +∞𝔽,-∞ 的 Number 值为 -∞𝔽

某些 ECMAScript 运算符只处理范围特定的整数,比如 [-231, 231 - 1] 或 [0, 216 - 1]。这些运算符接受任意 Number 类型值,但会先将其转换为预期范围的整数。具体转换见 7.1

6.1.6.1.1 Number::unaryMinus ( x )

The abstract operation Number::unaryMinus takes argument x (一个 Number) and returns 一个 Number. It performs the following steps when called:

  1. 如果 xNaN,返回 NaN
  2. 返回 x 的相反数;即生成一个数值,大小相同,符号相反。

6.1.6.1.2 Number::bitwiseNOT ( x )

The abstract operation Number::bitwiseNOT takes argument x (一个 Number) and returns 一个整数 Number. It performs the following steps when called:

  1. oldValue 为 ! ToInt32(x)。
  2. 返回 oldValue 的按位取反。结果的数学值正好能表示为一个 32 位补码二进制串。

6.1.6.1.3 Number::exponentiate ( base, exponent )

The abstract operation Number::exponentiate takes arguments base (一个 Number) and exponent (一个 Number) and returns 一个 Number. It performs the following steps when called:

  1. 如果 exponentNaN,返回 NaN
  2. 如果 exponent+0𝔽-0𝔽,返回 1𝔽
  3. 如果 baseNaN,返回 NaN
  4. 如果 base+∞𝔽
    1. 如果 exponent > +0𝔽,返回 +∞𝔽;否则返回 +0𝔽
  5. 如果 base-∞𝔽
    1. 如果 exponent > +0𝔽
      1. 如果 exponent 是奇数整数 Number,返回 -∞𝔽;否则返回 +∞𝔽
    2. 否则:
      1. 如果 exponent 是奇数整数 Number,返回 -0𝔽;否则返回 +0𝔽
  6. 如果 base+0𝔽
    1. 如果 exponent > +0𝔽,返回 +0𝔽;否则返回 +∞𝔽
  7. 如果 base-0𝔽
    1. 如果 exponent > +0𝔽
      1. 如果 exponent 是奇数整数 Number,返回 -0𝔽;否则返回 +0𝔽
    2. 否则:
      1. 如果 exponent 是奇数整数 Number,返回 -∞𝔽;否则返回 +∞𝔽
  8. 断言:base有限值且不是 +0𝔽 也不是 -0𝔽
  9. 如果 exponent+∞𝔽
    1. 如果 abs((base)) > 1,返回 +∞𝔽
    2. 如果 abs((base)) = 1,返回 NaN
    3. 如果 abs((base)) < 1,返回 +0𝔽
  10. 如果 exponent-∞𝔽
    1. 如果 abs((base)) > 1,返回 +0𝔽
    2. 如果 abs((base)) = 1,返回 NaN
    3. 如果 abs((base)) < 1,返回 +∞𝔽
  11. 断言:exponent有限值且不是 +0𝔽 也不是 -0𝔽
  12. 如果 base < -0𝔽exponent 不是整数 Number,返回 NaN
  13. 返回一个实现近似的 Number 值,表示 (base) 的 (exponent) 次幂。
Note

base1𝔽-1𝔽,且 exponent+∞𝔽-∞𝔽,或当 base1𝔽exponentNaN 时,base ** exponent 的结果与 IEEE 754-2019 不同。ECMAScript 第一版规定此操作结果为 NaN,而后续 IEEE 754 修订版规定为 1𝔽。此处保留 ECMAScript 历史行为以兼容。

6.1.6.1.4 Number::multiply ( x, y )

The abstract operation Number::multiply takes arguments x (一个 Number) and y (一个 Number) and returns 一个 Number. It performs the following steps when called:

  1. 如果 xyNaN,返回 NaN
  2. 如果 x+∞𝔽-∞𝔽
    1. 如果 y+0𝔽-0𝔽,返回 NaN
    2. 如果 y > +0𝔽,返回 x
    3. 返回 -x
  3. 如果 y+∞𝔽-∞𝔽
    1. 如果 x+0𝔽-0𝔽,返回 NaN
    2. 如果 x > +0𝔽,返回 y
    3. 返回 -y
  4. 如果 x-0𝔽
    1. 如果 y-0𝔽y < -0𝔽,返回 +0𝔽
    2. 否则,返回 -0𝔽
  5. 如果 y-0𝔽
    1. 如果 x < -0𝔽,返回 +0𝔽
    2. 否则,返回 -0𝔽
  6. 返回 𝔽((x) × (y))。
Note

有限精度乘法是可交换的,但不总是结合的。

6.1.6.1.5 Number::divide ( x, y )

The abstract operation Number::divide takes arguments x (一个 Number) and y (一个 Number) and returns 一个 Number. It performs the following steps when called:

  1. 如果 xyNaN,返回 NaN
  2. 如果 x+∞𝔽-∞𝔽
    1. 如果 y+∞𝔽-∞𝔽,返回 NaN
    2. 如果 y+0𝔽y > +0𝔽,返回 x
    3. 返回 -x
  3. 如果 y+∞𝔽
    1. 如果 x+0𝔽x > +0𝔽,返回 +0𝔽;否则返回 -0𝔽
  4. 如果 y-∞𝔽
    1. 如果 x+0𝔽x > +0𝔽,返回 -0𝔽;否则返回 +0𝔽
  5. 如果 x+0𝔽-0𝔽
    1. 如果 y+0𝔽-0𝔽,返回 NaN
    2. 如果 y > +0𝔽,返回 x
    3. 返回 -x
  6. 如果 y+0𝔽
    1. 如果 x > +0𝔽,返回 +∞𝔽;否则返回 -∞𝔽
  7. 如果 y-0𝔽
    1. 如果 x > +0𝔽,返回 -∞𝔽;否则返回 +∞𝔽
  8. 返回 𝔽((x) / (y))。

6.1.6.1.6 Number::remainder ( n, d )

The abstract operation Number::remainder takes arguments n (一个 Number) and d (一个 Number) and returns 一个 Number. It performs the following steps when called:

  1. 如果 ndNaN,返回 NaN
  2. 如果 n+∞𝔽-∞𝔽,返回 NaN
  3. 如果 d+∞𝔽-∞𝔽,返回 n
  4. 如果 d+0𝔽-0𝔽,返回 NaN
  5. 如果 n+0𝔽-0𝔽,返回 n
  6. 断言:nd 都是有限且非零值。
  7. quotient(n) / (d)。
  8. qtruncate(quotient)。
  9. r(n) - ((d) × q)。
  10. 如果 r = 0 且 n < -0𝔽,返回 -0𝔽
  11. 返回 𝔽(r)。
Note 1

C 和 C++ 的余数运算符只接受整数操作数;而 ECMAScript 也接受浮点数操作数。

Note 2
浮点数余数运算 % 的结果与 IEEE 754-2019 中定义的“余数”操作不同。IEEE 的余数操作基于四舍五入除法,而非截断除法,因此行为不同于通常的 整数 余数运算符。ECMAScript 定义 % 运算针对浮点数时的行为类似于 Java 整数 余数运算符;可与 C 库函数 fmod 作比较。

6.1.6.1.7 Number::add ( x, y )

The abstract operation Number::add takes arguments x (一个 Number) and y (一个 Number) and returns 一个 Number. It performs the following steps when called:

  1. 如果 xyNaN,返回 NaN
  2. 如果 x+∞𝔽y-∞𝔽,返回 NaN
  3. 如果 x-∞𝔽y+∞𝔽,返回 NaN
  4. 如果 x+∞𝔽-∞𝔽,返回 x
  5. 如果 y+∞𝔽-∞𝔽,返回 y
  6. 断言:xy 都是有限值。
  7. 如果 x-0𝔽y-0𝔽,返回 -0𝔽
  8. 返回 𝔽((x) + (y))。
Note

有限精度加法是可交换的,但不总是结合的。

6.1.6.1.8 Number::subtract ( x, y )

The abstract operation Number::subtract takes arguments x (一个 Number) and y (一个 Number) and returns 一个 Number. It performs the following steps when called:

  1. 返回 Number::add(x, Number::unaryMinus(y))。
Note

始终有 x - y 的结果与 x + (-y) 相同。

6.1.6.1.9 Number::leftShift ( x, y )

The abstract operation Number::leftShift takes arguments x (一个 Number) and y (一个 Number) and returns 一个整数 Number. It performs the following steps when called:

  1. lNum 为 ! ToInt32(x)。
  2. rNum 为 ! ToUint32(y)。
  3. shiftCount(rNum) 模 32。
  4. 返回将 lNum 左移 shiftCount 位的结果。结果的数学值正好能表示为 32 位补码二进制串。

6.1.6.1.10 Number::signedRightShift ( x, y )

The abstract operation Number::signedRightShift takes arguments x (一个 Number) and y (一个 Number) and returns 一个整数 Number. It performs the following steps when called:

  1. lNum 为 ! ToInt32(x)。
  2. rNum 为 ! ToUint32(y)。
  3. shiftCount(rNum) 模 32。
  4. 返回将 lNum 进行符号扩展右移 shiftCount 位的结果。最高位会被扩展。结果的数学值正好能表示为 32 位补码二进制串。

6.1.6.1.11 Number::unsignedRightShift ( x, y )

The abstract operation Number::unsignedRightShift takes arguments x (一个 Number) and y (一个 Number) and returns 一个整数 Number. It performs the following steps when called:

  1. lNum 为 ! ToUint32(x)。
  2. rNum 为 ! ToUint32(y)。
  3. shiftCount(rNum) 模 32。
  4. 返回将 lNum 进行零填充右移 shiftCount 位的结果。空出的位用零填充。结果的数学值正好能表示为 32 位无符号二进制串。

6.1.6.1.12 Number::lessThan ( x, y )

The abstract operation Number::lessThan takes arguments x (一个 Number) and y (一个 Number) and returns Boolean 或 undefined. It performs the following steps when called:

  1. 如果 xNaN,返回 undefined
  2. 如果 yNaN,返回 undefined
  3. 如果 x 等于 y,返回 false
  4. 如果 x+0𝔽y-0𝔽,返回 false
  5. 如果 x-0𝔽y+0𝔽,返回 false
  6. 如果 x+∞𝔽,返回 false
  7. 如果 y+∞𝔽,返回 true
  8. 如果 y-∞𝔽,返回 false
  9. 如果 x-∞𝔽,返回 true
  10. 断言:xy 都是有限值。
  11. 如果 (x) < (y),返回 true;否则返回 false

6.1.6.1.13 Number::equal ( x, y )

The abstract operation Number::equal takes arguments x (一个 Number) and y (一个 Number) and returns Boolean. It performs the following steps when called:

  1. 如果 xNaN,返回 false
  2. 如果 yNaN,返回 false
  3. 如果 x 等于 y,返回 true
  4. 如果 x+0𝔽y-0𝔽,返回 true
  5. 如果 x-0𝔽y+0𝔽,返回 true
  6. 返回 false

6.1.6.1.14 Number::sameValue ( x, y )

The abstract operation Number::sameValue takes arguments x (一个 Number) and y (一个 Number) and returns Boolean. It performs the following steps when called:

  1. 如果 xy 都是 NaN,返回 true
  2. 如果 x+0𝔽y-0𝔽,返回 false
  3. 如果 x-0𝔽y+0𝔽,返回 false
  4. 如果 x 等于 y,返回 true
  5. 返回 false

6.1.6.1.15 Number::sameValueZero ( x, y )

The abstract operation Number::sameValueZero takes arguments x (一个 Number) and y (一个 Number) and returns Boolean. It performs the following steps when called:

  1. 如果 xy 都是 NaN,返回 true
  2. 如果 x+0𝔽y-0𝔽,返回 true
  3. 如果 x-0𝔽y+0𝔽,返回 true
  4. 如果 x 等于 y,返回 true
  5. 返回 false

6.1.6.1.16 NumberBitwiseOp ( op, x, y )

The abstract operation NumberBitwiseOp takes arguments op (&, ^, 或 |), x (一个 Number), and y (一个 Number) and returns 一个整数 Number. It performs the following steps when called:

  1. lNum 为 ! ToInt32(x)。
  2. rNum 为 ! ToInt32(y)。
  3. lBits 为表示 (lNum) 的 32 位补码二进制串。
  4. rBits 为表示 (rNum) 的 32 位补码二进制串。
  5. 如果 op&
    1. result 为对 lBitsrBits 应用按位与操作的结果。
  6. 否则如果 op^
    1. result 为对 lBitsrBits 应用按位异或操作的结果。
  7. 否则:
    1. 断言 op|
    2. result 为对 lBitsrBits 应用按位或操作的结果。
  8. 返回由 32 位补码二进制串 result 表示的整数的 Number 值。

6.1.6.1.17 Number::bitwiseAND ( x, y )

The abstract operation Number::bitwiseAND takes arguments x (一个 Number) and y (一个 Number) and returns 一个整数 Number. It performs the following steps when called:

  1. 返回 NumberBitwiseOp(&, x, y)。

6.1.6.1.18 Number::bitwiseXOR ( x, y )

The abstract operation Number::bitwiseXOR takes arguments x (一个 Number) and y (一个 Number) and returns 一个整数 Number. It performs the following steps when called:

  1. 返回 NumberBitwiseOp(^, x, y)。

6.1.6.1.19 Number::bitwiseOR ( x, y )

The abstract operation Number::bitwiseOR takes arguments x (一个 Number) and y (一个 Number) and returns 一个整数 Number. It performs the following steps when called:

  1. 返回 NumberBitwiseOp(|, x, y)。

6.1.6.1.20 Number::toString ( x, radix )

The abstract operation Number::toString takes arguments x (一个 Number) and radix (2 到 36 之间的整数) and returns 一个字符串. It performs the following steps when called:

  1. 如果 xNaN,返回 "NaN"
  2. 如果 x+0𝔽-0𝔽,返回 "0"
  3. 如果 x < -0𝔽,返回 "-"Number::toString(-x, radix) 的拼接字符串。
  4. 如果 x+∞𝔽,返回 "Infinity"
  5. nks 为整数,满足 k ≥ 1,radixk - 1s < radixk𝔽(s × radixn - k) 为 x,且 k 尽可能小。注意 k 是用基数 radix 表示 s 时的位数,s 不能被 radix 整除,且最低位未必唯一。
  6. 如果 radix ≠ 10 或 n 在 -5 到 21 的区间内:
    1. 如果 nk
      1. 返回拼接字符串:
        • 用基数 radix 表示 sk 位数字
        • n - k 个 0x0030(数字零)码位
    2. 否则如 n > 0:
      1. 返回拼接字符串:
        • 用基数 radix 表示 s 的最高 n 位数字
        • 0x002E(英文句点)
        • 剩余 k - n 位数字
    3. 否则:
      1. 断言:n ≤ 0。
      2. 返回拼接字符串:
        • 0x0030(数字零)码位
        • 0x002E(英文句点)
        • -n 个 0x0030(数字零)码位
        • 用基数 radix 表示 sk 位数字
  7. 注意:此时输入会用科学 E 记数法表示,如 1.2e+3
  8. 断言:radix 为 10。
  9. 如果 n < 0:
    1. exponentSign 为 0x002D(减号)。
  10. 否则:
    1. exponentSign 为 0x002B(加号)。
  11. 如果 k = 1:
    1. 返回拼接字符串:
      • s 的单一数字码位
      • 0x0065(小写字母 e)
      • exponentSign
      • abs(n - 1) 的十进制表示码位
  12. 返回拼接字符串:
    • s 十进制表示的最高位数字码位
    • 0x002E(英文句点)
    • s 十进制表示的剩余 k - 1 位码位
    • 0x0065(小写字母 e)
    • exponentSign
    • abs(n - 1) 的十进制表示码位
Note 1

以下观察可为实现提供参考,但不是标准的规范要求:

  • -0𝔽 外,任意 Number 值 x 都满足 ToNumber(ToString(x)) === x。
  • 步骤 5s 的最低位不总是唯一确定。
Note 2

对于提供比上述规则更精确转换的实现,建议参考如下步骤 5 的替代版本:

  1. nks 为整数,满足 k ≥ 1,radixk - 1s < radixk𝔽(s × radixn - k) 为 x,且 k 尽可能小。如果有多个 s,选择 s × radixn - k 最接近 (x) 的那个;如有两个结果,选偶数的那个。注意 k 是用基数 radix 表示 s 的位数,且 s 不能被 radix 整除。
Note 3

ECMAScript 实现者可参考 David M. Gay 关于浮点数二进制到十进制转换的论文和代码:

Gay, David M. Correctly Rounded Binary-Decimal and Decimal-Binary Conversions. Numerical Analysis, Manuscript 90-10. AT&T Bell Laboratories (Murray Hill, New Jersey). 1990 年 11 月 30 日。参见
https://ampl.com/_archive/first-website/REFS/rounding.pdf。相关代码见
http://netlib.sandia.gov/fp/dtoa.c 以及
http://netlib.sandia.gov/fp/g_fmt.c,也可在多个 netlib 镜像站点找到。

6.1.6.2 BigInt 类型

BigInt 类型表示整数值。该值可以为任意大小,不受特定位宽限制。通常,除非另有说明,相关操作都设计为返回精确的数学答案。对于二元运算,BigInt 被视为二进制补码字符串,负数则被视为左边有无限个被置位的位。

6.1.6.2.1 BigInt::unaryMinus ( x )

The abstract operation BigInt::unaryMinus takes argument x (一个 BigInt) and returns 一个 BigInt. It performs the following steps when called:

  1. 如果 x = 0,返回 0
  2. 返回 -x

6.1.6.2.2 BigInt::bitwiseNOT ( x )

The abstract operation BigInt::bitwiseNOT takes argument x (一个 BigInt) and returns 一个 BigInt. It performs the following steps when called:

  1. 返回 -x - 1

6.1.6.2.3 BigInt::exponentiate ( base, exponent )

The abstract operation BigInt::exponentiate takes arguments base (一个 BigInt) and exponent (一个 BigInt) and returns 正常返回一个 BigInt 或抛出异常. It performs the following steps when called:

  1. 如果 exponent < 0,抛出 RangeError 异常。
  2. 如果 base = 0exponent = 0,返回 1
  3. 返回 baseexponent 次幂。

6.1.6.2.4 BigInt::multiply ( x, y )

The abstract operation BigInt::multiply takes arguments x (一个 BigInt) and y (一个 BigInt) and returns 一个 BigInt. It performs the following steps when called:

  1. 返回 x × y
Note
即使结果的位宽远大于输入,返回的也是精确的数学答案。

6.1.6.2.5 BigInt::divide ( x, y )

The abstract operation BigInt::divide takes arguments x (一个 BigInt) and y (一个 BigInt) and returns 正常返回一个 BigInt 或抛出异常. It performs the following steps when called:

  1. 如果 y = 0,抛出 RangeError 异常。
  2. quotient(x) / (y)。
  3. 返回 (truncate(quotient))。

6.1.6.2.6 BigInt::remainder ( n, d )

The abstract operation BigInt::remainder takes arguments n (一个 BigInt) and d (一个 BigInt) and returns 正常返回一个 BigInt 或抛出异常. It performs the following steps when called:

  1. 如果 d = 0,抛出 RangeError 异常。
  2. 如果 n = 0,返回 0
  3. quotient(n) / (d)。
  4. q(truncate(quotient))。
  5. 返回 n - (d × q)。
Note
结果的符号与被除数一致。

6.1.6.2.7 BigInt::add ( x, y )

The abstract operation BigInt::add takes arguments x (一个 BigInt) and y (一个 BigInt) and returns 一个 BigInt. It performs the following steps when called:

  1. 返回 x + y

6.1.6.2.8 BigInt::subtract ( x, y )

The abstract operation BigInt::subtract takes arguments x (一个 BigInt) and y (一个 BigInt) and returns 一个 BigInt. It performs the following steps when called:

  1. 返回 x - y

6.1.6.2.9 BigInt::leftShift ( x, y )

The abstract operation BigInt::leftShift takes arguments x (一个 BigInt) and y (一个 BigInt) and returns 一个 BigInt. It performs the following steps when called:

  1. 如果 y < 0
    1. 返回 (floor((x) / 2-(y)))。
  2. 返回 x × 2y
Note
此处的语义应等价于按位移位,将 BigInt 视为无限长度的二进制补码数字串。

6.1.6.2.10 BigInt::signedRightShift ( x, y )

The abstract operation BigInt::signedRightShift takes arguments x (一个 BigInt) and y (一个 BigInt) and returns 一个 BigInt. It performs the following steps when called:

  1. 返回 BigInt::leftShift(x, -y)。

6.1.6.2.11 BigInt::unsignedRightShift ( x, y )

The abstract operation BigInt::unsignedRightShift takes arguments x (一个 BigInt) and y (一个 BigInt) and returns 抛出异常. It performs the following steps when called:

  1. 抛出 TypeError 异常。

6.1.6.2.12 BigInt::lessThan ( x, y )

The abstract operation BigInt::lessThan takes arguments x (一个 BigInt) and y (一个 BigInt) and returns Boolean. It performs the following steps when called:

  1. 如果 (x) < (y),返回 true;否则返回 false

6.1.6.2.13 BigInt::equal ( x, y )

The abstract operation BigInt::equal takes arguments x (一个 BigInt) and y (一个 BigInt) and returns Boolean. It performs the following steps when called:

  1. 如果 (x) = (y),返回 true;否则返回 false

6.1.6.2.14 BinaryAnd ( x, y )

The abstract operation BinaryAnd takes arguments x (0 或 1) and y (0 或 1) and returns 0 或 1. It performs the following steps when called:

  1. 如果 x = 1 且 y = 1,返回 1。
  2. 否则,返回 0。

6.1.6.2.15 BinaryOr ( x, y )

The abstract operation BinaryOr takes arguments x (0 或 1) and y (0 或 1) and returns 0 或 1. It performs the following steps when called:

  1. 如果 x = 1 或 y = 1,返回 1。
  2. 否则,返回 0。

6.1.6.2.16 BinaryXor ( x, y )

The abstract operation BinaryXor takes arguments x (0 或 1) and y (0 或 1) and returns 0 或 1. It performs the following steps when called:

  1. 如果 x = 1 且 y = 0,返回 1。
  2. 否则如果 x = 0 且 y = 1,返回 1。
  3. 否则,返回 0。

6.1.6.2.17 BigIntBitwiseOp ( op, x, y )

The abstract operation BigIntBitwiseOp takes arguments op (&, ^, 或 |), x (一个 BigInt), and y (一个 BigInt) and returns 一个 BigInt. It performs the following steps when called:

  1. x(x)。
  2. y(y)。
  3. result 为 0。
  4. shift 为 0。
  5. 重复,直到 (x = 0 或 x = -1) 且 (y = 0 或 y = -1) 为止,
    1. xDigitx 模 2。
    2. yDigity 模 2。
    3. 如果 op&
      1. resultresult + 2shift × BinaryAnd(xDigit, yDigit)。
    4. 否则如果 op|
      1. resultresult + 2shift × BinaryOr(xDigit, yDigit)。
    5. 否则,
      1. 断言:op^
      2. resultresult + 2shift × BinaryXor(xDigit, yDigit)。
    6. shiftshift + 1。
    7. x 为 (x - xDigit) / 2。
    8. y 为 (y - yDigit) / 2。
  6. 如果 op&
    1. tmpBinaryAnd(x 模 2, y 模 2)。
  7. 否则如果 op|
    1. tmpBinaryOr(x 模 2, y 模 2)。
  8. 否则,
    1. 断言:op^
    2. tmpBinaryXor(x 模 2, y 模 2)。
  9. 如果 tmp ≠ 0,
    1. resultresult - 2shift
    2. 注意:此操作会扩展符号位。
  10. 返回 resultBigInt 值

6.1.6.2.18 BigInt::bitwiseAND ( x, y )

The abstract operation BigInt::bitwiseAND takes arguments x (一个 BigInt) and y (一个 BigInt) and returns 一个 BigInt. It performs the following steps when called:

  1. 返回 BigIntBitwiseOp(&, x, y)。

6.1.6.2.19 BigInt::bitwiseXOR ( x, y )

The abstract operation BigInt::bitwiseXOR takes arguments x (一个 BigInt) and y (一个 BigInt) and returns 一个 BigInt. It performs the following steps when called:

  1. 返回 BigIntBitwiseOp(^, x, y)。

6.1.6.2.20 BigInt::bitwiseOR ( x, y )

The abstract operation BigInt::bitwiseOR takes arguments x (一个 BigInt) and y (一个 BigInt) and returns 一个 BigInt. It performs the following steps when called:

  1. 返回 BigIntBitwiseOp(|, x, y)。

6.1.6.2.21 BigInt::toString ( x, radix )

The abstract operation BigInt::toString takes arguments x (一个 BigInt) and radix (2 到 36 之间的整数) and returns 一个字符串. It performs the following steps when called:

  1. 如果 x < 0,返回 "-"BigInt::toString(-x, radix) 的拼接字符串。
  2. 返回用基数 radix 表示 x 的字符串值。

6.1.7 对象类型

每个 Object 类型的实例,也简称为“对象”,表示一组属性的集合。每个属性要么是数据属性,要么是访问器属性:

  • 数据属性将一个键值与一个 ECMAScript 语言值以及一组布尔属性关联起来。
  • 访问器属性将一个键值与一个或两个访问器函数以及一组布尔属性关联起来。访问器函数用于存储或获取与该属性相关联的 ECMAScript 语言值

对象的属性通过属性键唯一标识。属性键可以是字符串或符号。所有字符串和符号,包括空字符串,都是有效的属性键属性名属性键为字符串的情况。

整数索引属性名 n,满足 CanonicalNumericIndexString(n) 返回一个在 +0𝔽𝔽(253 - 1) 的闭区间内的整数 Number。数组索引整数索引 n,且 CanonicalNumericIndexString(n) 返回一个在 +0𝔽𝔽(232 - 2) 的闭区间内的整数 Number。

Note

每个非负安全整数都有对应的整数索引。每个 32 位无符号整数(除 232 - 1)都有对应的数组索引"-0" 既不是整数索引,也不是数组索引

属性键用于访问属性及其值。属性有两种访问方式:获取设置,分别对应值的读取和赋值。可通过 get 和 set 访问的属性包括作为对象直接组成部分的自身属性和通过属性继承关系由其他关联对象提供的继承属性。继承属性可以是关联对象的自身属性或继承属性。对象的每个自身属性都必须有一个与该对象其他自身属性不同的键值。

所有对象在逻辑上都是属性的集合,但对象有多种形式,不同形式在访问和操作属性时语义有所区别。参见 6.1.7.2 以了解对象的多种形式定义。

此外,某些对象可调用,被称为函数或函数对象,详见下文。所有 ECMAScript 中的函数都是 Object 类型成员。

6.1.7.1 属性特性

本规范使用属性(attributes)来定义和解释对象属性的状态,详见 Table 3。除非明确说明,每个属性的初始值为其默认值。

Table 3: 对象属性的特性
特性名称 适用属性类型 值域 默认值 描述
[[Value]] 数据属性 一个 ECMAScript 语言值 undefined 通过 get 访问属性时获得的值。
[[Writable]] 数据属性 布尔值 false 如果为 false,则 ECMAScript 代码通过 [[Set]] 尝试改变属性的 [[Value]] 特性不会成功。
[[Get]] 访问器属性 对象或 undefined undefined 如果值是对象,则必须为函数对象。每次对属性进行 get 访问时,调用该函数的 [[Call]] 内部方法(参见 Table 5),参数列表为空,以获取属性值。
[[Set]] 访问器属性 对象或 undefined undefined 如果值是对象,则必须为函数对象。每次对属性进行 set 访问时,调用该函数的 [[Call]] 内部方法(参见 Table 5),参数列表只包含要赋值的值。属性的 [[Set]] 内部方法的效果可以影响后续 [[Get]] 的返回值,但不是必须的。
[[Enumerable]] 数据属性访问器属性 布尔值 false 如果为 true,属性会被 for-in 枚举(参见 14.7.5);否则,该属性被称为不可枚举
[[Configurable]] 数据属性访问器属性 布尔值 false 如果为 false,尝试删除属性、将其从数据属性变为访问器属性或反之,以及对其特性的任何修改(除了替换已有 [[Value]] 或设置 [[Writable]]false)都不会成功。

6.1.7.2 对象的内部方法与内部槽

ECMAScript 中对象的实际语义通过称为内部方法的算法来定义。每个 ECMAScript 引擎中的对象都关联一组内部方法,定义其运行时行为。这些内部方法不是 ECMAScript 语言的一部分,仅供规范说明之用。但 ECMAScript 的每个对象都必须符合其关联的内部方法的行为,具体实现方式由实现决定。

内部方法名称是多态的。意味着不同对象值在调用相同内部方法名时可以执行不同的算法。被调用的实际对象是该方法的“目标”。如果在运行时算法实现尝试使用一个对象未支持的内部方法,则抛出 TypeError 异常。

内部槽对应于与对象、Symbol 或私有名称关联的内部状态,被 ECMAScript 规范的各种算法使用。内部槽不是对象属性,也不会被继承。根据具体内部槽的规定,这些状态可以是任意 ECMAScript 类型值或特定 ECMAScript 规范类型值。除非另有说明,内部槽在创建对象、Symbol 或私有名称时分配,不能动态添加。除非另有说明,内部槽的初始值是 undefined。本规范中的各种算法会创建具有内部槽的值。但 ECMAScript 语言无法直接操作内部槽。

所有对象都有名为 [[PrivateElements]] 的内部槽,是一个 PrivateElements 列表,表示对象的私有字段、方法和访问器的值。初始为一个空列表。

规范中用双中括号 [[ ]] 标识内部方法和内部槽。

Table 4 总结了本规范用于所有 ECMAScript 创建或操作的对象所适用的基本内部方法。每个对象必须实现所有这些基本内部方法的算法,但并不一定所有对象都用相同的算法。

普通对象是满足以下条件的对象:

  • 对于 Table 4 列出的内部方法,对象采用 10.1 中定义的方法。
  • 如果对象有 [[Call]] 内部方法,则采用 10.2.110.3.1 中定义的方法。
  • 如果对象有 [[Construct]] 内部方法,则采用 10.2.210.3.2 中定义的方法。

特殊对象是不满足普通对象条件的对象。

本规范通过对象的内部方法区分不同类型的特殊对象。如果一个对象在行为上等同于某种特殊对象(如数组特殊对象或绑定函数特殊对象),但没有实现该类型指定的所有内部方法,则不被视为该类型的特殊对象

Table 4和类似表格的“签名”列描述了每个内部方法的调用模式。调用模式总包括一个括号包裹的参数名列表。如果参数名与 ECMAScript 类型名相同,则表示该参数值必须为该类型。如果内部方法显式返回值,则参数列表后跟符号“→”和返回值类型名。签名中类型名指本规范 6 定义的类型,并补充如下额外类型名。“any”表示值可以是任意 ECMAScript 语言类型

除了参数之外,内部方法始终能访问作为方法调用目标的对象。

内部方法隐式返回一个 Completion Record,要么是包装返回类型值的正常完成,要么是抛出完成。

Table 4: 基本内部方法
内部方法 签名 描述
[[GetPrototypeOf]] ( ) Object | Null 获取为此对象提供继承属性的对象。null 表示没有继承属性。
[[SetPrototypeOf]] (Object | Null) Boolean 将此对象与另一个提供继承属性的对象关联。传递 null 表示没有继承属性。返回 true 表示操作成功,返回 false 表示操作未成功。
[[IsExtensible]] ( ) Boolean 判断是否允许向此对象添加新属性。
[[PreventExtensions]] ( ) Boolean 控制是否可向对象添加新属性。返回 true 表示操作成功,false 表示操作失败。
[[GetOwnProperty]] (propertyKey) Undefined | Property Descriptor 返回此对象自身属性中键为 propertyKey 的属性描述符,若无则返回 undefined
[[DefineOwnProperty]] (propertyKey, PropertyDescriptor) Boolean 创建或更改自身属性(键为 propertyKey),使其状态与 PropertyDescriptor 描述一致。成功时返回 true,否则返回 false
[[HasProperty]] (propertyKey) Boolean 返回布尔值,表示此对象是否已有自身或继承属性,其键为 propertyKey
[[Get]] (propertyKey, Receiver) any 获取此对象中键为 propertyKey 的属性值。若需执行 ECMAScript 代码以获取属性值,则 Receiver 作为 this 值用于代码执行。
[[Set]] (propertyKey, value, Receiver) Boolean 将键为 propertyKey 的属性值设为 value。若需执行 ECMAScript 代码以设置属性值,则 Receiver 作为 this 值用于代码执行。成功返回 true,否则返回 false
[[Delete]] (propertyKey) Boolean 删除自身属性键propertyKey 的属性。删除失败且属性仍在时返回 false,否则返回 true
[[OwnPropertyKeys]] ( ) 属性键列表 返回对象所有自身属性键的列表。

Table 5 总结了函数对象支持的附加基本内部方法。函数对象是支持 [[Call]] 内部方法的对象。构造函数是支持 [[Construct]] 内部方法的对象。每个支持 [[Construct]] 的对象都必须支持 [[Call]],即每个构造函数也是函数对象。因此构造函数也可称为构造函数对象

Table 5: 函数对象的附加基本内部方法
内部方法 签名 描述
[[Call]] (any, any 列表) any 执行与此对象关联的代码。通过函数调用表达式调用。方法参数为 this 值及调用表达式传递的参数列表。实现此方法的对象为可调用对象。
[[Construct]] (any 列表, Object) Object 创建对象。通过 new 操作符或 super 调用。第一个参数为构造器调用或 super 调用的参数列表,第二个参数为最初应用 new 操作符的对象。实现此方法的对象为构造函数函数对象不一定是构造函数,非构造函数对象没有 [[Construct]] 方法。

普通对象和标准特殊对象的基本内部方法语义在 10 中定义。如果实现不支持对某特殊对象指定的内部方法,则尝试该用法时必须抛出 TypeError 异常。

6.1.7.3 基本内部方法的不变量

ECMAScript 引擎中的对象的内部方法必须符合下列不变量。普通 ECMAScript 对象以及本规范中的所有标准特殊对象都保持这些不变量。ECMAScript Proxy 对象通过对 [[ProxyHandler]] 对象上的 trap 调用结果进行运行时检查来保持这些不变量。

任何实现提供的特殊对象也必须为这些对象保持这些不变量。违反这些不变量可能导致 ECMAScript 代码行为不可预测并引发安全问题。但违反这些不变量决不能影响实现的内存安全。

实现不得以任何方式绕过这些不变量,比如提供不强制不变量的方法接口来实现基本内部方法。

定义:

  • 内部方法的目标是调用该内部方法的对象。
  • 如果目标的 [[IsExtensible]] 方法返回 false[[PreventExtensions]] 方法返回 true,则称为不可扩展
  • 不存在属性指在不可扩展目标对象上不存在的自身属性。
  • 所有对 SameValue 的引用均依照 SameValue 算法定义。

返回值:

任何内部方法返回的值必须是一个 Completion Record,包含以下之一:

  • [[Type]] = normal[[Target]] = empty[[Value]] = 该内部方法下方“正常返回类型”对应的值,或
  • [[Type]] = throw[[Target]] = empty[[Value]] = 任意 ECMAScript 语言值
Note 1

内部方法不得返回 continue、break 或 return 类型的 Completion Record

[[GetPrototypeOf]] ( )

  • 正常返回类型为 Object 或 Null。
  • 如果目标为不可扩展,且 [[GetPrototypeOf]] 返回值 V,则未来对 [[GetPrototypeOf]] 的调用都应返回与 V SameValue 的值。
Note 2

对象的原型链应有限(即从任意对象递归调用 [[GetPrototypeOf]] 最终应到达 null)。但如果原型链中包含未采用普通对象定义的特殊对象,则无法作为对象级不变量强制此要求。出现环形原型链时,访问对象属性可能导致无限循环。

[[SetPrototypeOf]] ( V )

  • 正常返回类型为 Boolean。
  • 如果目标为不可扩展,[[SetPrototypeOf]] 必须返回 false,除非 V 与目标已观察到的 [[GetPrototypeOf]]SameValue

[[IsExtensible]] ( )

  • 正常返回类型为 Boolean。
  • 如果 [[IsExtensible]] 返回 false,则未来对目标的所有 [[IsExtensible]] 调用都必须返回 false

[[PreventExtensions]] ( )

  • 正常返回类型为 Boolean。
  • 如果 [[PreventExtensions]] 返回 true,则未来对目标的所有 [[IsExtensible]] 调用都必须返回 false,且目标被视为不可扩展。

[[GetOwnProperty]] ( P )

  • 正常返回类型为 Property Descriptor 或 Undefined。
  • 如果返回值为 Property Descriptor,必须是完整的 Property Descriptor
  • 如果 P 被描述为不可配置、不可写的自身数据属性,则未来对 [[GetOwnProperty]] ( P ) 的所有调用都必须返回 [[Value]]P[[Value]] 属性 SameValueProperty Descriptor
  • 如果 P[[Writable]][[Value]] 外的属性可能随时间变化,或属性可能被删除,则 P[[Configurable]] 属性必须为 true
  • 如果 [[Writable]] 属性可能从 false 变为 true,则 [[Configurable]] 属性必须为 true
  • 如果目标为不可扩展且 P 不存在,则未来对目标的所有 [[GetOwnProperty]] (P) 调用都必须描述 P 为不存在(即返回 undefined)。
Note 3

由第三条不变量可知,如果某属性被描述为数据属性且可能随时间返回不同值,则无论是否暴露机制修改值,只要有可能,[[Writable]][[Configurable]] 属性至少有一个必须为 true

[[DefineOwnProperty]] ( P, Desc )

  • 正常返回类型为 Boolean。
  • 除非满足以下之一,否则 [[DefineOwnProperty]] 必须返回 false,如果 P 已被观察为目标的不可配置自身属性:
    1. P 是可写数据属性。不可配置且可写的数据属性可以变为不可配置且不可写的数据属性
    2. Desc 的所有属性与 P 的属性 SameValue
  • 如果目标为不可扩展且 P 是不存在的自身属性,则 [[DefineOwnProperty]] (P, Desc) 必须返回 false。即不可扩展对象不能添加新属性。

[[HasProperty]] ( P )

  • 正常返回类型为 Boolean。
  • 如果 P 已被观察为目标的不可配置自身数据或访问器属性,则 [[HasProperty]] 必须返回 true

[[Get]] ( P, Receiver )

  • 正常返回类型为任意 ECMAScript 语言类型
  • 如果 P 已被观察为目标的不可配置、不可写自身数据属性且值为 V,则 [[Get]] 必须返回与 V SameValue 的值。
  • 如果 P 已被观察为目标的不可配置自身访问器属性[[Get]] 属性为 undefined,则 [[Get]] 操作必须返回 undefined

[[Set]] ( P, V, Receiver )

  • 正常返回类型为 Boolean。
  • 如果 P 已被观察为目标的不可配置、不可写自身数据属性,则除非 VP[[Value]] 属性 SameValue[[Set]] 必须返回 false
  • 如果 P 已被观察为目标的不可配置自身访问器属性[[Set]] 属性为 undefined,则 [[Set]] 操作必须返回 false

[[Delete]] ( P )

  • 正常返回类型为 Boolean。
  • 如果 P 已被观察为目标的不可配置自身数据或访问器属性,则 [[Delete]] 必须返回 false

[[OwnPropertyKeys]] ( )

  • 正常返回类型为 List
  • 返回的 List 不能有重复项。
  • 返回的 List 的每个元素必须是属性键
  • 返回的 List 至少含有所有已观察到的不可配置自身属性的键。
  • 如果目标为不可扩展,则返回的 List 只能包含所有可通过 [[GetOwnProperty]] 观察到的自身属性键

[[Call]] ( )

[[Construct]] ( )

  • 正常返回类型为 Object。
  • 目标还必须有 [[Call]] 内部方法。

6.1.7.4 知名内置对象

知名内置对象是本规范的算法显式引用的内置对象,通常具有特定于“域”(realm)的身份。除非另有说明,每个内置对象实际对应一组类似对象,每个域各一个。

在本规范中,%name% 表示当前域关联的对应名称的内置对象。%name.a.b% 表示在执行任何 ECMAScript 代码之前,访问内置对象 %name% 的属性 "a",再访问该属性的 "b" 属性。当前域和其内置对象的确定见 9.4。知名内置对象列表见 Table 6

Table 6: 知名内置对象
内置名称 全局名称 ECMAScript 语言关联
%AggregateError% AggregateError AggregateError 构造函数(参见 20.5.7.1
%Array% Array Array 构造函数(参见 23.1.1
%ArrayBuffer% ArrayBuffer ArrayBuffer 构造函数(参见 25.1.4
%ArrayIteratorPrototype% 数组迭代器对象的原型(参见 23.1.5
%AsyncFromSyncIteratorPrototype% Async-from-Sync 迭代器对象的原型(参见 27.1.6
%AsyncFunction% async 函数对象构造函数(参见 27.7.1
%AsyncGeneratorFunction% async 生成器函数对象构造函数(参见 27.4.1
%AsyncGeneratorPrototype% async 生成器对象的原型(参见 27.6
%AsyncIteratorPrototype% 所有标准内置 async 迭代器对象的间接继承对象
%Atomics% Atomics Atomics 对象(参见 25.4
%BigInt% BigInt BigInt 构造函数(参见 21.2.1
%BigInt64Array% BigInt64Array BigInt64Array 构造函数(参见 23.2
%BigUint64Array% BigUint64Array BigUint64Array 构造函数(参见 23.2
%Boolean% Boolean Boolean 构造函数(参见 20.3.1
%DataView% DataView DataView 构造函数(参见 25.3.2
%Date% Date Date 构造函数(参见 21.4.2
%decodeURI% decodeURI decodeURI 函数(参见 19.2.6.1
%decodeURIComponent% decodeURIComponent decodeURIComponent 函数(参见 19.2.6.2
%encodeURI% encodeURI encodeURI 函数(参见 19.2.6.3
%encodeURIComponent% encodeURIComponent encodeURIComponent 函数(参见 19.2.6.4
%Error% Error Error 构造函数(参见 20.5.1
%eval% eval eval 函数(参见 19.2.1
%EvalError% EvalError EvalError 构造函数(参见 20.5.5.1
%FinalizationRegistry% FinalizationRegistry FinalizationRegistry 构造函数(参见 26.2.1
%Float16Array% Float16Array Float16Array 构造函数(参见 23.2
%Float32Array% Float32Array Float32Array 构造函数(参见 23.2
%Float64Array% Float64Array Float64Array 构造函数(参见 23.2
%ForInIteratorPrototype% For-In 迭代器对象的原型(参见 14.7.5.10
%Function% Function Function 构造函数(参见 20.2.1
%GeneratorFunction% 生成器函数对象构造函数(参见 27.3.1
%GeneratorPrototype% 生成器对象的原型(参见 27.5
%Int8Array% Int8Array Int8Array 构造函数(参见 23.2
%Int16Array% Int16Array Int16Array 构造函数(参见 23.2
%Int32Array% Int32Array Int32Array 构造函数(参见 23.2
%isFinite% isFinite isFinite 函数(参见 19.2.2
%isNaN% isNaN isNaN 函数(参见 19.2.3
%Iterator% Iterator Iterator 构造函数(参见 27.1.3.1
%IteratorHelperPrototype% Iterator Helper 对象的原型(参见 27.1.2.1
%JSON% JSON JSON 对象(参见 25.5
%Map% Map Map 构造函数(参见 24.1.1
%MapIteratorPrototype% Map 迭代器对象的原型(参见 24.1.5
%Math% Math Math 对象(参见 21.3
%Number% Number Number 构造函数(参见 21.1.1
%Object% Object Object 构造函数(参见 20.1.1
%parseFloat% parseFloat parseFloat 函数(参见 19.2.4
%parseInt% parseInt parseInt 函数(参见 19.2.5
%Promise% Promise Promise 构造函数(参见 27.2.3
%Proxy% Proxy Proxy 构造函数(参见 28.2.1
%RangeError% RangeError RangeError 构造函数(参见 20.5.5.2
%ReferenceError% ReferenceError ReferenceError 构造函数(参见 20.5.5.3
%Reflect% Reflect Reflect 对象(参见 28.1
%RegExp% RegExp RegExp 构造函数(参见 22.2.4
%RegExpStringIteratorPrototype% 正则表达式字符串迭代器对象的原型(参见 22.2.9
%Set% Set Set 构造函数(参见 24.2.2
%SetIteratorPrototype% Set 迭代器对象的原型(参见 24.2.6
%SharedArrayBuffer% SharedArrayBuffer SharedArrayBuffer 构造函数(参见 25.2.3
%String% String String 构造函数(参见 22.1.1
%StringIteratorPrototype% 字符串迭代器对象的原型(参见 22.1.5
%Symbol% Symbol Symbol 构造函数(参见 20.4.1
%SyntaxError% SyntaxError SyntaxError 构造函数(参见 20.5.5.4
%ThrowTypeError% 一个函数对象,总是抛出新的 %TypeError% 实例
%TypedArray% 所有类型化数组构造函数的超类(参见 23.2.1
%TypeError% TypeError TypeError 构造函数(参见 20.5.5.5
%Uint8Array% Uint8Array Uint8Array 构造函数(参见 23.2
%Uint8ClampedArray% Uint8ClampedArray Uint8ClampedArray 构造函数(参见 23.2
%Uint16Array% Uint16Array Uint16Array 构造函数(参见 23.2
%Uint32Array% Uint32Array Uint32Array 构造函数(参见 23.2
%URIError% URIError URIError 构造函数(参见 20.5.5.6
%WeakMap% WeakMap WeakMap 构造函数(参见 24.3.1
%WeakRef% WeakRef WeakRef 构造函数(参见 26.1.1
%WeakSet% WeakSet WeakSet 构造函数(参见 24.4.1
%WrapForValidIteratorPrototype% Iterator.from 返回的包装迭代器对象的原型(参见 27.1.3.2.1.1
Note

更多条目见 Table 100

6.2 ECMAScript 规范类型

规范类型对应于算法中用于描述 ECMAScript 语言结构和 ECMAScript 语言类型语义的元值。规范类型包括 Reference RecordListCompletion RecordProperty DescriptorEnvironment RecordAbstract ClosureData Block。规范类型值是规范中的产物,不一定对应于 ECMAScript 实现中的具体实体。规范类型值可用于描述 ECMAScript 表达式求值的中间结果,但这些值不能作为对象的属性或 ECMAScript 语言变量的值存储。

6.2.1 枚举规范类型

枚举是规范内部使用的值,不能被 ECMAScript 代码直接观察。枚举用 无衬线体 表示。例如,Completion Record[[Type]] 字段会取 normalreturnthrow 等值。枚举除了名称外没有其他特性。枚举的名称仅用于与其他枚举区分,并不暗示其在上下文中的用途或意义。

6.2.2 List 和 Record 规范类型

List 类型用于解释参数列表(参见 13.3.8)在 new 表达式、函数调用以及需要简单有序值列表的其他算法中的求值。List 类型的值就是包含各个值的有序元素序列,序列长度可任意。List 的元素可用 0 起始的索引随机访问。为方便记号,可用类似数组的语法访问 List 元素。例如,arguments[2] 表示 List arguments 的第 3 个元素。

当算法遍历 List 元素但未指定顺序时,使用 List 元素的原有顺序。

在本规范中,为方便记号,可用字面量语法表达新的 List 值。例如,« 1, 2 » 定义了一个有两个元素的 List 值,每个元素初始化为特定值。空 List 可写作 « »。

在本规范中,“AB... 的列表拼接”(每个参数都是可能为空的 List)表示一个新 List,其元素是各参数元素(按顺序)拼接而成。

对于字符串 List,“按字典序码位顺序排序”意指按较短字符串长度以内各码位的数值排序,如相等则短字符串排前,详见抽象操作 IsLessThan

Record 类型用于规范算法中的数据聚合。Record 类型值由一个或多个具名字段组成,每个字段的值为 ECMAScript 语言值或规范值。字段名总用双括号包裹,例如 [[Value]]

在规范中,为方便记号,可用类似对象字面量的语法表达 Record 值。例如,{ [[Field1]]: 42, [[Field2]]: false, [[Field3]]: empty } 表示一个包含三个字段的 Record 值,每个字段初始化为特定值。字段名顺序无关紧要,未列出的字段视为不存在。

在规范文本和算法中,可用点号表示法引用 Record 的某个字段。例如,若 R 为上文的 Record,则 R.[[Field2]] 表示“R 的 [[Field2]] 字段”。

常用字段组合的 Record 可以命名,并作为字面量前缀,以标识描述的聚合类型。例如:PropertyDescriptor { [[Value]]: 42, [[Writable]]: false, [[Configurable]]: true }。

6.2.3 Set 和 Relation 规范类型

Set 类型用于说明内存模型中无序元素集合。它不同于 ECMAScript 集合类型 Set。为区分,规范中 ECMAScript 集合类型始终称为“Set 对象”。Set 类型值是元素集合,每个元素只出现一次。元素可加入或移除集合,集合之间可以并集、交集或相减。

Relation 类型用于说明集合上的约束。Relation 类型值是其值域上的有序对集合。例如,事件上的 Relation 是事件有序对的集合。若 Relation R,值域中的 ab,则 a R b 表示有序对 (a, b) 属于 R。Relation 是满足某些条件的最小 Relation,即满足条件的最小 Relation

严格偏序是满足以下条件的 Relation 值 R

  • R 的值域内所有 abc

    • 不存在 a R a,且
    • a R bb R c,则 a R c
Note 1

上述两个条件分别称为反自反性和传递性。

严格全序是满足以下条件的 Relation 值 R

  • R 的值域内所有 abc

    • a 等于 ba R bb R a,且
    • 不存在 a R a,且
    • a R bb R c,则 a R c
Note 2

上述三个条件分别称为全序性、反自反性和传递性。

6.2.4 Completion Record 规范类型

Completion Record 规范类型用于解释运行时值和控制流的传播,如语句(breakcontinuereturnthrow)实现的非局部控制转移行为。

Completion Record 包含 Table 7 定义的字段。

Table 7: Completion Record 字段
字段名 含义
[[Type]] normalbreakcontinuereturnthrow 发生的完成类型。
[[Value]] Completion Record 外的任何值 产生的值。
[[Target]] 字符串或 empty 用于定向控制转移的目标标签。

下列术语有时用于指代 Completion Record:

  • 正常完成[[Type]] 值为 normal 的 Completion Record。
  • break 完成[[Type]] 值为 break 的 Completion Record。
  • continue 完成[[Type]] 值为 continue 的 Completion Record。
  • return 完成[[Type]] 值为 return 的 Completion Record。
  • throw 完成[[Type]] 值为 throw 的 Completion Record。
  • 异常完成[[Type]] 值不是 normal 的 Completion Record。
  • 包含某类型值的正常完成”指 [[Value]] 字段为该类型值的正常完成。

规范中定义的可调用对象只返回正常完成或 throw 完成。返回其他类型的 Completion Record 属于编辑错误。

实现自定义的可调用对象也必须只返回正常完成或 throw 完成。

6.2.4.1 NormalCompletion ( value )

The abstract operation NormalCompletion takes argument value (除 Completion Record 外的任何值) and returns 正常完成. It performs the following steps when called:

  1. 返回 Completion Record { [[Type]]: normal, [[Value]]: value, [[Target]]: empty }。

6.2.4.2 ThrowCompletion ( value )

The abstract operation ThrowCompletion takes argument value (一个 ECMAScript 语言值) and returns throw 完成. It performs the following steps when called:

  1. 返回 Completion Record { [[Type]]: throw, [[Value]]: value, [[Target]]: empty }。

6.2.4.3 ReturnCompletion ( value )

The abstract operation ReturnCompletion takes argument value (一个 ECMAScript 语言值) and returns return 完成. It performs the following steps when called:

  1. 返回 Completion Record { [[Type]]: return, [[Value]]: value, [[Target]]: empty }。

6.2.4.4 UpdateEmpty ( completionRecord, value )

The abstract operation UpdateEmpty takes arguments completionRecord (一个 Completion Record) and value (除 Completion Record 外的任何值) and returns 一个 Completion Record. It performs the following steps when called:

  1. 断言:若 completionRecordreturn 完成throw 完成,则 completionRecord.[[Value]] 不是 empty
  2. completionRecord.[[Value]] 不是 empty,返回 ? completionRecord
  3. 返回 Completion Record { [[Type]]: completionRecord.[[Type]], [[Value]]: value, [[Target]]: completionRecord.[[Target]] }。

6.2.5 Reference Record 规范类型

Reference Record 类型用于解释如 deletetypeof、赋值运算符、super 关键字等操作的行为。例如,赋值的左操作数应产生一个 Reference Record。

Reference Record 是已解析的名称或(可能尚未解析的)属性绑定;其字段定义见 Table 8

Table 8: Reference Record 字段
字段名 含义
[[Base]] 一个 ECMAScript 语言值Environment Recordunresolvable 持有绑定的值或 Environment Record[[Base]]unresolvable 表示绑定无法解析。
[[ReferencedName]] 一个 ECMAScript 语言值Private Name 绑定的名称。若 [[Base]]Environment Record,则总为字符串。否则,可能为除字符串和符号外的 ECMAScript 语言值,直到执行 ToPropertyKey
[[Strict]] 布尔值 Reference Record 来源于严格模式代码,则为 true,否则为 false
[[ThisValue]] 一个 ECMAScript 语言值empty 若非 empty,则代表用 super 关键字表达的属性绑定,称为 Super Reference Record,其 [[Base]] 不会是 Environment Record。此时 [[ThisValue]] 字段保存创建 Reference Record 时的 this 值。

本规范使用以下抽象操作处理 Reference Record:

6.2.5.1 IsPropertyReference ( V )

The abstract operation IsPropertyReference takes argument V (一个 Reference Record) and returns 布尔值. It performs the following steps when called:

  1. V.[[Base]]unresolvable,返回 false
  2. V.[[Base]]Environment Record,返回 false;否则返回 true

6.2.5.2 IsUnresolvableReference ( V )

The abstract operation IsUnresolvableReference takes argument V (一个 Reference Record) and returns 布尔值. It performs the following steps when called:

  1. V.[[Base]]unresolvable,返回 true;否则返回 false

6.2.5.3 IsSuperReference ( V )

The abstract operation IsSuperReference takes argument V (一个 Reference Record) and returns 布尔值. It performs the following steps when called:

  1. V.[[ThisValue]]empty,返回 true;否则返回 false

6.2.5.4 IsPrivateReference ( V )

The abstract operation IsPrivateReference takes argument V (一个 Reference Record) and returns 布尔值. It performs the following steps when called:

  1. V.[[ReferencedName]]Private Name,返回 true;否则返回 false

6.2.5.5 GetValue ( V )

The abstract operation GetValue takes argument V (一个 Reference RecordECMAScript 语言值) and returns 返回包含 ECMAScript 语言值正常完成异常完成. It performs the following steps when called:

  1. V 不是 Reference Record,返回 V
  2. IsUnresolvableReference(V) 为 true,抛出 ReferenceError 异常。
  3. IsPropertyReference(V) 为 true
    1. baseObj 为 ? ToObject(V.[[Base]])。
    2. IsPrivateReference(V) 为 true
      1. 返回 ? PrivateGet(baseObj, V.[[ReferencedName]])。
    3. V.[[ReferencedName]] 不是属性键
      1. V.[[ReferencedName]] 为 ? ToPropertyKey(V.[[ReferencedName]])。
    4. 返回 ? baseObj.[[Get]](V.[[ReferencedName]], GetThisValue(V))。
  4. 否则,
    1. baseV.[[Base]]
    2. 断言:baseEnvironment Record
    3. 返回 ? base.GetBindingValue(V.[[ReferencedName]], V.[[Strict]])(参见 9.1)。
Note

步骤 3.a 可能创建的对象仅在上述抽象操作普通对象 [[Get]] 内部方法中可访问。实现可选择避免实际创建该对象。

6.2.5.6 PutValue ( V, W )

The abstract operation PutValue takes arguments V (一个 Reference RecordECMAScript 语言值) and W (一个 ECMAScript 语言值) and returns 返回包含 unused正常完成异常完成. It performs the following steps when called:

  1. V 不是 Reference Record,抛出 ReferenceError 异常。
  2. IsUnresolvableReference(V) 为 true
    1. V.[[Strict]]true,抛出 ReferenceError 异常。
    2. globalObjGetGlobalObject()。
    3. 执行 ? Set(globalObj, V.[[ReferencedName]], W, false)。
    4. 返回 unused
  3. IsPropertyReference(V) 为 true
    1. baseObj 为 ? ToObject(V.[[Base]])。
    2. IsPrivateReference(V) 为 true
      1. 返回 ? PrivateSet(baseObj, V.[[ReferencedName]], W)。
    3. V.[[ReferencedName]] 不是属性键
      1. V.[[ReferencedName]] 为 ? ToPropertyKey(V.[[ReferencedName]])。
    4. succeeded 为 ? baseObj.[[Set]](V.[[ReferencedName]], W, GetThisValue(V))。
    5. succeededfalseV.[[Strict]]true,抛出 TypeError 异常。
    6. 返回 unused
  4. 否则,
    1. baseV.[[Base]]
    2. 断言:baseEnvironment Record
    3. 返回 ? base.SetMutableBinding(V.[[ReferencedName]], W, V.[[Strict]])(参见 9.1)。
Note

步骤 3.a 可能创建的对象仅在上述抽象操作普通对象 [[Set]] 内部方法中可访问。实现可选择避免实际创建该对象。

6.2.5.7 GetThisValue ( V )

The abstract operation GetThisValue takes argument V (一个 Reference Record) and returns 一个 ECMAScript 语言值. It performs the following steps when called:

  1. 断言:IsPropertyReference(V) 为 true
  2. IsSuperReference(V) 为 true,返回 V.[[ThisValue]];否则返回 V.[[Base]]

6.2.5.8 InitializeReferencedBinding ( V, W )

The abstract operation InitializeReferencedBinding takes arguments V (一个 Reference Record) and W (一个 ECMAScript 语言值) and returns 返回包含 unused正常完成异常完成. It performs the following steps when called:

  1. 断言:IsUnresolvableReference(V) 为 false
  2. baseV.[[Base]]
  3. 断言:baseEnvironment Record
  4. 返回 ? base.InitializeBinding(V.[[ReferencedName]], W)。

6.2.5.9 MakePrivateReference ( baseValue, privateIdentifier )

The abstract operation MakePrivateReference takes arguments baseValue (一个 ECMAScript 语言值) and privateIdentifier (字符串) and returns 一个 Reference Record. It performs the following steps when called:

  1. privateEnv 为当前执行上下文的 PrivateEnvironment。
  2. 断言:privateEnv 不为 null
  3. privateNameResolvePrivateIdentifier(privateEnv, privateIdentifier)。
  4. 返回 Reference Record { [[Base]]: baseValue, [[ReferencedName]]: privateName, [[Strict]]: true, [[ThisValue]]: empty }。

6.2.6 Property Descriptor 规范类型

Property Descriptor 类型用于解释对象属性特性的操作及具现。Property Descriptor 是一个包含零个或多个字段的 Record,每个字段名为特性名,值为 6.1.7.1 所定义的特性值。本规范用 “PropertyDescriptor” 作为字面量描述 Property Descriptor Record 的标签名称。

Property Descriptor 值可根据某些字段的存在或用途进一步分为数据 Property Descriptor 和访问器 Property Descriptor。包含 [[Value]][[Writable]] 字段的为数据 Property Descriptor;包含 [[Get]][[Set]] 字段的为访问器 Property Descriptor。任意 Property Descriptor 都可包含 [[Enumerable]][[Configurable]] 字段。Property Descriptor 值不能同时为数据和访问器 Property Descriptor,但可以两者都不是(此时为通用 Property Descriptor)。完全填充的 Property Descriptor指为访问器 Property Descriptor 或数据 Property Descriptor 且已定义所有对应字段(见 Table 3)。

本规范用以下抽象操作处理 Property Descriptor 值:

6.2.6.1 IsAccessorDescriptor ( Desc )

The abstract operation IsAccessorDescriptor takes argument Desc (一个 Property Descriptor) and returns 布尔值. It performs the following steps when called:

  1. Desc[[Get]] 字段,返回 true
  2. Desc[[Set]] 字段,返回 true
  3. 返回 false

6.2.6.2 IsDataDescriptor ( Desc )

The abstract operation IsDataDescriptor takes argument Desc (一个 Property Descriptor) and returns 布尔值. It performs the following steps when called:

  1. Desc[[Value]] 字段,返回 true
  2. Desc[[Writable]] 字段,返回 true
  3. 返回 false

6.2.6.3 IsGenericDescriptor ( Desc )

The abstract operation IsGenericDescriptor takes argument Desc (一个 Property Descriptor) and returns 布尔值. It performs the following steps when called:

  1. IsAccessorDescriptor(Desc) 为 true,返回 false
  2. IsDataDescriptor(Desc) 为 true,返回 false
  3. 返回 true

6.2.6.4 FromPropertyDescriptor ( Desc )

The abstract operation FromPropertyDescriptor takes argument Desc (一个 Property Descriptorundefined) and returns 一个对象或 undefined. It performs the following steps when called:

  1. Descundefined,返回 undefined
  2. objOrdinaryObjectCreate(%Object.prototype%)。
  3. 断言:obj 是可扩展的普通对象且无自身属性。
  4. Desc[[Value]] 字段,
    1. 执行 ! CreateDataPropertyOrThrow(obj, "value", Desc.[[Value]])。
  5. Desc[[Writable]] 字段,
    1. 执行 ! CreateDataPropertyOrThrow(obj, "writable", Desc.[[Writable]])。
  6. Desc[[Get]] 字段,
    1. 执行 ! CreateDataPropertyOrThrow(obj, "get", Desc.[[Get]])。
  7. Desc[[Set]] 字段,
    1. 执行 ! CreateDataPropertyOrThrow(obj, "set", Desc.[[Set]])。
  8. Desc[[Enumerable]] 字段,
    1. 执行 ! CreateDataPropertyOrThrow(obj, "enumerable", Desc.[[Enumerable]])。
  9. Desc[[Configurable]] 字段,
    1. 执行 ! CreateDataPropertyOrThrow(obj, "configurable", Desc.[[Configurable]])。
  10. 返回 obj

6.2.6.5 ToPropertyDescriptor ( Obj )

The abstract operation ToPropertyDescriptor takes argument Obj (一个 ECMAScript 语言值) and returns 返回包含 Property Descriptor正常完成异常完成. It performs the following steps when called:

  1. Obj 不是对象,抛出 TypeError 异常。
  2. desc 为一个初始无字段的新 Property Descriptor
  3. hasEnumerable 为 ? HasProperty(Obj, "enumerable")。
  4. hasEnumerabletrue
    1. enumerableToBoolean(? Get(Obj, "enumerable"))。
    2. 设置 desc.[[Enumerable]]enumerable
  5. hasConfigurable 为 ? HasProperty(Obj, "configurable")。
  6. hasConfigurabletrue
    1. configurableToBoolean(? Get(Obj, "configurable"))。
    2. 设置 desc.[[Configurable]]configurable
  7. hasValue 为 ? HasProperty(Obj, "value")。
  8. hasValuetrue
    1. value 为 ? Get(Obj, "value")。
    2. 设置 desc.[[Value]]value
  9. hasWritable 为 ? HasProperty(Obj, "writable")。
  10. hasWritabletrue
    1. writableToBoolean(? Get(Obj, "writable"))。
    2. 设置 desc.[[Writable]]writable
  11. hasGet 为 ? HasProperty(Obj, "get")。
  12. hasGettrue
    1. getter 为 ? Get(Obj, "get")。
    2. IsCallable(getter) 为 falsegetter 不为 undefined,抛出 TypeError 异常。
    3. 设置 desc.[[Get]]getter
  13. hasSet 为 ? HasProperty(Obj, "set")。
  14. hasSettrue
    1. setter 为 ? Get(Obj, "set")。
    2. IsCallable(setter) 为 falsesetter 不为 undefined,抛出 TypeError 异常。
    3. 设置 desc.[[Set]]setter
  15. desc[[Get]] 字段或 [[Set]] 字段,
    1. desc[[Value]] 字段或 [[Writable]] 字段,抛出 TypeError 异常。
  16. 返回 desc

6.2.6.6 CompletePropertyDescriptor ( Desc )

The abstract operation CompletePropertyDescriptor takes argument Desc (一个 Property Descriptor) and returns unused. It performs the following steps when called:

  1. likeRecord { [[Value]]: undefined, [[Writable]]: false, [[Get]]: undefined, [[Set]]: undefined, [[Enumerable]]: false, [[Configurable]]: false }。
  2. IsGenericDescriptor(Desc) 为 trueIsDataDescriptor(Desc) 为 true
    1. Desc[[Value]] 字段,设置 Desc.[[Value]]like.[[Value]]
    2. Desc[[Writable]] 字段,设置 Desc.[[Writable]]like.[[Writable]]
  3. 否则,
    1. Desc[[Get]] 字段,设置 Desc.[[Get]]like.[[Get]]
    2. Desc[[Set]] 字段,设置 Desc.[[Set]]like.[[Set]]
  4. Desc[[Enumerable]] 字段,设置 Desc.[[Enumerable]]like.[[Enumerable]]
  5. Desc[[Configurable]] 字段,设置 Desc.[[Configurable]]like.[[Configurable]]
  6. 返回 unused

6.2.7 Environment Record 规范类型

Environment Record 类型用于解释嵌套函数和块中的名称解析行为。此类型及其操作定义见 9.1

6.2.8 Abstract Closure 规范类型

Abstract Closure 规范类型用于引用算法步骤及一组值。Abstract Closure 是元值,用函数调用风格如 closure(arg1, arg2) 调用。和抽象操作类似,调用时执行 Abstract Closure 描述的算法步骤。

创建 Abstract Closure 的算法步骤,用 “capture” 和别名列表描述需捕获的值。创建时,按别名捕获当时关联的值。指定 Abstract Closure 被调用时的算法步骤时,每个捕获值都用其别名引用。

若 Abstract Closure 返回 Completion Record,则必须是正常完成throw 完成

Abstract Closure 通常作为其他算法的一部分内联创建,示例如下:

  1. addend 为 41。
  2. closure 为新建 Abstract Closure,参数 (x),捕获 addend,调用时执行以下步骤:
    1. 返回 x + addend
  3. valclosure(1)。
  4. 断言:val 为 42。

6.2.9 数据块

Data Block 规范类型用于描述一段独立且可变的字节(8 位)数值序列。字节值是 0 到 255 的整数。Data Block 值创建时拥有固定数量字节,每个初始值为 0。

在规范中,为方便记号,可用类似数组的语法访问 Data Block 的各字节。该记号将 Data Block 视为 0 起始整数索引的字节序列。例如,若 db 为 5 字节 Data Block,则 db[2] 用于访问第 3 个字节。

可被多个 agent 并发引用的驻留于内存的数据块称为 Shared Data Block。Shared Data Block 有一个用于相等性测试的无地址身份:它不是绑定到任何进程的虚拟地址,而是与所代表的内存位置集合绑定。只有包含的内存位置集合相等,两数据块才相等,否则不等且其集合交集为空。Shared Data Block 可与 Data Block 区分。

Shared Data Block 的语义由内存模型通过 Shared Data Block 事件定义。下述抽象操作引入 Shared Data Block 事件,并作为求值语义与内存模型事件语义的接口。事件构成候选执行,内存模型对其进行筛选。完整语义参见内存模型

Shared Data Block 事件由内存模型定义的 Record 表示。

本规范用以下抽象操作处理 Data Block 值:

6.2.9.1 CreateByteDataBlock ( size )

The abstract operation CreateByteDataBlock takes argument size (非负整数) and returns 返回包含 Data Block正常完成异常完成. It performs the following steps when called:

  1. size > 253 - 1,抛出 RangeError 异常。
  2. db 为由 size 字节组成的新 Data Block 值。若无法创建该 Data Block,抛出 RangeError 异常。
  3. db 的所有字节设为 0。
  4. 返回 db

6.2.9.2 CreateSharedByteDataBlock ( size )

The abstract operation CreateSharedByteDataBlock takes argument size (非负整数) and returns 返回包含 Shared Data Block正常完成异常完成. It performs the following steps when called:

  1. db 为由 size 字节组成的新 Shared Data Block 值。若无法创建该 Shared Data Block,抛出 RangeError 异常。
  2. execution 为当前 agent 的 Agent Record[[CandidateExecution]] 字段。
  3. eventsRecordexecution.[[EventsRecords]][[AgentSignifier]]AgentSignifier() 的 Agent Events Record
  4. zero 为 « 0 »。
  5. db 的每个索引 i
    1. WriteSharedMemory { [[Order]]: init, [[NoTear]]: true, [[Block]]: db, [[ByteIndex]]: i, [[ElementSize]]: 1, [[Payload]]: zero } 添加到 eventsRecord.[[EventList]]
  6. 返回 db

6.2.9.3 CopyDataBlockBytes ( toBlock, toIndex, fromBlock, fromIndex, count )

The abstract operation CopyDataBlockBytes takes arguments toBlock (Data BlockShared Data Block), toIndex (非负整数), fromBlock (Data BlockShared Data Block), fromIndex (非负整数), and count (非负整数) and returns unused. It performs the following steps when called:

  1. 断言:fromBlocktoBlock 是不同值。
  2. fromSizefromBlock 的字节数。
  3. 断言:fromIndex + countfromSize
  4. toSizetoBlock 的字节数。
  5. 断言:toIndex + counttoSize
  6. count > 0 时重复:
    1. fromBlockShared Data Block
      1. execution 为当前 agent 的 Agent Record[[CandidateExecution]] 字段。
      2. eventsRecordexecution.[[EventsRecords]][[AgentSignifier]]AgentSignifier() 的 Agent Events Record
      3. bytes 为仅有一个由非确定性选择的字节值List
      4. 注:在实现中,bytes 是底层硬件非原子读指令的结果。非确定性由内存模型语义规定,以描述弱一致性硬件的可观察行为。
      5. readEventReadSharedMemory { [[Order]]: unordered, [[NoTear]]: true, [[Block]]: fromBlock, [[ByteIndex]]: fromIndex, [[ElementSize]]: 1 }。
      6. readEvent 添加到 eventsRecord.[[EventList]]
      7. Chosen Value Record { [[Event]]: readEvent, [[ChosenValue]]: bytes } 添加到 execution.[[ChosenValues]]
      8. toBlockShared Data Block
        1. WriteSharedMemory { [[Order]]: unordered, [[NoTear]]: true, [[Block]]: toBlock, [[ByteIndex]]: toIndex, [[ElementSize]]: 1, [[Payload]]: bytes } 添加到 eventsRecord.[[EventList]]
      9. 否则,
        1. 设置 toBlock[toIndex] 为 bytes[0]。
    2. 否则,
      1. 断言:toBlock 不是 Shared Data Block
      2. 设置 toBlock[toIndex] 为 fromBlock[fromIndex]。
    3. 设置 toIndextoIndex + 1。
    4. 设置 fromIndexfromIndex + 1。
    5. 设置 countcount - 1。
  7. 返回 unused

6.2.10 PrivateElement 规范类型

PrivateElement 类型是用于规范私有类字段、方法和访问器的 Record。虽然 PrivateElement 不用 Property Descriptor,但私有字段的行为类似于不可配置、不可枚举、可写的数据属性,私有方法类似于不可配置、不可枚举、不可写的数据属性,私有访问器类似于不可配置、不可枚举访问器属性

PrivateElement 类型的值是包含 Table 9 定义字段的 Record。此类值称为 PrivateElements

Table 9: PrivateElement 字段
字段名 存在时 [[Kind]] 字段的值 含义
[[Key]] 所有 Private Name 字段、方法或访问器的名称。
[[Kind]] 所有 fieldmethodaccessor 元素类型。
[[Value]] fieldmethod 一个 ECMAScript 语言值 字段的值。
[[Get]] accessor 函数对象undefined 私有访问器的 getter。
[[Set]] accessor 函数对象undefined 私有访问器的 setter。

6.2.11 ClassFieldDefinition Record 规范类型

ClassFieldDefinition 类型是用于规范类字段的 Record

ClassFieldDefinition 类型的值是包含 Table 10 定义字段的 Record。此类值称为 ClassFieldDefinition Records

Table 10: ClassFieldDefinition Record 字段
字段名 含义
[[Name]] Private Name、字符串或符号 字段的名称。
[[Initializer]] ECMAScript 函数对象empty 字段的初始化器(如有)。

6.2.12 Private Name

Private Name 规范类型用于描述全局唯一值(即使与其他 Private Name 外观一致也不同),用于表示私有类元素(字段、方法或访问器)的键。每个 Private Name 有不可变的 [[Description]] 内部槽,为字符串。Private Name 可通过 PrivateFieldAddPrivateMethodOrAccessorAdd 安装到任意 ECMAScript 对象上,然后可用 PrivateGetPrivateSet 读取或写入。

6.2.13 ClassStaticBlockDefinition Record 规范类型

ClassStaticBlockDefinition Record 是用于封装类静态初始化块可执行代码的 Record 值。

ClassStaticBlockDefinition Record 包含 Table 11 列出的字段。

Table 11: ClassStaticBlockDefinition Record 字段
字段名 含义
[[BodyFunction]] 一个 ECMAScript 函数对象 类静态初始化时要调用的函数对象

7 抽象操作 (Abstract Operations)

这些操作不属于 ECMAScript 语言本身;它们仅在此定义,用于辅助描述 ECMAScript 语言语义。本规范其余部分还定义了其他更专业的抽象操作

7.1 类型转换 (Type Conversion)

ECMAScript 语言会按需隐式执行自动类型转换。为澄清某些结构的语义,有必要定义一组转换类抽象操作。转换抽象操作是多态的;它们可以接受任意 ECMAScript 语言类型的值。但不会与其它规范类型(specification types)一起使用。

BigInt 类型在 ECMAScript 语言中没有隐式转换;程序员必须显式调用 BigInt 以从其他类型转换值。

7.1.1 ToPrimitive ( input: 一个 ECMAScript 语言值, 可选 preferredType: stringnumber, ): 返回包含一个 ECMAScript 语言值的正常完成或一个抛出完成

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. 将参数 input 转换为非 Object 的类型。如果一个对象可以转换为多个不同的原始类型,它可利用可选提示 preferredType 来偏向该类型。 It performs the following steps when called:

  1. 如果 input 是一个 Object,则
    1. exoticToPrim 为 ? GetMethod(input, %Symbol.toPrimitive%)。
    2. 如果 exoticToPrim 不为 undefined,则
      1. 如果 preferredType 不存在,
        1. hint"default"
      2. 否则如果 preferredTypestring
        1. hint"string"
      3. 否则,
        1. 断言:preferredTypenumber
        2. hint"number"
      4. result 为 ? Call(exoticToPrim, input, « hint »)。
      5. 如果 result 不是一个 Object,返回 result
      6. 抛出 TypeError 异常。
    3. 如果 preferredType 不存在,令 preferredTypenumber
    4. 返回 ? OrdinaryToPrimitive(input, preferredType)。
  2. 返回 input
Note

当 ToPrimitive 未带 hint 被调用时,一般表现为 hint 为 number。但对象可通过定义 %Symbol.toPrimitive% 方法来覆写此行为。本规范中只有 Date(参见 21.4.4.45)和 Symbol 对象(参见 20.4.3.5)覆写默认行为。Date 在缺少 hint 时将其视为 string

7.1.1.1 OrdinaryToPrimitive ( O, hint )

The abstract operation OrdinaryToPrimitive takes arguments O (一个 Object) and hint (stringnumber) and returns 返回包含一个 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. 如果 hintstring,则
    1. methodNames 为 « "toString", "valueOf" »。
  2. 否则,
    1. methodNames 为 « "valueOf", "toString" »。
  3. 对于 methodNames 的每个元素 name,执行
    1. method 为 ? Get(O, name)。
    2. 如果 IsCallable(method) 是 true,则
      1. result 为 ? Call(method, O)。
      2. 如果 result 不是一个 Object,返回 result
  4. 抛出 TypeError 异常。

7.1.2 ToBoolean ( argument )

The abstract operation ToBoolean takes argument argument (一个 ECMAScript 语言值) and returns 一个 Boolean. 将 argument 转换为 Boolean 类型。 It performs the following steps when called:

  1. 如果 argument 是 Boolean,返回 argument
  2. 如果 argumentundefinednull+0𝔽-0𝔽NaN0 或空字符串,返回 false
  3. Normative Optional
    如果宿主是 web 浏览器或支持 [[IsHTMLDDA]] 内部槽,则
    1. 如果 argument 是 Object 且具有 [[IsHTMLDDA]] 内部槽,返回 false
  4. 返回 true

7.1.3 ToNumeric ( value )

The abstract operation ToNumeric takes argument value (一个 ECMAScript 语言值) and returns 返回包含 Number 或 BigInt 的正常完成,或抛出完成. 返回 value 转换后的 Number 或 BigInt。 It performs the following steps when called:

  1. primValue 为 ? ToPrimitive(value, number)。
  2. 如果 primValue 是 BigInt,返回 primValue
  3. 返回 ? ToNumber(primValue)。

7.1.4 ToNumber ( argument )

The abstract operation ToNumber takes argument argument (一个 ECMAScript 语言值) and returns 返回包含一个 Number 的正常完成或抛出完成. 将 argument 转换为 Number 类型。 It performs the following steps when called:

  1. 如果 argument 是 Number,返回 argument
  2. 如果 argument 是 Symbol 或 BigInt,抛出 TypeError 异常。
  3. 如果 argumentundefined,返回 NaN
  4. 如果 argumentnullfalse,返回 +0𝔽
  5. 如果 argumenttrue,返回 1𝔽
  6. 如果 argument 是 String,返回 StringToNumber(argument)。
  7. 断言:argument 是一个 Object。
  8. primValue 为 ? ToPrimitive(argument, number)。
  9. 断言:primValue 不是 Object
  10. 返回 ? ToNumber(primValue)。

7.1.4.1 应用于 String 类型的 ToNumber

抽象操作 StringToNumber 规定如何使用下列语法将一个 String 值转换为 Number 值。

Syntax

StringNumericLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt StrWhiteSpace ::: StrWhiteSpaceChar StrWhiteSpaceopt StrWhiteSpaceChar ::: WhiteSpace LineTerminator StrNumericLiteral ::: StrDecimalLiteral NonDecimalIntegerLiteral[~Sep] StrDecimalLiteral ::: StrUnsignedDecimalLiteral + StrUnsignedDecimalLiteral - StrUnsignedDecimalLiteral StrUnsignedDecimalLiteral ::: Infinity DecimalDigits[~Sep] . DecimalDigits[~Sep]opt ExponentPart[~Sep]opt . DecimalDigits[~Sep] ExponentPart[~Sep]opt DecimalDigits[~Sep] ExponentPart[~Sep]opt

未在上方显式定义的语法符号,采用数字字面量词法语法 (12.9.3) 中的定义。

Note

需要注意 StringNumericLiteralNumericLiteral 语法之间的一些差异:

7.1.4.1.1 StringToNumber ( str )

The abstract operation StringToNumber takes argument str (一个 String) and returns 一个 Number. It performs the following steps when called:

  1. literal 为 ParseText(str, StringNumericLiteral)。
  2. 如果 literal 是一个错误列表,返回 NaN
  3. 返回 literal 的 StringNumericValue。

7.1.4.1.2 运行时语义:StringNumericValue

The syntax-directed operation 运行时语义:StringNumericValue takes no arguments and returns 一个 Number.

Note

StringNumericLiteral 转换为 Number 值的整体过程与确定 NumericLiteral 的 NumericValue 类似(参见 12.9.3),但细节有所不同。

It is defined piecewise over the following productions:

StringNumericLiteral ::: StrWhiteSpaceopt
  1. 返回 +0𝔽
StringNumericLiteral ::: StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt
  1. 返回 StrNumericLiteral 的 StringNumericValue。
StrNumericLiteral ::: NonDecimalIntegerLiteral
  1. 返回 𝔽(NonDecimalIntegerLiteral 的 MV)。
StrDecimalLiteral ::: - StrUnsignedDecimalLiteral
  1. aStrUnsignedDecimalLiteral 的 StringNumericValue。
  2. 如果 a+0𝔽,返回 -0𝔽
  3. 返回 -a
StrUnsignedDecimalLiteral ::: Infinity
  1. 返回 +∞𝔽
StrUnsignedDecimalLiteral ::: DecimalDigits . DecimalDigitsopt ExponentPartopt
  1. a 为第一个 DecimalDigits 的 MV。
  2. 如果第二个 DecimalDigits 存在,则
    1. b 为第二个 DecimalDigits 的 MV。
    2. n 为第二个 DecimalDigits 的码点数量。
  3. 否则,
    1. b 为 0。
    2. n 为 0。
  4. 如果 ExponentPart 存在,令 e 为其 MV;否则令 e 为 0。
  5. 返回 RoundMVResult((a + (b × 10-n)) × 10e)。
StrUnsignedDecimalLiteral ::: . DecimalDigits ExponentPartopt
  1. bDecimalDigits 的 MV。
  2. 如果 ExponentPart 存在,令 e 为其 MV;否则令 e 为 0。
  3. nDecimalDigits 的码点数量。
  4. 返回 RoundMVResult(b × 10e - n)。
StrUnsignedDecimalLiteral ::: DecimalDigits ExponentPartopt
  1. aDecimalDigits 的 MV。
  2. 如果 ExponentPart 存在,令 e 为其 MV;否则令 e 为 0。
  3. 返回 RoundMVResult(a × 10e)。

7.1.4.1.3 RoundMVResult ( n )

The abstract operation RoundMVResult takes argument n (一个数学值) and returns 一个 Number. 以实现定义的方式将 n 转换为 Number。对本抽象操作而言,若一位数字不是 0,或其左侧与右侧存在非零数字,则该位为有效数字。此处“数学值的表示所表示的数学值”与“数学值的十进制表示”互为逆过程。 It performs the following steps when called:

  1. 如果 n 的十进制表示有不超过 20 个有效数字,返回 𝔽(n)。
  2. option1 为将 n 十进制表示中第 20 位之后的每个有效数字替换为 0 后所表示的数学值
  3. option2 为将 n 十进制表示中第 20 位之后的每个有效数字替换为 0,然后对第 20 位进位(必要时连锁进位)后所表示的数学值
  4. chosen 为实现定义地在 option1option2 中选择的其中一个。
  5. 返回 𝔽(chosen)。

7.1.5 ToIntegerOrInfinity ( argument )

The abstract operation ToIntegerOrInfinity takes argument argument (一个 ECMAScript 语言值) and returns 返回包含一个整数、+∞、- ∞ 的正常完成,或抛出完成. 将 argument 转换为其 Number 值去掉小数部分后的整数;若该 Number 值为无穷大,则转换为 +∞ 或 -∞。 It performs the following steps when called:

  1. number 为 ? ToNumber(argument)。
  2. 如果 numberNaN+0𝔽-0𝔽,返回 0。
  3. 如果 number+∞𝔽,返回 +∞。
  4. 如果 number-∞𝔽,返回 -∞。
  5. 返回 truncate((number))。
Note
𝔽(ToIntegerOrInfinity(x)) 对任意 x 都不会返回 -0𝔽。截断小数部分在将 x 转换为数学值之后执行。

7.1.6 ToInt32 ( argument )

The abstract operation ToInt32 takes argument argument (一个 ECMAScript 语言值) and returns 返回包含一个整型 Number 的正常完成或一个抛出完成. 将 argument 转换为 232 个整型 Number 值之一,范围为 𝔽(-231) 到 𝔽(231 - 1)(含)。 It performs the following steps when called:

  1. number 为 ? ToNumber(argument)。
  2. 如果 number 不是有限数或为 +0𝔽-0𝔽,返回 +0𝔽
  3. inttruncate((number))。
  4. int32bitint modulo 232
  5. 如果 int32bit ≥ 231,返回 𝔽(int32bit - 232);否则返回 𝔽(int32bit)。
Note

基于上述定义:

  • ToInt32 是幂等的:对其输出再次应用结果不变。
  • 对所有 x,ToInt32(ToUint32(x)) 与 ToInt32(x) 相同。(为保持此性质,+∞𝔽-∞𝔽 被映射为 +0𝔽。)
  • ToInt32 将 -0𝔽 映射为 +0𝔽

7.1.7 ToUint32 ( argument )

The abstract operation ToUint32 takes argument argument (一个 ECMAScript 语言值) and returns 返回包含一个整型 Number 的正常完成或一个抛出完成. 将 argument 转换为 232 个整型 Number 值之一,范围为 +0𝔽𝔽(232 - 1)(含)。 It performs the following steps when called:

  1. number 为 ? ToNumber(argument)。
  2. 如果 number 不是有限数或为 +0𝔽-0𝔽,返回 +0𝔽
  3. inttruncate((number))。
  4. int32bitint modulo 232
  5. 返回 𝔽(int32bit)。
Note

基于上述定义:

  • 步骤 5 是 ToUint32 与 ToInt32 的唯一差别。
  • ToUint32 幂等。
  • 对所有 x,ToUint32(ToInt32(x)) 与 ToUint32(x) 相同。(为保持此性质,+∞𝔽-∞𝔽 被映射为 +0𝔽。)
  • ToUint32 将 -0𝔽 映射为 +0𝔽

7.1.8 ToInt16 ( argument )

The abstract operation ToInt16 takes argument argument (一个 ECMAScript 语言值) and returns 返回包含一个整型 Number 的正常完成或抛出完成. 转换为 216 个整型 Number 之一,范围 𝔽(-215) 到 𝔽(215 - 1)。 It performs the following steps when called:

  1. number 为 ? ToNumber(argument)。
  2. 如果 number 不是有限数或为 +0𝔽-0𝔽,返回 +0𝔽
  3. inttruncate((number))。
  4. int16bitint modulo 216
  5. 如果 int16bit ≥ 215,返回 𝔽(int16bit - 216);否则返回 𝔽(int16bit)。

7.1.9 ToUint16 ( argument )

The abstract operation ToUint16 takes argument argument (一个 ECMAScript 语言值) and returns 返回包含一个整型 Number 的正常完成或抛出完成. 转换为 216 个整型 Number 之一,范围 +0𝔽𝔽(216 - 1)。 It performs the following steps when called:

  1. number 为 ? ToNumber(argument)。
  2. 如果 number 不是有限数或为 +0𝔽-0𝔽,返回 +0𝔽
  3. inttruncate((number))。
  4. int16bitint modulo 216
  5. 返回 𝔽(int16bit)。
Note

基于上述定义:

  • 在步骤 4 中把 216 代替 232ToUint32 与 ToUint16 的唯一差别。
  • ToUint16 将 -0𝔽 映射为 +0𝔽

7.1.10 ToInt8 ( argument )

The abstract operation ToInt8 takes argument argument (一个 ECMAScript 语言值) and returns 返回包含一个整型 Number 的正常完成或抛出完成. 转换为 28 个整型 Number 之一,范围 -128𝔽127𝔽。 It performs the following steps when called:

  1. number 为 ? ToNumber(argument)。
  2. 如果 number 不是有限数或为 +0𝔽-0𝔽,返回 +0𝔽
  3. inttruncate((number))。
  4. int8bitint modulo 28
  5. 如果 int8bit ≥ 27,返回 𝔽(int8bit - 28);否则返回 𝔽(int8bit)。

7.1.11 ToUint8 ( argument )

The abstract operation ToUint8 takes argument argument (一个 ECMAScript 语言值) and returns 返回包含一个整型 Number 的正常完成或抛出完成. 转换为 28 个整型 Number 之一,范围 +0𝔽255𝔽。 It performs the following steps when called:

  1. number 为 ? ToNumber(argument)。
  2. 如果 number 不是有限数或为 +0𝔽-0𝔽,返回 +0𝔽
  3. inttruncate((number))。
  4. int8bitint modulo 28
  5. 返回 𝔽(int8bit)。

7.1.12 ToUint8Clamp ( argument )

The abstract operation ToUint8Clamp takes argument argument (一个 ECMAScript 语言值) and returns 返回包含一个整型 Number 的正常完成或抛出完成. 对 argument 进行钳制并取整,结果为 28 个整型 Number 之一,范围 +0𝔽255𝔽。 It performs the following steps when called:

  1. number 为 ? ToNumber(argument)。
  2. 如果 numberNaN,返回 +0𝔽
  3. mvnumber扩展数学值
  4. clampedmv 在 0 与 255 之间钳制的结果。
  5. ffloor(clamped)。
  6. 如果 clamped < f + 0.5,返回 𝔽(f)。
  7. 如果 clamped > f + 0.5,返回 𝔽(f + 1)。
  8. 如果 f 是偶数,返回 𝔽(f);否则返回 𝔽(f + 1)。
Note

不同于大多数整数转换操作,ToUint8Clamp 会四舍五入而不是截断非整数值,它使用“round half to even”平分舍入规则,不同于 Math.round 的“round half up”。

7.1.13 ToBigInt ( argument )

The abstract operation ToBigInt takes argument argument (一个 ECMAScript 语言值) and returns 返回包含 BigInt 的正常完成或抛出完成. 将 argument 转换为 BigInt;若需要从 Number 的隐式转换则抛出。 It performs the following steps when called:

  1. prim 为 ? ToPrimitive(argument, number)。
  2. 返回 primTable 12 中对应的值。
Table 12: BigInt 转换
参数类型 结果
Undefined 抛出 TypeError 异常。
Null 抛出 TypeError 异常。
Boolean primtrue 返回 1n,若为 false 返回 0n
BigInt 返回 prim
Number 抛出 TypeError 异常。
String
  1. nStringToBigInt(prim)。
  2. 如果 nundefined,抛出 SyntaxError 异常。
  3. 返回 n
Symbol 抛出 TypeError 异常。

7.1.14 StringToBigInt ( str )

The abstract operation StringToBigInt takes argument str (一个 String) and returns 一个 BigInt 或 undefined. It performs the following steps when called:

  1. literal 为 ParseText(str, StringIntegerLiteral)。
  2. 如果 literal 是一个错误列表,返回 undefined
  3. mvliteral 的 MV。
  4. 断言:mv 是整数。
  5. 返回 (mv)。

7.1.14.1 StringIntegerLiteral 语法

StringToBigInt 使用以下语法。

Syntax

StringIntegerLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrIntegerLiteral StrWhiteSpaceopt StrIntegerLiteral ::: SignedInteger[~Sep] NonDecimalIntegerLiteral[~Sep]

7.1.14.2 运行时语义:MV

7.1.15 ToBigInt64 ( argument )

The abstract operation ToBigInt64 takes argument argument (一个 ECMAScript 语言值) and returns 返回包含 BigInt 的正常完成或抛出完成. 将 argument 转换为 264 个 BigInt 之一,范围 (-263) 到 (263 - 1)(含)。 It performs the following steps when called:

  1. n 为 ? ToBigInt(argument)。
  2. int64bit(n) modulo 264
  3. 如果 int64bit ≥ 263,返回 (int64bit - 264);否则返回 (int64bit)。

7.1.16 ToBigUint64 ( argument )

The abstract operation ToBigUint64 takes argument argument (一个 ECMAScript 语言值) and returns 返回包含 BigInt 的正常完成或抛出完成. 将 argument 转换为 264 个 BigInt 之一,范围 0(264 - 1)(含)。 It performs the following steps when called:

  1. n 为 ? ToBigInt(argument)。
  2. int64bit(n) modulo 264
  3. 返回 (int64bit)。

7.1.17 ToString ( argument )

The abstract operation ToString takes argument argument (一个 ECMAScript 语言值) and returns 返回包含一个 String 的正常完成或抛出完成. 将 argument 转换为 String 类型。 It performs the following steps when called:

  1. 如果 argument 是 String,返回 argument
  2. 如果 argument 是 Symbol,抛出 TypeError 异常。
  3. 如果 argumentundefined,返回 "undefined"
  4. 如果 argumentnull,返回 "null"
  5. 如果 argumenttrue,返回 "true"
  6. 如果 argumentfalse,返回 "false"
  7. 如果 argument 是 Number,返回 Number::toString(argument, 10)。
  8. 如果 argument 是 BigInt,返回 BigInt::toString(argument, 10)。
  9. 断言:argument 是 Object
  10. primValue 为 ? ToPrimitive(argument, string)。
  11. 断言:primValue 不是 Object
  12. 返回 ? ToString(primValue)。

7.1.18 ToObject ( argument )

The abstract operation ToObject takes argument argument (一个 ECMAScript 语言值) and returns 返回包含一个 Object 的正常完成或抛出完成. 将 argument 转换为 Object 类型。 It performs the following steps when called:

  1. 如果 argumentundefinednull,抛出 TypeError 异常。
  2. 如果 argument 是 Boolean,返回一个新 Boolean 对象,其 [[BooleanData]] 内部槽设为 argument。详见 20.3
  3. 如果 argument 是 Number,返回一个新 Number 对象,其 [[NumberData]] 设为 argument。详见 21.1
  4. 如果 argument 是 String,返回一个新 String 对象,其 [[StringData]] 设为 argument。详见 22.1
  5. 如果 argument 是 Symbol,返回一个新 Symbol 对象,其 [[SymbolData]] 设为 argument。详见 20.4
  6. 如果 argument 是 BigInt,返回一个新 BigInt 对象,其 [[BigIntData]] 设为 argument。详见 21.2
  7. 断言:argument 是一个 Object。
  8. 返回 argument

7.1.19 ToPropertyKey ( argument )

The abstract operation ToPropertyKey takes argument argument (一个 ECMAScript 语言值) and returns 返回包含一个属性键正常完成或抛出完成. 将 argument 转换为可用作属性键的值。 It performs the following steps when called:

  1. key 为 ? ToPrimitive(argument, string)。
  2. 如果 key 是 Symbol,则
    1. 返回 key
  3. 返回 ! ToString(key)。

7.1.20 ToLength ( argument )

The abstract operation ToLength takes argument argument (一个 ECMAScript 语言值) and returns 返回包含非负整型 Number 的正常完成或抛出完成. 将 argument 钳制并截断为可用于类数组对象 length 的非负整型 Number。 It performs the following steps when called:

  1. len 为 ? ToIntegerOrInfinity(argument)。
  2. 如果 len ≤ 0,返回 +0𝔽
  3. 返回 𝔽(min(len, 253 - 1))。

7.1.21 CanonicalNumericIndexString ( argument )

The abstract operation CanonicalNumericIndexString takes argument argument (一个 String) and returns 一个 Number 或 undefined. 如果 argument"-0" 或者完全匹配某个 Number 值 nToString(n),则返回该 Number 值;否则返回 undefined。 It performs the following steps when called:

  1. 如果 argument"-0",返回 -0𝔽
  2. n 为 ! ToNumber(argument)。
  3. 如果 ! ToString(n) 是 argument,返回 n
  4. 返回 undefined

规范数值字符串是对其执行 CanonicalNumericIndexString 抽象操作不返回 undefined 的任意字符串。

7.1.22 ToIndex ( value )

The abstract operation ToIndex takes argument value (一个 ECMAScript 语言值) and returns 返回包含非负整数的正常完成或抛出完成. 将 value 转换为整数,若其为非负且对应整数索引则返回该整数;否则抛出异常。 It performs the following steps when called:

  1. integer 为 ? ToIntegerOrInfinity(value)。
  2. 如果 integer 不在 0 到 253 - 1(含)内,抛出 RangeError 异常。
  3. 返回 integer

7.2 测试与比较操作 (Testing and Comparison Operations)

7.2.1 RequireObjectCoercible ( argument )

The abstract operation RequireObjectCoercible takes argument argument (一个 ECMAScript 语言值) and returns 返回包含 unused正常完成或抛出完成. 若 argument 不能通过 ToObject 转换为对象则抛出错误。 It performs the following steps when called:

  1. 如果 argumentundefinednull,抛出 TypeError 异常。
  2. 返回 unused

7.2.2 IsArray ( argument )

The abstract operation IsArray takes argument argument (一个 ECMAScript 语言值) and returns 返回包含 Boolean 的正常完成或抛出完成. It performs the following steps when called:

  1. 如果 argument 不是 Object,返回 false
  2. 如果 argument 是 Array exotic object,返回 true
  3. 如果 argument 是 Proxy exotic object,则
    1. 执行 ? ValidateNonRevokedProxy(argument)。
    2. proxyTargetargument.[[ProxyTarget]]
    3. 返回 ? IsArray(proxyTarget)。
  4. 返回 false

7.2.3 IsCallable ( argument )

The abstract operation IsCallable takes argument argument (一个 ECMAScript 语言值) and returns 一个 Boolean. 判断 argument 是否为具有 [[Call]] 内部方法的可调用函数。 It performs the following steps when called:

  1. 如果 argument 不是 Object,返回 false
  2. 如果 argument 具有 [[Call]] 内部方法,返回 true
  3. 返回 false

7.2.4 IsConstructor ( argument )

The abstract operation IsConstructor takes argument argument (一个 ECMAScript 语言值) and returns 一个 Boolean. 判断 argument 是否为具有 [[Construct]] 内部方法的函数对象。 It performs the following steps when called:

  1. 如果 argument 不是 Object,返回 false
  2. 如果 argument 具有 [[Construct]] 内部方法,返回 true
  3. 返回 false

7.2.5 IsExtensible ( O )

The abstract operation IsExtensible takes argument O (一个 Object) and returns 返回包含 Boolean 的正常完成或抛出完成. 用于判断是否可向 O 添加额外属性。 It performs the following steps when called:

  1. 返回 ? O.[[IsExtensible]]()。

7.2.6 IsRegExp ( argument )

The abstract operation IsRegExp takes argument argument (一个 ECMAScript 语言值) and returns 返回包含 Boolean 的正常完成或抛出完成. It performs the following steps when called:

  1. 如果 argument 不是 Object,返回 false
  2. matcher 为 ? Get(argument, %Symbol.match%)。
  3. 如果 matcher 不为 undefined,返回 ToBoolean(matcher)。
  4. 如果 argument[[RegExpMatcher]] 内部槽,返回 true
  5. 返回 false

7.2.7 静态语义: IsStringWellFormedUnicode ( string: 一个 String, ): 一个 Boolean

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. 将 string 视为 UTF-16 编码的代码点序列(见 6.1.4),判断其是否为 well formed UTF-16 序列。 It performs the following steps when called:

  1. lenstring 的长度。
  2. k 为 0。
  3. 循环,当 k < len
    1. cp 为 CodePointAt(string, k)。
    2. 如果 cp.[[IsUnpairedSurrogate]]true,返回 false
    3. kk + cp.[[CodeUnitCount]]
  4. 返回 true

7.2.8 SameType ( x, y )

The abstract operation SameType takes arguments x (一个 ECMAScript 语言值) and y (一个 ECMAScript 语言值) and returns 一个 Boolean. 判断两个参数是否是相同类型。 It performs the following steps when called:

  1. 如果 xundefinedyundefined,返回 true
  2. 如果 xnullynull,返回 true
  3. 如果 x 是 Boolean 且 y 是 Boolean,返回 true
  4. 如果 x 是 Numbery 是 Number,返回 true
  5. 如果 x 是 BigInty 是 BigInt,返回 true
  6. 如果 x 是 Symbol 且 y 是 Symbol,返回 true
  7. 如果 x 是 String 且 y 是 String,返回 true
  8. 如果 x 是 Objecty 是 Object,返回 true
  9. 返回 false

7.2.9 SameValue ( x, y )

The abstract operation SameValue takes arguments x (一个 ECMAScript 语言值) and y (一个 ECMAScript 语言值) and returns 一个 Boolean. 判断两个参数是否为同一值。 It performs the following steps when called:

  1. 如果 SameType(x, y) 为 false,返回 false
  2. 如果 x 是 Number,则
    1. 返回 Number::sameValue(x, y)。
  3. 返回 SameValueNonNumber(x, y)。
Note

该算法与严格相等算法不同之处在于:它将所有 NaN 视为等价,并区分 +0𝔽-0𝔽

7.2.10 SameValueZero ( x, y )

The abstract operation SameValueZero takes arguments x (一个 ECMAScript 语言值) and y (一个 ECMAScript 语言值) and returns 一个 Boolean. 判断是否为同一值(忽略 +0𝔽-0𝔽 的差别)。 It performs the following steps when called:

  1. 如果 SameType(x, y) 为 false,返回 false
  2. 如果 x 是 Number,则
    1. 返回 Number::sameValueZero(x, y)。
  3. 返回 SameValueNonNumber(x, y)。
Note

SameValueZero 与 SameValue 唯一差别是它认为 +0𝔽-0𝔽 等价。

7.2.11 SameValueNonNumber ( x, y )

The abstract operation SameValueNonNumber takes arguments x (一个 ECMAScript 语言值(非 Number)) and y (一个 ECMAScript 语言值(非 Number)) and returns 一个 Boolean. It performs the following steps when called:

  1. 断言:SameType(x, y) 为 true
  2. 如果 xundefinednull,返回 true
  3. 如果 x 是 BigInt,则
    1. 返回 BigInt::equal(x, y)。
  4. 如果 x 是 String,则
    1. 如果 xy 长度相同且相同位置的代码单元相同,返回 true;否则返回 false
  5. 如果 x 是 Boolean,则
    1. 若都为 true 或都为 false,返回 true;否则返回 false
  6. NOTE: 其他 ECMAScript 语言值按身份比较。
  7. 如果 xy,返回 true;否则返回 false
Note 1
为了阐述目的,本算法中一些分支被单独列出,即便不是必须。
Note 2
xy” 的具体含义详见 5.2.7

7.2.12 IsLessThan ( x, y, LeftFirst )

The abstract operation IsLessThan takes arguments x (一个 ECMAScript 语言值), y (一个 ECMAScript 语言值), and LeftFirst (一个 Boolean) and returns 返回包含 Boolean 或 undefined正常完成,或抛出完成. 提供 x < y 的语义,返回 truefalseundefined(表示至少一个操作数为 NaN)。LeftFirst 标志控制可能具副作用的操作执行顺序,以符合 ECMAScript 自左向右求值规则。若 LeftFirsttruex 对应的表达式位于 y 左侧;否则顺序反转并需先对 y 执行操作。 It performs the following steps when called:

  1. 如果 LeftFirsttrue,则
    1. px 为 ? ToPrimitive(x, number)。
    2. py 为 ? ToPrimitive(y, number)。
  2. 否则,
    1. NOTE: 需反转求值顺序以保持自左向右求值。
    2. py 为 ? ToPrimitive(y, number)。
    3. px 为 ? ToPrimitive(x, number)。
  3. 如果 px 是 String 且 py 是 String,则
    1. lxpx 的长度。
    2. lypy 的长度。
    3. 对每个整数 i,0 ≤ i < min(lx, ly) 递增:
      1. cxpx 索引 i 的代码单元数值。
      2. cypy 索引 i 的代码单元数值。
      3. 如果 cx < cy,返回 true
      4. 如果 cx > cy,返回 false
    4. 如果 lx < ly,返回 true;否则返回 false
  4. 否则,
    1. 如果 px 是 BigIntpy 是 String,则
      1. nyStringToBigInt(py)。
      2. 如果 nyundefined,返回 undefined
      3. 返回 BigInt::lessThan(px, ny)。
    2. 如果 px 是 String 且 py 是 BigInt,则
      1. nxStringToBigInt(px)。
      2. 如果 nxundefined,返回 undefined
      3. 返回 BigInt::lessThan(nx, py)。
    3. NOTE: 因 pxpy 是原始值,求值顺序无关。
    4. nx 为 ? ToNumeric(px)。
    5. ny 为 ? ToNumeric(py)。
    6. 如果 SameType(nx, ny) 为 true,则
      1. 如果 nx 是 Number
        1. 返回 Number::lessThan(nx, ny)。
      2. 否则,
        1. 断言:nx 是 BigInt
        2. 返回 BigInt::lessThan(nx, ny)。
    7. 断言:nx 是 BigIntny 是 Number,或 nx 是 Numberny 是 BigInt
    8. 如果 nxnyNaN,返回 undefined
    9. 如果 nx-∞𝔽ny+∞𝔽,返回 true
    10. 如果 nx+∞𝔽ny-∞𝔽,返回 false
    11. 如果 (nx) < (ny),返回 true;否则返回 false
Note 1

步骤 3 与加法运算符 + 算法 (13.15.3) 中的步骤 1.c 不同之处在于这里使用逻辑与,而非逻辑或。

Note 2

字符串比较使用 UTF-16 代码单元的简单字典序,不使用 Unicode 中更复杂的按语义等价或排序规则。因此按 Unicode 标准规范等价但不同规范化形式的字符串可能判定为不相等;含代理对的字符串按代码单元排序与按代码点排序可能不同。

7.2.13 IsLooselyEqual ( x, y )

The abstract operation IsLooselyEqual takes arguments x (一个 ECMAScript 语言值) and y (一个 ECMAScript 语言值) and returns 返回包含 Boolean 的正常完成或抛出完成. == 运算符的语义。 It performs the following steps when called:

  1. 如果 SameType(x, y) 为 true,则
    1. 返回 IsStrictlyEqual(x, y)。
  2. 如果 xnullyundefined,返回 true
  3. 如果 xundefinedynull,返回 true
  4. Normative Optional
    宿主是 web 浏览器或支持 [[IsHTMLDDA]] 内部槽
    1. x 是 Object、具有 [[IsHTMLDDA]]yundefinednull,返回 true
    2. xundefinednully 是具有 [[IsHTMLDDA]] 的 Object,返回 true
  5. 如果 x 是 Numbery 是 String,返回 ! IsLooselyEqual(x, ! ToNumber(y))。
  6. 如果 x 是 String 且 y 是 Number,返回 ! IsLooselyEqual(! ToNumber(x), y)。
  7. 如果 x 是 BigInty 是 String,则
    1. nStringToBigInt(y)。
    2. 如果 nundefined,返回 false
    3. 返回 ! IsLooselyEqual(x, n)。
  8. 如果 x 是 String 且 y 是 BigInt,返回 ! IsLooselyEqual(y, x)。
  9. 如果 x 是 Boolean,返回 ! IsLooselyEqual(! ToNumber(x), y)。
  10. 如果 y 是 Boolean,返回 ! IsLooselyEqual(x, ! ToNumber(y))。
  11. 如果 x 是 String / Number / BigInt / Symbol 且 y 是 Object,返回 ! IsLooselyEqual(x, ? ToPrimitive(y))。
  12. 如果 x 是 Objecty 是 String / Number / BigInt / Symbol,返回 ! IsLooselyEqual(? ToPrimitive(x), y)。
  13. 如果 (x BigInt 且 y Number) 或 (x Number 且 y BigInt),则
    1. x有限y有限,返回 false
    2. (x) = (y),返回 true;否则返回 false
  14. 返回 false

7.2.14 IsStrictlyEqual ( x, y )

The abstract operation IsStrictlyEqual takes arguments x (一个 ECMAScript 语言值) and y (一个 ECMAScript 语言值) and returns 一个 Boolean. === 运算符的语义。 It performs the following steps when called:

  1. 如果 SameType(x, y) 为 false,返回 false
  2. 如果 x 是 Number,则
    1. 返回 Number::equal(x, y)。
  3. 返回 SameValueNonNumber(x, y)。
Note

该算法与 SameValue 算法在带符号零和 NaN 的处理上不同。

7.3 对象操作 (Operations on Objects)

7.3.1 MakeBasicObject ( internalSlotsList )

The abstract operation MakeBasicObject takes argument internalSlotsList (一个内部槽名称的 List) and returns 一个 Object. 是所有算法创建 ECMAScript 对象(普通或特殊)的基础,它抽出创建所有对象的通用步骤并集中化对象创建。 It performs the following steps when called:

  1. internalSlotsList 设为其与 « [[PrivateElements]] » 的列表拼接
  2. obj 为一个新创建的对象,对 internalSlotsList 中每个名称建一个内部槽。
  3. NOTE: 如 对象的内部方法与内部槽 所述,除非另有说明,每个内部槽初始值为 undefined
  4. 设置 obj.[[PrivateElements]] 为一个新的空 List
  5. obj 的基本内部方法设为 10.1 指定的普通对象默认定义。
  6. 断言:若调用者不会同时覆写 obj[[GetPrototypeOf]][[SetPrototypeOf]],则 internalSlotsList 包含 [[Prototype]]
  7. 断言:若调用者不会全部覆写 obj[[SetPrototypeOf]][[IsExtensible]][[PreventExtensions]],则 internalSlotsList 包含 [[Extensible]]
  8. 如果 internalSlotsList 包含 [[Extensible]],设 obj.[[Extensible]]true
  9. 返回 obj
Note

在本规范中,特殊对象(exotic objects)通过如 ArrayCreateBoundFunctionCreate抽象操作创建:先调用 MakeBasicObject 得到基础对象,再覆写其部分或全部内部方法。为封装特殊对象创建,其基本内部方法不会在这些操作之外被修改。

7.3.2 Get ( O, P )

The abstract operation Get takes arguments O (一个 Object) and P (一个属性键) and returns 返回包含一个 ECMAScript 语言值正常完成或抛出完成. 用于获取对象特定属性的值。 It performs the following steps when called:

  1. 返回 ? O.[[Get]](P, O)。

7.3.3 GetV ( V, P )

The abstract operation GetV takes arguments V (一个 ECMAScript 语言值) and P (一个属性键) and returns 返回包含一个 ECMAScript 语言值正常完成或抛出完成. 用于获取一个 ECMAScript 语言值特定属性的值;若该值不是对象,则通过类型对应的包装对象执行属性查找。 It performs the following steps when called:

  1. O 为 ? ToObject(V)。
  2. 返回 ? O.[[Get]](P, V)。

7.3.4 Set ( O, P, V, Throw )

The abstract operation Set takes arguments O (一个 Object), P (一个属性键), V (一个 ECMAScript 语言值), and Throw (一个 Boolean) and returns 返回包含 unused正常完成或抛出完成. 设置对象特定属性的值,V 是新值。 It performs the following steps when called:

  1. success 为 ? O.[[Set]](P, V, O)。
  2. successfalseThrowtrue,抛出 TypeError
  3. 返回 unused

7.3.5 CreateDataProperty ( O, P, V )

The abstract operation CreateDataProperty takes arguments O (一个 Object), P (一个属性键), and V (一个 ECMAScript 语言值) and returns 返回包含 Boolean 的正常完成或抛出完成. 创建对象的一个新的自身属性。 It performs the following steps when called:

  1. newDesc 为 PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }。
  2. 返回 ? O.[[DefineOwnProperty]](P, newDesc)。
Note

此操作创建的属性特性与语言赋值运算符新建属性时的默认特性相同。通常该属性不存在;若已存在且不可配置,或 O 不可扩展,则 [[DefineOwnProperty]] 返回 false

7.3.6 CreateDataPropertyOrThrow ( O, P, V )

The abstract operation CreateDataPropertyOrThrow takes arguments O (一个 Object), P (一个属性键), and V (一个 ECMAScript 语言值) and returns 返回包含 unused正常完成或抛出完成. 创建对象一个新的自身属性。如果该属性更新无法执行则抛出 TypeError。 It performs the following steps when called:

  1. success 为 ? CreateDataProperty(O, P, V)。
  2. successfalse,抛出 TypeError
  3. 返回 unused
Note

CreateDataProperty 类似,但失败时抛出异常。

7.3.7 CreateNonEnumerableDataPropertyOrThrow ( O, P, V )

The abstract operation CreateNonEnumerableDataPropertyOrThrow takes arguments O (一个 Object), P (一个属性键), and V (一个 ECMAScript 语言值) and returns unused. 创建一个新的不可枚举自身数据属性普通对象)。 It performs the following steps when called:

  1. 断言:O 是可扩展、普通对象,且无不可配置属性。
  2. newDesc 为 PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }。
  3. 执行 ! DefinePropertyOrThrow(O, P, newDesc)。
  4. 返回 unused
Note

特性与赋值运算符默认值相同,唯独 [[Enumerable]]false

7.3.8 DefinePropertyOrThrow ( O, P, desc )

The abstract operation DefinePropertyOrThrow takes arguments O (一个 Object), P (一个属性键), and desc (一个 Property Descriptor) and returns 返回包含 unused正常完成或抛出完成. 以会在失败时抛出 TypeError 的方式调用对象的 [[DefineOwnProperty]]。 It performs the following steps when called:

  1. success 为 ? O.[[DefineOwnProperty]](P, desc)。
  2. successfalse,抛出 TypeError
  3. 返回 unused

7.3.9 DeletePropertyOrThrow ( O, P )

The abstract operation DeletePropertyOrThrow takes arguments O (一个 Object) and P (一个属性键) and returns 返回包含 unused正常完成或抛出完成. 移除对象的指定自身属性;若属性不可配置则抛出异常。 It performs the following steps when called:

  1. success 为 ? O.[[Delete]](P)。
  2. successfalse,抛出 TypeError
  3. 返回 unused

7.3.10 GetMethod ( V, P )

The abstract operation GetMethod takes arguments V (一个 ECMAScript 语言值) and P (一个属性键) and returns 返回包含函数对象undefined正常完成,或抛出完成. 获取一个 ECMAScript 语言值的指定属性值,并期望其为函数。 It performs the following steps when called:

  1. func 为 ? GetV(V, P)。
  2. 如果 funcundefinednull,返回 undefined
  3. 如果 IsCallable(func) 为 false,抛出 TypeError
  4. 返回 func

7.3.11 HasProperty ( O, P )

The abstract operation HasProperty takes arguments O (一个 Object) and P (一个属性键) and returns 返回包含 Boolean 的正常完成或抛出完成. 判断对象是否具有指定键的属性(自身或继承)。 It performs the following steps when called:

  1. 返回 ? O.[[HasProperty]](P)。

7.3.12 HasOwnProperty ( O, P )

The abstract operation HasOwnProperty takes arguments O (一个 Object) and P (一个属性键) and returns 返回包含 Boolean 的正常完成或抛出完成. 判断对象是否具有指定键的自身属性。 It performs the following steps when called:

  1. desc 为 ? O.[[GetOwnProperty]](P)。
  2. 如果 descundefined,返回 false
  3. 返回 true

7.3.13 Call ( F: 一个 ECMAScript 语言值, V: 一个 ECMAScript 语言值, 可选 argumentsList: 一个 ECMAScript 语言值的 List, ): 返回包含一个 ECMAScript 语言值的正常完成或抛出完成

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. 调用函数对象[[Call]] 内部方法。F函数对象Vthis 值,argumentsList 为传递的参数列表。若 argumentsList 不存在,使用新的空 List。 It performs the following steps when called:

  1. argumentsList 不存在,设其为新空 List
  2. IsCallable(F) 为 false,抛出 TypeError
  3. 返回 ? F.[[Call]](V, argumentsList)。

7.3.14 Construct ( F: 一个 constructor, 可选 argumentsList: ECMAScript 语言值 List, 可选 newTarget: 一个 constructor, ): 返回包含一个 Object 的正常完成或抛出完成

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. 调用函数对象[[Construct]] 内部方法。argumentsListnewTarget 为对应参数;若 argumentsList 缺省,用新空 List;若 newTarget 缺省,用 F。 It performs the following steps when called:

  1. newTarget 不存在,设为 F
  2. argumentsList 不存在,设为新空 List
  3. 返回 ? F.[[Construct]](argumentsList, newTarget)。
Note

newTarget 不存在,等价于:new F(...argumentsList)

7.3.15 SetIntegrityLevel ( O, level )

The abstract operation SetIntegrityLevel takes arguments O (一个 Object) and level (sealedfrozen) and returns 返回包含 Boolean 的正常完成或抛出完成. 固定对象自身属性集合。 It performs the following steps when called:

  1. status 为 ? O.[[PreventExtensions]]()。
  2. statusfalse,返回 false
  3. keys 为 ? O.[[OwnPropertyKeys]]()。
  4. 如果 levelsealed,则
    1. keys 中每个 k
      1. 执行 ? DefinePropertyOrThrow(O, k, PropertyDescriptor { [[Configurable]]: false })。
  5. 否则,
    1. 断言:levelfrozen
    2. keys 中每个 k
      1. currentDesc 为 ? O.[[GetOwnProperty]](k)。
      2. currentDesc 不为 undefined,则
        1. 如果 IsAccessorDescriptor(currentDesc) 为 true
          1. desc 为 PropertyDescriptor { [[Configurable]]: false }。
        2. 否则,
          1. desc 为 PropertyDescriptor { [[Configurable]]: false, [[Writable]]: false }。
        3. 执行 ? DefinePropertyOrThrow(O, k, desc)。
  6. 返回 true

7.3.16 TestIntegrityLevel ( O, level )

The abstract operation TestIntegrityLevel takes arguments O (一个 Object) and level (sealedfrozen) and returns 返回包含 Boolean 的正常完成或抛出完成. 判断对象自身属性集合是否已固定。 It performs the following steps when called:

  1. extensible 为 ? IsExtensible(O)。
  2. extensibletrue,返回 false
  3. NOTE: 若对象可扩展,不检查属性。
  4. keys 为 ? O.[[OwnPropertyKeys]]()。
  5. keys 中每个 k
    1. currentDesc 为 ? O.[[GetOwnProperty]](k)。
    2. currentDesc 不为 undefined,则
      1. currentDesc.[[Configurable]]true,返回 false
      2. levelfrozenIsDataDescriptor(currentDesc) 为 true,则
        1. currentDesc.[[Writable]]true,返回 false
  6. 返回 true

7.3.17 CreateArrayFromList ( elements )

The abstract operation CreateArrayFromList takes argument elements (一个 ECMAScript 语言值List) and returns 一个 Array. 创建一个其元素由 elements 提供的数组。 It performs the following steps when called:

  1. array 为 ! ArrayCreate(0)。
  2. n 为 0。
  3. elements 中每个 e
    1. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(n)), e)。
    2. nn + 1。
  4. 返回 array

7.3.18 LengthOfArrayLike ( obj )

The abstract operation LengthOfArrayLike takes argument obj (一个 Object) and returns 返回包含非负整数的正常完成或抛出完成. 返回类数组对象 "length" 属性的值。 It performs the following steps when called:

  1. 返回 (? ToLength(? Get(obj, "length"))).

类数组对象 指此操作能正常完成的任意对象。

Note 1
通常类数组对象也具有一些整型索引属性,但这不是定义要求。
Note 2
Array 和 String 对象是类数组对象的例子。

7.3.19 CreateListFromArrayLike ( obj: 一个 ECMAScript 语言值, 可选 validElementTypes: allproperty-key, ): 返回包含 ECMAScript 语言值 List 的正常完成或抛出完成

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. 创建一个 List,其元素由 obj 的按索引属性提供;validElementTypes 指定允许的元素类型。 It performs the following steps when called:

  1. validElementTypes 不存在,设为 all
  2. obj 不是 Object,抛出 TypeError
  3. len 为 ? LengthOfArrayLike(obj)。
  4. list 为新空 List
  5. index 为 0。
  6. index < len
    1. indexName 为 ! ToString(𝔽(index))。
    2. next 为 ? Get(obj, indexName)。
    3. validElementTypesproperty-keynext 不是属性键,抛出 TypeError
    4. next 附加到 list
    5. indexindex + 1。
  7. 返回 list

7.3.20 Invoke ( V: 一个 ECMAScript 语言值, P: 一个属性键, 可选 argumentsList: ECMAScript 语言值 List, ): 返回包含一个 ECMAScript 语言值的正常完成或抛出完成

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. 调用一个 ECMAScript 语言值的方法属性,V 既作为查找点又作为 this 值。argumentsList 为传入参数,缺省用空 List。 It performs the following steps when called:

  1. argumentsList 不存在,设为新空 List
  2. func 为 ? GetV(V, P)。
  3. 返回 ? Call(func, V, argumentsList)。

7.3.21 OrdinaryHasInstance ( C, O )

The abstract operation OrdinaryHasInstance takes arguments C (一个 ECMAScript 语言值) and O (一个 ECMAScript 语言值) and returns 返回包含 Boolean 的正常完成或抛出完成. 实现默认算法:判断 O 是否继承自 C 提供的实例继承路径。 It performs the following steps when called:

  1. IsCallable(C) 为 false,返回 false
  2. C[[BoundTargetFunction]] 内部槽,则
    1. BCC.[[BoundTargetFunction]]
    2. 返回 ? InstanceofOperator(O, BC)。
  3. O 不是 Object,返回 false
  4. P 为 ? Get(C, "prototype")。
  5. P 不是 Object,抛出 TypeError
  6. 循环:
    1. O 为 ? O.[[GetPrototypeOf]]()。
    2. Onull,返回 false
    3. SameValue(P, O) 为 true,返回 true

7.3.22 SpeciesConstructor ( O, defaultConstructor )

The abstract operation SpeciesConstructor takes arguments O (一个 Object) and defaultConstructor (一个 constructor) and returns 返回包含 constructor 的正常完成或抛出完成. 获取用于创建从 O 派生的新对象的构造函数;若从 O 开始找不到 %Symbol.species% 属性则使用 defaultConstructor。 It performs the following steps when called:

  1. C 为 ? Get(O, "constructor")。
  2. Cundefined,返回 defaultConstructor
  3. C 不是 Object,抛出 TypeError
  4. S 为 ? Get(C, %Symbol.species%)。
  5. Sundefinednull,返回 defaultConstructor
  6. IsConstructor(S) 为 true,返回 S
  7. 抛出 TypeError

7.3.23 EnumerableOwnProperties ( O, kind )

The abstract operation EnumerableOwnProperties takes arguments O (一个 Object) and kind (key, value, 或 key+value) and returns 返回包含 ECMAScript 语言值 List正常完成或抛出完成. It performs the following steps when called:

  1. ownKeys 为 ? O.[[OwnPropertyKeys]]()。
  2. results 为新空 List
  3. ownKeys 中每个 key
    1. 如果 key 是 String,则
      1. desc 为 ? O.[[GetOwnProperty]](key)。
      2. desc 不为 undefineddesc.[[Enumerable]]true,则
        1. 如果 kindkey
          1. key 加入 results
        2. 否则,
          1. value 为 ? Get(O, key)。
          2. kindvalue
            1. value 加入 results
          3. 否则,
            1. 断言:kindkey+value
            2. entryCreateArrayFromListkey, value »)。
            3. entry 加入 results
  4. 返回 results

7.3.24 GetFunctionRealm ( obj )

The abstract operation GetFunctionRealm takes argument obj (一个函数对象) and returns 返回包含 Realm Record正常完成或抛出完成. It performs the following steps when called:

  1. obj[[Realm]] 内部槽,
    1. 返回 obj.[[Realm]]
  2. obj 是绑定函数特殊对象
    1. boundTargetFunctionobj.[[BoundTargetFunction]]
    2. 返回 ? GetFunctionRealm(boundTargetFunction)。
  3. obj 是 Proxy 特殊对象
    1. 执行 ? ValidateNonRevokedProxy(obj)。
    2. proxyTargetobj.[[ProxyTarget]]
    3. 断言:proxyTarget函数对象
    4. 返回 ? GetFunctionRealm(proxyTarget)。
  4. 返回当前 Realm Record
Note

仅当 obj 是无 [[Realm]] 内部槽的非标准函数特殊对象时才会到达步骤 4

7.3.25 CopyDataProperties ( target, source, excludedItems )

The abstract operation CopyDataProperties takes arguments target (一个 Object), source (一个 ECMAScript 语言值), and excludedItems (一个属性键List) and returns 返回包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. 如果 sourceundefinednull,返回 unused
  2. from 为 ! ToObject(source)。
  3. keys 为 ? from.[[OwnPropertyKeys]]()。
  4. keys 中每个 nextKey
    1. excludedfalse
    2. excludedItems 中每个 e
      1. SameValue(e, nextKey) 为 true
        1. excludedtrue
    3. excludedfalse,则
      1. desc 为 ? from.[[GetOwnProperty]](nextKey)。
      2. desc 不为 undefineddesc.[[Enumerable]]true
        1. propValue 为 ? Get(from, nextKey)。
        2. 执行 ! CreateDataPropertyOrThrow(target, nextKey, propValue)。
  5. 返回 unused
Note

此处的 target 总是新创建且在抛错情况下不可被直接访问。

7.3.26 PrivateElementFind ( O, P )

The abstract operation PrivateElementFind takes arguments O (一个 Object) and P (一个 Private Name) and returns 一个 PrivateElementempty. It performs the following steps when called:

  1. 如果 O.[[PrivateElements]] 包含 PrivateElement pepe.[[Key]]P
    1. 返回 pe
  2. 返回 empty

7.3.27 PrivateFieldAdd ( O, P, value )

The abstract operation PrivateFieldAdd takes arguments O (一个 Object), P (一个 Private Name), and value (一个 ECMAScript 语言值) and returns 返回包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. 宿主是 web 浏览器,
    1. 执行 ? HostEnsureCanAddPrivateElement(O)。
  2. entryPrivateElementFind(O, P)。
  3. entry 不为 empty,抛出 TypeError
  4. PrivateElement { [[Key]]: P, [[Kind]]: field, [[Value]]: value } 附加到 O.[[PrivateElements]]
  5. 返回 unused

7.3.28 PrivateMethodOrAccessorAdd ( O, method )

The abstract operation PrivateMethodOrAccessorAdd takes arguments O (一个 Object) and method (一个 PrivateElement) and returns 返回包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. 断言:method.[[Kind]]methodaccessor
  2. 宿主是 web 浏览器,
    1. 执行 ? HostEnsureCanAddPrivateElement(O)。
  3. entryPrivateElementFind(O, method.[[Key]])。
  4. entry 不为 empty,抛出 TypeError
  5. method 附加到 O.[[PrivateElements]]
  6. 返回 unused
Note

私有方法与访问器的值在实例之间共享,不会为每个实例复制。

7.3.29 HostEnsureCanAddPrivateElement ( O )

The host-defined abstract operation HostEnsureCanAddPrivateElement takes argument O (一个 Object) and returns 返回包含 unused正常完成或抛出完成. 允许宿主环境阻止某些宿主定义特殊对象添加私有元素。

实现需符合:

默认实现为返回 NormalCompletion(unused)。

仅由作为 web 浏览器的 ECMAScript 宿主调用。

7.3.30 PrivateGet ( O, P )

The abstract operation PrivateGet takes arguments O (一个 Object) and P (一个 Private Name) and returns 返回包含一个 ECMAScript 语言值正常完成或抛出完成. It performs the following steps when called:

  1. entryPrivateElementFind(O, P)。
  2. entryempty,抛出 TypeError
  3. entry.[[Kind]]fieldmethod
    1. 返回 entry.[[Value]]
  4. 断言:entry.[[Kind]]accessor
  5. entry.[[Get]]undefined,抛出 TypeError
  6. getterentry.[[Get]]
  7. 返回 ? Call(getter, O)。

7.3.31 PrivateSet ( O, P, value )

The abstract operation PrivateSet takes arguments O (一个 Object), P (一个 Private Name), and value (一个 ECMAScript 语言值) and returns 返回包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. entryPrivateElementFind(O, P)。
  2. entryempty,抛出 TypeError
  3. entry.[[Kind]]field,则
    1. entry.[[Value]]value
  4. 否则如果 entry.[[Kind]]method
    1. 抛出 TypeError
  5. 否则,
    1. 断言:entry.[[Kind]]accessor
    2. entry.[[Set]]undefined,抛出 TypeError
    3. setterentry.[[Set]]
    4. 执行 ? Call(setter, O, « value »)。
  6. 返回 unused

7.3.32 DefineField ( receiver, fieldRecord )

The abstract operation DefineField takes arguments receiver (一个 Object) and fieldRecord (一个 ClassFieldDefinition Record) and returns 返回包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. fieldNamefieldRecord.[[Name]]
  2. initializerfieldRecord.[[Initializer]]
  3. 如果 initializer 不是 empty
    1. initValue 为 ? Call(initializer, receiver)。
  4. 否则,
    1. initValueundefined
  5. fieldNamePrivate Name
    1. 执行 ? PrivateFieldAdd(receiver, fieldName, initValue)。
  6. 否则,
    1. 断言:fieldName属性键
    2. 执行 ? CreateDataPropertyOrThrow(receiver, fieldName, initValue)。
  7. 返回 unused

7.3.33 InitializeInstanceElements ( O, constructor )

The abstract operation InitializeInstanceElements takes arguments O (一个 Object) and constructor (一个 ECMAScript 函数对象) and returns 返回包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. methodsconstructor.[[PrivateMethods]]
  2. methods 中每个 PrivateElement method
    1. 执行 ? PrivateMethodOrAccessorAdd(O, method)。
  3. fieldsconstructor.[[Fields]]
  4. fields 中每个 fieldRecord
    1. 执行 ? DefineField(O, fieldRecord)。
  5. 返回 unused

7.3.34 AddValueToKeyedGroup ( groups, key, value )

The abstract operation AddValueToKeyedGroup takes arguments groups (一个包含 [[Key]] (ECMAScript 语言值) 与 [[Elements]] (值 List) 字段的 Record List), key (一个 ECMAScript 语言值), and value (一个 ECMAScript 语言值) and returns unused. It performs the following steps when called:

  1. groups 中每个 Record { [[Key]], [[Elements]] } g
    1. SameValue(g.[[Key]], key) 为 true,则
      1. 断言:恰有一个元素符合。
      2. value 加入 g.[[Elements]]
      3. 返回 unused
  2. groupRecord { [[Key]]: key, [[Elements]]: « value » }。
  3. group 加入 groups
  4. 返回 unused

7.3.35 GroupBy ( items, callback, keyCoercion )

The abstract operation GroupBy takes arguments items (一个 ECMAScript 语言值), callback (一个 ECMAScript 语言值), and keyCoercion (propertycollection) and returns 返回包含带 [[Key]][[Elements]] 字段的 Record List正常完成,或抛出完成. It performs the following steps when called:

  1. 执行 ? RequireObjectCoercible(items)。
  2. IsCallable(callback) 为 false,抛出 TypeError
  3. groups 为新空 List
  4. iteratorRecord 为 ? GetIterator(items, sync)。
  5. k 为 0。
  6. 循环:
    1. k ≥ 253 - 1,则
      1. errorThrowCompletion(新建 TypeError 对象)。
      2. 返回 ? IteratorClose(iteratorRecord, error)。
    2. next 为 ? IteratorStepValue(iteratorRecord)。
    3. nextdone
      1. 返回 groups
    4. valuenext
    5. keyCompletion(Call(callback, undefined, « value, 𝔽(k) »))。
    6. IfAbruptCloseIterator(key, iteratorRecord)。
    7. keyCoercionproperty,则
      1. keyCompletion(ToPropertyKey(key))。
      2. IfAbruptCloseIterator(key, iteratorRecord)。
    8. 否则,
      1. 断言:keyCoercioncollection
      2. keyCanonicalizeKeyedCollectionKey(key)。
    9. 执行 AddValueToKeyedGroup(groups, key, value)。
    10. kk + 1。

7.3.36 SetterThatIgnoresPrototypeProperties ( thisValue, home, p, v )

The abstract operation SetterThatIgnoresPrototypeProperties takes arguments thisValue (一个 ECMAScript 语言值), home (一个 Object), p (一个属性键), and v (一个 ECMAScript 语言值) and returns 返回包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. 如果 thisValue 不是 Object
    1. 抛出 TypeError
  2. 如果 SameValue(thisValue, home) 为 true
    1. NOTE: 此处抛出模拟在严格模式下给 home 不可写数据属性赋值。
    2. 抛出 TypeError
  3. desc 为 ? thisValue.[[GetOwnProperty]](p)。
  4. descundefined
    1. 执行 ? CreateDataPropertyOrThrow(thisValue, p, v)。
  5. 否则,
    1. 执行 ? Set(thisValue, p, v, true)。
  6. 返回 unused

7.4 迭代器对象操作 (Operations on Iterator Objects)

参见通用迭代接口 (27.1)。

7.4.1 Iterator Records

Iterator Record 是一个 Record,用于封装迭代器或异步迭代器及其 next 方法。

Iterator Record 拥有 Table 13 所列字段。

Table 13: Iterator Record 字段
字段名 含义
[[Iterator]] 一个 Object 符合迭代器或异步迭代器接口的对象。
[[NextMethod]] 一个 ECMAScript 语言值 [[Iterator]] 对象的 next 方法。
[[Done]] 一个 Boolean 迭代器是否已完成或被关闭。

7.4.2 GetIteratorDirect ( obj )

The abstract operation GetIteratorDirect takes argument obj (一个 Object) and returns 返回包含 Iterator Record正常完成或抛出完成. It performs the following steps when called:

  1. nextMethod 为 ? Get(obj, "next")。
  2. iteratorRecordIterator Record { [[Iterator]]: obj, [[NextMethod]]: nextMethod, [[Done]]: false }。
  3. 返回 iteratorRecord

7.4.3 GetIteratorFromMethod ( obj, method )

The abstract operation GetIteratorFromMethod takes arguments obj (一个 ECMAScript 语言值) and method (一个函数对象) and returns 返回包含 Iterator Record正常完成或抛出完成. It performs the following steps when called:

  1. iterator 为 ? Call(method, obj)。
  2. iterator 不是 Object,抛出 TypeError
  3. 返回 ? GetIteratorDirect(iterator)。

7.4.4 GetIterator ( obj, kind )

The abstract operation GetIterator takes arguments obj (一个 ECMAScript 语言值) and kind (syncasync) and returns 返回包含 Iterator Record正常完成或抛出完成. It performs the following steps when called:

  1. kindasync,则
    1. method 为 ? GetMethod(obj, %Symbol.asyncIterator%)。
    2. methodundefined,则
      1. syncMethod 为 ? GetMethod(obj, %Symbol.iterator%)。
      2. syncMethodundefined,抛出 TypeError
      3. syncIteratorRecord 为 ? GetIteratorFromMethod(obj, syncMethod)。
      4. 返回 CreateAsyncFromSyncIterator(syncIteratorRecord)。
  2. 否则,
    1. method 为 ? GetMethod(obj, %Symbol.iterator%)。
  3. methodundefined,抛出 TypeError
  4. 返回 ? GetIteratorFromMethod(obj, method)。

7.4.5 GetIteratorFlattenable ( obj, primitiveHandling )

The abstract operation GetIteratorFlattenable takes arguments obj (一个 ECMAScript 语言值) and primitiveHandling (iterate-string-primitivesreject-primitives) and returns 返回包含 Iterator Record正常完成或抛出完成. It performs the following steps when called:

  1. obj 不是 Object,则
    1. primitiveHandlingreject-primitives,抛出 TypeError
    2. 断言:primitiveHandlingiterate-string-primitives
    3. obj 不是 String,抛出 TypeError
  2. method 为 ? GetMethod(obj, %Symbol.iterator%)。
  3. methodundefined
    1. iteratorobj
  4. 否则,
    1. iterator 为 ? Call(method, obj)。
  5. iterator 不是 Object,抛出 TypeError
  6. 返回 ? GetIteratorDirect(iterator)。

7.4.6 IteratorNext ( iteratorRecord: 一个 Iterator Record, 可选 value: 一个 ECMAScript 语言值, ): 返回包含一个 Object 的正常完成或抛出完成

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

  1. 如果 value 不存在,
    1. resultCompletion(Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]))。
  2. 否则,
    1. resultCompletion(Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « value »))。
  3. result 是 throw completion,
    1. iteratorRecord.[[Done]]true
    2. 返回 ? result
  4. result 为 ! result
  5. result 不是 Object
    1. iteratorRecord.[[Done]]true
    2. 抛出 TypeError
  6. 返回 result

7.4.7 IteratorComplete ( iteratorResult )

The abstract operation IteratorComplete takes argument iteratorResult (一个 Object) and returns 返回包含 Boolean 的正常完成或抛出完成. It performs the following steps when called:

  1. 返回 ToBoolean(? Get(iteratorResult, "done"))。

7.4.8 IteratorValue ( iteratorResult )

The abstract operation IteratorValue takes argument iteratorResult (一个 Object) and returns 返回包含一个 ECMAScript 语言值正常完成或抛出完成. It performs the following steps when called:

  1. 返回 ? Get(iteratorResult, "value")。

7.4.9 IteratorStep ( iteratorRecord )

The abstract operation IteratorStep takes argument iteratorRecord (一个 Iterator Record) and returns 返回包含一个 Object 或 done正常完成或抛出完成. 调用 iteratorRecord.[[NextMethod]] 请求下一个值;若迭代结束返回 done,否则返回 IteratorResult 对象。 It performs the following steps when called:

  1. result 为 ? IteratorNext(iteratorRecord)。
  2. doneCompletion(IteratorComplete(result))。
  3. done 是 throw completion,
    1. iteratorRecord.[[Done]]true
    2. 返回 ? done
  4. done 为 ! done
  5. donetrue
    1. iteratorRecord.[[Done]]true
    2. 返回 done
  6. 返回 result

7.4.10 IteratorStepValue ( iteratorRecord )

The abstract operation IteratorStepValue takes argument iteratorRecord (一个 Iterator Record) and returns 返回包含 ECMAScript 语言值done正常完成,或抛出完成. 与 IteratorStep 类似,但若有值则直接返回值,否则 done。 It performs the following steps when called:

  1. result 为 ? IteratorStep(iteratorRecord)。
  2. resultdone
    1. 返回 done
  3. valueCompletion(IteratorValue(result))。
  4. value 是 throw completion,
    1. iteratorRecord.[[Done]]true
  5. 返回 ? value

7.4.11 IteratorClose ( iteratorRecord, completion )

The abstract operation IteratorClose takes arguments iteratorRecord (一个 Iterator Record) and completion (一个 Completion Record) and returns 一个 Completion Record. 通知迭代器执行其完成状态下的收尾动作。 It performs the following steps when called:

  1. 断言:iteratorRecord.[[Iterator]] 是 Object
  2. iteratoriteratorRecord.[[Iterator]]
  3. innerResultCompletion(GetMethod(iterator, "return"))。
  4. innerResult 是 normal completion,
    1. returninnerResult.[[Value]]
    2. returnundefined,返回 ? completion
    3. innerResultCompletion(Call(return, iterator))。
  5. completion 是 throw completion,返回 ? completion
  6. innerResult 是 throw completion,返回 ? innerResult
  7. innerResult.[[Value]] 不是 Object,抛出 TypeError
  8. 返回 ? completion

7.4.12 IfAbruptCloseIterator ( value, iteratorRecord )

IfAbruptCloseIterator 是使用 Iterator Record 相关步骤的简写。形如:

  1. IfAbruptCloseIterator(value, iteratorRecord)。

等价于:

  1. 断言:valueCompletion Record
  2. value 是 abrupt completion,返回 ? IteratorClose(iteratorRecord, value)。
  3. 否则,设 value 为 ! value

7.4.13 AsyncIteratorClose ( iteratorRecord, completion )

The abstract operation AsyncIteratorClose takes arguments iteratorRecord (一个 Iterator Record) and completion (一个 Completion Record) and returns 一个 Completion Record. 通知异步迭代器执行其完成状态下的收尾动作。 It performs the following steps when called:

  1. 断言:iteratorRecord.[[Iterator]] 是 Object
  2. iteratoriteratorRecord.[[Iterator]]
  3. innerResultCompletion(GetMethod(iterator, "return"))。
  4. innerResult 是 normal completion,
    1. returninnerResult.[[Value]]
    2. returnundefined,返回 ? completion
    3. innerResultCompletion(Call(return, iterator))。
    4. innerResult 是 normal completion,设其为 Completion(Await(innerResult.[[Value]]))。
  5. completion 是 throw completion,返回 ? completion
  6. innerResult 是 throw completion,返回 ? innerResult
  7. innerResult.[[Value]] 不是 Object,抛出 TypeError
  8. 返回 ? completion

7.4.14 CreateIteratorResultObject ( value, done )

The abstract operation CreateIteratorResultObject takes arguments value (一个 ECMAScript 语言值) and done (一个 Boolean) and returns 一个符合 IteratorResult 接口的 Object. 创建一个符合 IteratorResult 接口的对象。 It performs the following steps when called:

  1. objOrdinaryObjectCreate(%Object.prototype%)。
  2. 执行 ! CreateDataPropertyOrThrow(obj, "value", value)。
  3. 执行 ! CreateDataPropertyOrThrow(obj, "done", done)。
  4. 返回 obj

7.4.15 CreateListIteratorRecord ( list )

The abstract operation CreateListIteratorRecord takes argument list (一个 ECMAScript 语言值List) and returns 一个 Iterator Record. 创建一个 Iterator Record,其 [[NextMethod]] 依次返回 list 的元素。 It performs the following steps when called:

  1. closure 为一个新建的 Abstract Closure(无参数),捕获 list,被调用时:
    1. list 中每个 E
      1. 执行 ? GeneratorYield(CreateIteratorResultObject(E, false))。
    2. 返回 NormalCompletion(undefined)。
  2. iteratorCreateIteratorFromClosure(closure, empty, %Iterator.prototype%)。
  3. 返回 Iterator Record { [[Iterator]]: iterator, [[NextMethod]]: %GeneratorPrototype.next%, [[Done]]: false }。
Note

该列表迭代器对象对 ECMAScript 代码不可直接访问。

7.4.16 IteratorToList ( iteratorRecord )

The abstract operation IteratorToList takes argument iteratorRecord (一个 Iterator Record) and returns 返回包含 ECMAScript 语言值 List正常完成或抛出完成. It performs the following steps when called:

  1. values 为新空 List
  2. 循环:
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. nextdone
      1. 返回 values
    3. next 加入 values

8 语法指引操作 (Syntax-Directed Operations)

除了本节定义的操作外,规范其余部分还定义了许多专门的语法指引操作。

8.1 运行时语义:Evaluation

The syntax-directed operation 运行时语义:Evaluation takes no arguments and returns 一个 Completion Record.

Note
本操作的定义分布在本规范“ECMAScript Language”各章节中。每个定义出现在相关产生式首次定义之后。

8.2 作用域分析 (Scope Analysis)

8.2.1 静态语义:BoundNames

The syntax-directed operation 静态语义:BoundNames takes no arguments and returns 一个字符串列表.

Note

"*default*" 在本规范中用作模块默认导出的合成名称(当它没有其它名称时)。模块的 [[Environment]] 中会以该名称创建一个条目并保存相应的值,对该模块调用 ResolveExport ( exportName [ , resolveSet ] ) 解析名为 "default" 的导出会返回一个 [[BindingName]]"*default*"ResolvedBinding Record,随后它在模块的 [[Environment]] 中解析为上述的值。此举仅为规范书写方便,使匿名默认导出能与其它导出统一解析。该 "*default*" 字符串在 ECMAScript 代码及模块链接算法中不可见。

It is defined piecewise over the following productions:

BindingIdentifier : Identifier
  1. 返回仅含 Identifier 的 StringValue 的列表。
BindingIdentifier : yield
  1. 返回 « "yield" »。
BindingIdentifier : await
  1. 返回 « "await" »。
LexicalDeclaration : LetOrConst BindingList ;
  1. 返回 BindingList 的 BoundNames。
BindingList : BindingList , LexicalBinding
  1. names1BindingList 的 BoundNames。
  2. names2LexicalBinding 的 BoundNames。
  3. 返回 names1names2列表拼接
LexicalBinding : BindingIdentifier Initializeropt
  1. 返回 BindingIdentifier 的 BoundNames。
LexicalBinding : BindingPattern Initializer
  1. 返回 BindingPattern 的 BoundNames。
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. names1VariableDeclarationList 的 BoundNames。
  2. names2VariableDeclaration 的 BoundNames。
  3. 返回 names1names2列表拼接
VariableDeclaration : BindingIdentifier Initializeropt
  1. 返回 BindingIdentifier 的 BoundNames。
VariableDeclaration : BindingPattern Initializer
  1. 返回 BindingPattern 的 BoundNames。
ObjectBindingPattern : { }
  1. 返回一个新的空列表。
ObjectBindingPattern : { BindingPropertyList , BindingRestProperty }
  1. names1BindingPropertyList 的 BoundNames。
  2. names2BindingRestProperty 的 BoundNames。
  3. 返回 names1names2列表拼接
ArrayBindingPattern : [ Elisionopt ]
  1. 返回一个新的空列表。
ArrayBindingPattern : [ Elisionopt BindingRestElement ]
  1. 返回 BindingRestElement 的 BoundNames。
ArrayBindingPattern : [ BindingElementList , Elisionopt ]
  1. 返回 BindingElementList 的 BoundNames。
ArrayBindingPattern : [ BindingElementList , Elisionopt BindingRestElement ]
  1. names1BindingElementList 的 BoundNames。
  2. names2BindingRestElement 的 BoundNames。
  3. 返回 names1names2列表拼接
BindingPropertyList : BindingPropertyList , BindingProperty
  1. names1BindingPropertyList 的 BoundNames。
  2. names2BindingProperty 的 BoundNames。
  3. 返回 names1names2列表拼接
BindingElementList : BindingElementList , BindingElisionElement
  1. names1BindingElementList 的 BoundNames。
  2. names2BindingElisionElement 的 BoundNames。
  3. 返回 names1names2列表拼接
BindingElisionElement : Elisionopt BindingElement
  1. 返回 BindingElement 的 BoundNames。
BindingProperty : PropertyName : BindingElement
  1. 返回 BindingElement 的 BoundNames。
SingleNameBinding : BindingIdentifier Initializeropt
  1. 返回 BindingIdentifier 的 BoundNames。
BindingElement : BindingPattern Initializeropt
  1. 返回 BindingPattern 的 BoundNames。
ForDeclaration : LetOrConst ForBinding
  1. 返回 ForBinding 的 BoundNames。
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. 返回 BindingIdentifier 的 BoundNames。
FunctionDeclaration : function ( FormalParameters ) { FunctionBody }
  1. 返回 « "*default*" »。
FormalParameters : [empty]
  1. 返回一个新的空列表。
FormalParameters : FormalParameterList , FunctionRestParameter
  1. names1FormalParameterList 的 BoundNames。
  2. names2FunctionRestParameter 的 BoundNames。
  3. 返回 names1names2列表拼接
FormalParameterList : FormalParameterList , FormalParameter
  1. names1FormalParameterList 的 BoundNames。
  2. names2FormalParameter 的 BoundNames。
  3. 返回 names1names2列表拼接
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsCoverParenthesizedExpressionAndArrowParameterList 覆盖ArrowFormalParameters
  2. 返回 formals 的 BoundNames。
GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody }
  1. 返回 BindingIdentifier 的 BoundNames。
GeneratorDeclaration : function * ( FormalParameters ) { GeneratorBody }
  1. 返回 « "*default*" »。
AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody }
  1. 返回 BindingIdentifier 的 BoundNames。
AsyncGeneratorDeclaration : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. 返回 « "*default*" »。
ClassDeclaration : class BindingIdentifier ClassTail
  1. 返回 BindingIdentifier 的 BoundNames。
ClassDeclaration : class ClassTail
  1. 返回 « "*default*" »。
AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 BindingIdentifier 的 BoundNames。
AsyncFunctionDeclaration : async function ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 « "*default*" »。
CoverCallExpressionAndAsyncArrowHead : MemberExpression Arguments
  1. headCoverCallExpressionAndAsyncArrowHead 覆盖AsyncArrowHead
  2. 返回 head 的 BoundNames。
ImportDeclaration : import ImportClause FromClause WithClauseopt ;
  1. 返回 ImportClause 的 BoundNames。
ImportDeclaration : import ModuleSpecifier WithClauseopt ;
  1. 返回一个新的空列表。
ImportClause : ImportedDefaultBinding , NameSpaceImport
  1. names1ImportedDefaultBinding 的 BoundNames。
  2. names2NameSpaceImport 的 BoundNames。
  3. 返回 names1names2列表拼接
ImportClause : ImportedDefaultBinding , NamedImports
  1. names1ImportedDefaultBinding 的 BoundNames。
  2. names2NamedImports 的 BoundNames。
  3. 返回 names1names2列表拼接
NamedImports : { }
  1. 返回一个新的空列表。
ImportsList : ImportsList , ImportSpecifier
  1. names1ImportsList 的 BoundNames。
  2. names2ImportSpecifier 的 BoundNames。
  3. 返回 names1names2列表拼接
ImportSpecifier : ModuleExportName as ImportedBinding
  1. 返回 ImportedBinding 的 BoundNames。
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ; export NamedExports ;
  1. 返回一个新的空列表。
ExportDeclaration : export VariableStatement
  1. 返回 VariableStatement 的 BoundNames。
ExportDeclaration : export Declaration
  1. 返回 Declaration 的 BoundNames。
ExportDeclaration : export default HoistableDeclaration
  1. declarationNamesHoistableDeclaration 的 BoundNames。
  2. declarationNames 不含 "*default*",将 "*default*" 添加到 declarationNames
  3. 返回 declarationNames
ExportDeclaration : export default ClassDeclaration
  1. declarationNamesClassDeclaration 的 BoundNames。
  2. declarationNames 不含 "*default*",将 "*default*" 添加到 declarationNames
  3. 返回 declarationNames
ExportDeclaration : export default AssignmentExpression ;
  1. 返回 « "*default*" »。

8.2.2 静态语义:DeclarationPart

The syntax-directed operation 静态语义:DeclarationPart takes no arguments and returns 一个 Parse Node. It is defined piecewise over the following productions:

HoistableDeclaration : FunctionDeclaration
  1. 返回 FunctionDeclaration
HoistableDeclaration : GeneratorDeclaration
  1. 返回 GeneratorDeclaration
HoistableDeclaration : AsyncFunctionDeclaration
  1. 返回 AsyncFunctionDeclaration
HoistableDeclaration : AsyncGeneratorDeclaration
  1. 返回 AsyncGeneratorDeclaration
Declaration : ClassDeclaration
  1. 返回 ClassDeclaration
Declaration : LexicalDeclaration
  1. 返回 LexicalDeclaration

8.2.3 静态语义:IsConstantDeclaration

The syntax-directed operation 静态语义:IsConstantDeclaration takes no arguments and returns 一个 Boolean. It is defined piecewise over the following productions:

LexicalDeclaration : LetOrConst BindingList ;
  1. 返回 LetOrConst 的 IsConstantDeclaration。
LetOrConst : let
  1. 返回 false
LetOrConst : const
  1. 返回 true
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 false
ClassDeclaration : class BindingIdentifier ClassTail class ClassTail
  1. 返回 false
ExportDeclaration : export ExportFromClause FromClause ; export NamedExports ; export default AssignmentExpression ;
  1. 返回 false
Note

无需将 export default AssignmentExpression 视作常量声明,因为不存在语法允许对用于引用模块默认对象的内部绑定名赋值。

8.2.4 静态语义:LexicallyDeclaredNames

The syntax-directed operation 静态语义:LexicallyDeclaredNames takes no arguments and returns 一个字符串列表. It is defined piecewise over the following productions:

Block : { }
  1. 返回一个新的空列表。
StatementList : StatementList StatementListItem
  1. names1StatementList 的 LexicallyDeclaredNames。
  2. names2StatementListItem 的 LexicallyDeclaredNames。
  3. 返回 names1names2列表拼接
StatementListItem : Statement
  1. Statement Statement : LabelledStatement ,返回 LabelledStatement 的 LexicallyDeclaredNames。
  2. 返回一个新的空列表。
StatementListItem : Declaration
  1. 返回 Declaration 的 BoundNames。
CaseBlock : { }
  1. 返回一个新的空列表。
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 若第一个 CaseClauses 存在,令 names1 为其 LexicallyDeclaredNames;否则 names1 为新空列表。
  2. names2DefaultClause 的 LexicallyDeclaredNames。
  3. 若第二个 CaseClauses 存在,令 names3 为其 LexicallyDeclaredNames;否则 names3 为新空列表。
  4. 返回 names1names2names3列表拼接
CaseClauses : CaseClauses CaseClause
  1. names1CaseClauses 的 LexicallyDeclaredNames。
  2. names2CaseClause 的 LexicallyDeclaredNames。
  3. 返回 names1names2列表拼接
CaseClause : case Expression : StatementListopt
  1. StatementList 存在,返回其 LexicallyDeclaredNames。
  2. 返回一个新的空列表。
DefaultClause : default : StatementListopt
  1. StatementList 存在,返回其 LexicallyDeclaredNames。
  2. 返回一个新的空列表。
LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 LabelledItem 的 LexicallyDeclaredNames。
LabelledItem : Statement
  1. 返回一个新的空列表。
LabelledItem : FunctionDeclaration
  1. 返回 FunctionDeclaration 的 BoundNames。
FunctionStatementList : [empty]
  1. 返回一个新的空列表。
FunctionStatementList : StatementList
  1. 返回 StatementList 的 TopLevelLexicallyDeclaredNames。
ClassStaticBlockStatementList : [empty]
  1. 返回一个新的空列表。
ClassStaticBlockStatementList : StatementList
  1. 返回 StatementList 的 TopLevelLexicallyDeclaredNames。
ConciseBody : ExpressionBody
  1. 返回一个新的空列表。
AsyncConciseBody : ExpressionBody
  1. 返回一个新的空列表。
Script : [empty]
  1. 返回一个新的空列表。
ScriptBody : StatementList
  1. 返回 StatementList 的 TopLevelLexicallyDeclaredNames。
Note 1

Script 顶层的函数声明按 var 声明处理,而非按词法声明处理。

Note 2

Module 的 LexicallyDeclaredNames 包含其所有导入绑定的名称。

ModuleItemList : ModuleItemList ModuleItem
  1. names1ModuleItemList 的 LexicallyDeclaredNames。
  2. names2ModuleItem 的 LexicallyDeclaredNames。
  3. 返回 names1names2列表拼接
ModuleItem : ImportDeclaration
  1. 返回 ImportDeclaration 的 BoundNames。
ModuleItem : ExportDeclaration
  1. ExportDeclarationexport VariableStatement,返回一个新的空列表。
  2. 返回 ExportDeclaration 的 BoundNames。
ModuleItem : StatementListItem
  1. 返回 StatementListItem 的 LexicallyDeclaredNames。
Note 3

Module 顶层的函数声明按词法声明处理,而非按 var 声明。

8.2.5 静态语义:LexicallyScopedDeclarations

The syntax-directed operation 静态语义:LexicallyScopedDeclarations takes no arguments and returns 一个 Parse Node 列表. It is defined piecewise over the following productions:

StatementList : StatementList StatementListItem
  1. declarations1StatementList 的 LexicallyScopedDeclarations。
  2. declarations2StatementListItem 的 LexicallyScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
StatementListItem : Statement
  1. Statement Statement : LabelledStatement ,返回 LabelledStatement 的 LexicallyScopedDeclarations。
  2. 返回一个新的空列表。
StatementListItem : Declaration
  1. 返回仅含 Declaration 的 DeclarationPart 的列表。
CaseBlock : { }
  1. 返回一个新的空列表。
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 若第一个 CaseClauses 存在,令 declarations1 为其 LexicallyScopedDeclarations;否则 declarations1 为新空列表。
  2. declarations2DefaultClause 的 LexicallyScopedDeclarations。
  3. 若第二个 CaseClauses 存在,令 declarations3 为其 LexicallyScopedDeclarations;否则 declarations3 为新空列表。
  4. 返回 declarations1declarations2declarations3列表拼接
CaseClauses : CaseClauses CaseClause
  1. declarations1CaseClauses 的 LexicallyScopedDeclarations。
  2. declarations2CaseClause 的 LexicallyScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
CaseClause : case Expression : StatementListopt
  1. StatementList 存在,返回其 LexicallyScopedDeclarations。
  2. 返回一个新的空列表。
DefaultClause : default : StatementListopt
  1. StatementList 存在,返回其 LexicallyScopedDeclarations。
  2. 返回一个新的空列表。
LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 LabelledItem 的 LexicallyScopedDeclarations。
LabelledItem : Statement
  1. 返回一个新的空列表。
LabelledItem : FunctionDeclaration
  1. 返回 « FunctionDeclaration »。
FunctionStatementList : [empty]
  1. 返回一个新的空列表。
FunctionStatementList : StatementList
  1. 返回 StatementList 的 TopLevelLexicallyScopedDeclarations。
ClassStaticBlockStatementList : [empty]
  1. 返回一个新的空列表。
ClassStaticBlockStatementList : StatementList
  1. 返回 StatementList 的 TopLevelLexicallyScopedDeclarations。
ConciseBody : ExpressionBody
  1. 返回一个新的空列表。
AsyncConciseBody : ExpressionBody
  1. 返回一个新的空列表。
Script : [empty]
  1. 返回一个新的空列表。
ScriptBody : StatementList
  1. 返回 StatementList 的 TopLevelLexicallyScopedDeclarations。
Module : [empty]
  1. 返回一个新的空列表。
ModuleItemList : ModuleItemList ModuleItem
  1. declarations1ModuleItemList 的 LexicallyScopedDeclarations。
  2. declarations2ModuleItem 的 LexicallyScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
ModuleItem : ImportDeclaration
  1. 返回一个新的空列表。
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ; export NamedExports ; export VariableStatement
  1. 返回一个新的空列表。
ExportDeclaration : export Declaration
  1. 返回仅含 Declaration 的 DeclarationPart 的列表。
ExportDeclaration : export default HoistableDeclaration
  1. 返回仅含 HoistableDeclaration 的 DeclarationPart 的列表。
ExportDeclaration : export default ClassDeclaration
  1. 返回仅含 ClassDeclaration 的列表。
ExportDeclaration : export default AssignmentExpression ;
  1. 返回仅含本 ExportDeclaration 的列表。

8.2.6 静态语义:VarDeclaredNames

The syntax-directed operation 静态语义:VarDeclaredNames takes no arguments and returns 一个字符串列表. It is defined piecewise over the following productions:

Statement : EmptyStatement ExpressionStatement ContinueStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement
  1. 返回一个新的空列表。
Block : { }
  1. 返回一个新的空列表。
StatementList : StatementList StatementListItem
  1. names1StatementList 的 VarDeclaredNames。
  2. names2StatementListItem 的 VarDeclaredNames。
  3. 返回 names1names2列表拼接
StatementListItem : Declaration
  1. 返回一个新的空列表。
VariableStatement : var VariableDeclarationList ;
  1. 返回 VariableDeclarationList 的 BoundNames。
IfStatement : if ( Expression ) Statement else Statement
  1. names1 为第一个 Statement 的 VarDeclaredNames。
  2. names2 为第二个 Statement 的 VarDeclaredNames。
  3. 返回 names1names2列表拼接
IfStatement : if ( Expression ) Statement
  1. 返回 Statement 的 VarDeclaredNames。
DoWhileStatement : do Statement while ( Expression ) ;
  1. 返回 Statement 的 VarDeclaredNames。
WhileStatement : while ( Expression ) Statement
  1. 返回 Statement 的 VarDeclaredNames。
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
  1. 返回 Statement 的 VarDeclaredNames。
ForStatement : for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement
  1. names1VariableDeclarationList 的 BoundNames。
  2. names2Statement 的 VarDeclaredNames。
  3. 返回 names1names2列表拼接
ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. 返回 Statement 的 VarDeclaredNames。
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. 返回 Statement 的 VarDeclaredNames。
ForInOfStatement : for ( var ForBinding in Expression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement
  1. names1ForBinding 的 BoundNames。
  2. names2Statement 的 VarDeclaredNames。
  3. 返回 names1names2列表拼接
Note

本节由附件 B.3.5 扩展。

WithStatement : with ( Expression ) Statement
  1. 返回 Statement 的 VarDeclaredNames。
SwitchStatement : switch ( Expression ) CaseBlock
  1. 返回 CaseBlock 的 VarDeclaredNames。
CaseBlock : { }
  1. 返回一个新的空列表。
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 若第一个 CaseClauses 存在,令 names1 为其 VarDeclaredNames;否则 names1 为新空列表。
  2. names2DefaultClause 的 VarDeclaredNames。
  3. 若第二个 CaseClauses 存在,令 names3 为其 VarDeclaredNames;否则 names3 为新空列表。
  4. 返回 names1names2names3列表拼接
CaseClauses : CaseClauses CaseClause
  1. names1CaseClauses 的 VarDeclaredNames。
  2. names2CaseClause 的 VarDeclaredNames。
  3. 返回 names1names2列表拼接
CaseClause : case Expression : StatementListopt
  1. StatementList 存在,返回其 VarDeclaredNames。
  2. 返回一个新的空列表。
DefaultClause : default : StatementListopt
  1. StatementList 存在,返回其 VarDeclaredNames。
  2. 返回一个新的空列表。
LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 LabelledItem 的 VarDeclaredNames。
LabelledItem : FunctionDeclaration
  1. 返回一个新的空列表。
TryStatement : try Block Catch
  1. names1Block 的 VarDeclaredNames。
  2. names2Catch 的 VarDeclaredNames。
  3. 返回 names1names2列表拼接
TryStatement : try Block Finally
  1. names1Block 的 VarDeclaredNames。
  2. names2Finally 的 VarDeclaredNames。
  3. 返回 names1names2列表拼接
TryStatement : try Block Catch Finally
  1. names1Block 的 VarDeclaredNames。
  2. names2Catch 的 VarDeclaredNames。
  3. names3Finally 的 VarDeclaredNames。
  4. 返回 names1names2names3列表拼接
Catch : catch ( CatchParameter ) Block
  1. 返回 Block 的 VarDeclaredNames。
FunctionStatementList : [empty]
  1. 返回一个新的空列表。
FunctionStatementList : StatementList
  1. 返回 StatementList 的 TopLevelVarDeclaredNames。
ClassStaticBlockStatementList : [empty]
  1. 返回一个新的空列表。
ClassStaticBlockStatementList : StatementList
  1. 返回 StatementList 的 TopLevelVarDeclaredNames。
ConciseBody : ExpressionBody
  1. 返回一个新的空列表。
AsyncConciseBody : ExpressionBody
  1. 返回一个新的空列表。
Script : [empty]
  1. 返回一个新的空列表。
ScriptBody : StatementList
  1. 返回 StatementList 的 TopLevelVarDeclaredNames。
ModuleItemList : ModuleItemList ModuleItem
  1. names1ModuleItemList 的 VarDeclaredNames。
  2. names2ModuleItem 的 VarDeclaredNames。
  3. 返回 names1names2列表拼接
ModuleItem : ImportDeclaration
  1. 返回一个新的空列表。
ModuleItem : ExportDeclaration
  1. ExportDeclarationexport VariableStatement,返回 ExportDeclaration 的 BoundNames。
  2. 返回一个新的空列表。

8.2.7 静态语义:VarScopedDeclarations

The syntax-directed operation 静态语义:VarScopedDeclarations takes no arguments and returns 一个 Parse Node 列表. It is defined piecewise over the following productions:

Statement : EmptyStatement ExpressionStatement ContinueStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement
  1. 返回一个新的空列表。
Block : { }
  1. 返回一个新的空列表。
StatementList : StatementList StatementListItem
  1. declarations1StatementList 的 VarScopedDeclarations。
  2. declarations2StatementListItem 的 VarScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
StatementListItem : Declaration
  1. 返回一个新的空列表。
VariableDeclarationList : VariableDeclaration
  1. 返回 « VariableDeclaration »。
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. declarations1VariableDeclarationList 的 VarScopedDeclarations。
  2. 返回 declarations1 与 « VariableDeclaration » 的列表拼接
IfStatement : if ( Expression ) Statement else Statement
  1. declarations1 为第一个 Statement 的 VarScopedDeclarations。
  2. declarations2 为第二个 Statement 的 VarScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
IfStatement : if ( Expression ) Statement
  1. 返回 Statement 的 VarScopedDeclarations。
DoWhileStatement : do Statement while ( Expression ) ;
  1. 返回 Statement 的 VarScopedDeclarations。
WhileStatement : while ( Expression ) Statement
  1. 返回 Statement 的 VarScopedDeclarations。
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
  1. 返回 Statement 的 VarScopedDeclarations。
ForStatement : for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement
  1. declarations1VariableDeclarationList 的 VarScopedDeclarations。
  2. declarations2Statement 的 VarScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. 返回 Statement 的 VarScopedDeclarations。
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. 返回 Statement 的 VarScopedDeclarations。
ForInOfStatement : for ( var ForBinding in Expression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement
  1. declarations1 为 « ForBinding »。
  2. declarations2Statement 的 VarScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
Note

本节由附件 B.3.5 扩展。

WithStatement : with ( Expression ) Statement
  1. 返回 Statement 的 VarScopedDeclarations。
SwitchStatement : switch ( Expression ) CaseBlock
  1. 返回 CaseBlock 的 VarScopedDeclarations。
CaseBlock : { }
  1. 返回一个新的空列表。
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 若第一个 CaseClauses 存在,令 declarations1 为其 VarScopedDeclarations;否则 declarations1 为新空列表。
  2. declarations2DefaultClause 的 VarScopedDeclarations。
  3. 若第二个 CaseClauses 存在,令 declarations3 为其 VarScopedDeclarations;否则 declarations3 为新空列表。
  4. 返回 declarations1declarations2declarations3列表拼接
CaseClauses : CaseClauses CaseClause
  1. declarations1CaseClauses 的 VarScopedDeclarations。
  2. declarations2CaseClause 的 VarScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
CaseClause : case Expression : StatementListopt
  1. StatementList 存在,返回其 VarScopedDeclarations。
  2. 返回一个新的空列表。
DefaultClause : default : StatementListopt
  1. StatementList 存在,返回其 VarScopedDeclarations。
  2. 返回一个新的空列表。
LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 LabelledItem 的 VarScopedDeclarations。
LabelledItem : FunctionDeclaration
  1. 返回一个新的空列表。
TryStatement : try Block Catch
  1. declarations1Block 的 VarScopedDeclarations。
  2. declarations2Catch 的 VarScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
TryStatement : try Block Finally
  1. declarations1Block 的 VarScopedDeclarations。
  2. declarations2Finally 的 VarScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
TryStatement : try Block Catch Finally
  1. declarations1Block 的 VarScopedDeclarations。
  2. declarations2Catch 的 VarScopedDeclarations。
  3. declarations3Finally 的 VarScopedDeclarations。
  4. 返回 declarations1declarations2declarations3列表拼接
Catch : catch ( CatchParameter ) Block
  1. 返回 Block 的 VarScopedDeclarations。
FunctionStatementList : [empty]
  1. 返回一个新的空列表。
FunctionStatementList : StatementList
  1. 返回 StatementList 的 TopLevelVarScopedDeclarations。
ClassStaticBlockStatementList : [empty]
  1. 返回一个新的空列表。
ClassStaticBlockStatementList : StatementList
  1. 返回 StatementList 的 TopLevelVarScopedDeclarations。
ConciseBody : ExpressionBody
  1. 返回一个新的空列表。
AsyncConciseBody : ExpressionBody
  1. 返回一个新的空列表。
Script : [empty]
  1. 返回一个新的空列表。
ScriptBody : StatementList
  1. 返回 StatementList 的 TopLevelVarScopedDeclarations。
Module : [empty]
  1. 返回一个新的空列表。
ModuleItemList : ModuleItemList ModuleItem
  1. declarations1ModuleItemList 的 VarScopedDeclarations。
  2. declarations2ModuleItem 的 VarScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
ModuleItem : ImportDeclaration
  1. 返回一个新的空列表。
ModuleItem : ExportDeclaration
  1. ExportDeclarationexport VariableStatement,返回 VariableStatement 的 VarScopedDeclarations。
  2. 返回一个新的空列表。

8.2.8 静态语义:TopLevelLexicallyDeclaredNames

The syntax-directed operation 静态语义:TopLevelLexicallyDeclaredNames takes no arguments and returns 一个字符串列表. It is defined piecewise over the following productions:

StatementList : StatementList StatementListItem
  1. names1StatementList 的 TopLevelLexicallyDeclaredNames。
  2. names2StatementListItem 的 TopLevelLexicallyDeclaredNames。
  3. 返回 names1names2列表拼接
StatementListItem : Statement
  1. 返回一个新的空列表。
StatementListItem : Declaration
  1. Declaration Declaration : HoistableDeclaration
    1. 返回一个新的空列表。
  2. 返回 Declaration 的 BoundNames。
Note

函数或脚本顶层中,函数声明按 var 声明而非词法声明处理。

8.2.9 静态语义:TopLevelLexicallyScopedDeclarations

The syntax-directed operation 静态语义:TopLevelLexicallyScopedDeclarations takes no arguments and returns 一个 Parse Node 列表. It is defined piecewise over the following productions:

StatementList : StatementList StatementListItem
  1. declarations1StatementList 的 TopLevelLexicallyScopedDeclarations。
  2. declarations2StatementListItem 的 TopLevelLexicallyScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
StatementListItem : Statement
  1. 返回一个新的空列表。
StatementListItem : Declaration
  1. Declaration Declaration : HoistableDeclaration
    1. 返回一个新的空列表。
  2. 返回 « Declaration »。

8.2.10 静态语义:TopLevelVarDeclaredNames

The syntax-directed operation 静态语义:TopLevelVarDeclaredNames takes no arguments and returns 一个字符串列表. It is defined piecewise over the following productions:

StatementList : StatementList StatementListItem
  1. names1StatementList 的 TopLevelVarDeclaredNames。
  2. names2StatementListItem 的 TopLevelVarDeclaredNames。
  3. 返回 names1names2列表拼接
StatementListItem : Declaration
  1. Declaration Declaration : HoistableDeclaration
    1. 返回 HoistableDeclaration 的 BoundNames。
  2. 返回一个新的空列表。
StatementListItem : Statement
  1. Statement Statement : LabelledStatement ,返回 Statement 的 TopLevelVarDeclaredNames。
  2. 返回 Statement 的 VarDeclaredNames。
Note

函数或脚本顶层的内部函数声明按 var 声明处理。

LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 LabelledItem 的 TopLevelVarDeclaredNames。
LabelledItem : Statement
  1. Statement Statement : LabelledStatement ,返回 Statement 的 TopLevelVarDeclaredNames。
  2. 返回 Statement 的 VarDeclaredNames。
LabelledItem : FunctionDeclaration
  1. 返回 FunctionDeclaration 的 BoundNames。

8.2.11 静态语义:TopLevelVarScopedDeclarations

The syntax-directed operation 静态语义:TopLevelVarScopedDeclarations takes no arguments and returns 一个 Parse Node 列表. It is defined piecewise over the following productions:

StatementList : StatementList StatementListItem
  1. declarations1StatementList 的 TopLevelVarScopedDeclarations。
  2. declarations2StatementListItem 的 TopLevelVarScopedDeclarations。
  3. 返回 declarations1declarations2列表拼接
StatementListItem : Statement
  1. Statement Statement : LabelledStatement ,返回 Statement 的 TopLevelVarScopedDeclarations。
  2. 返回 Statement 的 VarScopedDeclarations。
StatementListItem : Declaration
  1. Declaration Declaration : HoistableDeclaration
    1. declarationHoistableDeclaration 的 DeclarationPart。
    2. 返回 « declaration »。
  2. 返回一个新的空列表。
LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 LabelledItem 的 TopLevelVarScopedDeclarations。
LabelledItem : Statement
  1. Statement Statement : LabelledStatement ,返回 Statement 的 TopLevelVarScopedDeclarations。
  2. 返回 Statement 的 VarScopedDeclarations。
LabelledItem : FunctionDeclaration
  1. 返回 « FunctionDeclaration »。

8.3 标签 (Labels)

8.3.1 静态语义:ContainsDuplicateLabels

The syntax-directed operation 静态语义:ContainsDuplicateLabels takes argument labelSet (一个字符串列表) and returns 一个 Boolean. It is defined piecewise over the following productions:

Statement : VariableStatement EmptyStatement ExpressionStatement ContinueStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement Block : { } StatementListItem : Declaration
  1. 返回 false
StatementList : StatementList StatementListItem
  1. hasDuplicatesStatementList 的 ContainsDuplicateLabels(参数 labelSet)。
  2. hasDuplicatestrue,返回 true
  3. 返回 StatementListItem 的 ContainsDuplicateLabels(参数 labelSet)。
IfStatement : if ( Expression ) Statement else Statement
  1. hasDuplicate 为第一个 Statement 的 ContainsDuplicateLabels(参数 labelSet)。
  2. hasDuplicatetrue,返回 true
  3. 返回第二个 Statement 的 ContainsDuplicateLabels(参数 labelSet)。
IfStatement : if ( Expression ) Statement
  1. 返回 Statement 的 ContainsDuplicateLabels(参数 labelSet)。
DoWhileStatement : do Statement while ( Expression ) ;
  1. 返回 Statement 的 ContainsDuplicateLabels(参数 labelSet)。
WhileStatement : while ( Expression ) Statement
  1. 返回 Statement 的 ContainsDuplicateLabels(参数 labelSet)。
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. 返回 Statement 的 ContainsDuplicateLabels(参数 labelSet)。
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. 返回 Statement 的 ContainsDuplicateLabels(参数 labelSet)。
Note

本节由附录 B.3.5 扩展。

WithStatement : with ( Expression ) Statement
  1. 返回 Statement 的 ContainsDuplicateLabels(参数 labelSet)。
SwitchStatement : switch ( Expression ) CaseBlock
  1. 返回 CaseBlock 的 ContainsDuplicateLabels(参数 labelSet)。
CaseBlock : { }
  1. 返回 false
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 若第一个 CaseClauses 存在,则
    1. 若第一个 CaseClauses 的 ContainsDuplicateLabels(参数 labelSet)为 true,返回 true
  2. DefaultClause 的 ContainsDuplicateLabels(参数 labelSet)为 true,返回 true
  3. 若第二个 CaseClauses 不存在,返回 false
  4. 返回第二个 CaseClauses 的 ContainsDuplicateLabels(参数 labelSet)。
CaseClauses : CaseClauses CaseClause
  1. hasDuplicatesCaseClauses 的 ContainsDuplicateLabels(参数 labelSet)。
  2. hasDuplicatestrue,返回 true
  3. 返回 CaseClause 的 ContainsDuplicateLabels(参数 labelSet)。
CaseClause : case Expression : StatementListopt
  1. StatementList 存在,返回其 ContainsDuplicateLabels(参数 labelSet)。
  2. 返回 false
DefaultClause : default : StatementListopt
  1. StatementList 存在,返回其 ContainsDuplicateLabels(参数 labelSet)。
  2. 返回 false
LabelledStatement : LabelIdentifier : LabelledItem
  1. labelLabelIdentifier 的 StringValue。
  2. labelSet 包含 label,返回 true
  3. newLabelSetlabelSet 与 « label » 的列表拼接
  4. 返回 LabelledItem 的 ContainsDuplicateLabels(参数 newLabelSet)。
LabelledItem : FunctionDeclaration
  1. 返回 false
TryStatement : try Block Catch
  1. hasDuplicatesBlock 的 ContainsDuplicateLabels(参数 labelSet)。
  2. hasDuplicatestrue,返回 true
  3. 返回 Catch 的 ContainsDuplicateLabels(参数 labelSet)。
TryStatement : try Block Finally
  1. hasDuplicatesBlock 的 ContainsDuplicateLabels(参数 labelSet)。
  2. hasDuplicatestrue,返回 true
  3. 返回 Finally 的 ContainsDuplicateLabels(参数 labelSet)。
TryStatement : try Block Catch Finally
  1. Block 的 ContainsDuplicateLabels(参数 labelSet)为 true,返回 true
  2. Catch 的 ContainsDuplicateLabels(参数 labelSet)为 true,返回 true
  3. 返回 Finally 的 ContainsDuplicateLabels(参数 labelSet)。
Catch : catch ( CatchParameter ) Block
  1. 返回 Block 的 ContainsDuplicateLabels(参数 labelSet)。
FunctionStatementList : [empty]
  1. 返回 false
ClassStaticBlockStatementList : [empty]
  1. 返回 false
ModuleItemList : ModuleItemList ModuleItem
  1. hasDuplicatesModuleItemList 的 ContainsDuplicateLabels(参数 labelSet)。
  2. hasDuplicatestrue,返回 true
  3. 返回 ModuleItem 的 ContainsDuplicateLabels(参数 labelSet)。
ModuleItem : ImportDeclaration ExportDeclaration
  1. 返回 false

8.3.2 静态语义:ContainsUndefinedBreakTarget

The syntax-directed operation 静态语义:ContainsUndefinedBreakTarget takes argument labelSet (一个字符串列表) and returns 一个 Boolean. It is defined piecewise over the following productions:

Statement : VariableStatement EmptyStatement ExpressionStatement ContinueStatement ReturnStatement ThrowStatement DebuggerStatement Block : { } StatementListItem : Declaration
  1. 返回 false
StatementList : StatementList StatementListItem
  1. hasUndefinedLabelsStatementList 的 ContainsUndefinedBreakTarget(参数 labelSet)。
  2. hasUndefinedLabelstrue,返回 true
  3. 返回 StatementListItem 的 ContainsUndefinedBreakTarget(参数 labelSet)。
IfStatement : if ( Expression ) Statement else Statement
  1. hasUndefinedLabels 为第一个 Statement 的 ContainsUndefinedBreakTarget(参数 labelSet)。
  2. hasUndefinedLabelstrue,返回 true
  3. 返回第二个 Statement 的 ContainsUndefinedBreakTarget(参数 labelSet)。
IfStatement : if ( Expression ) Statement
  1. 返回 Statement 的 ContainsUndefinedBreakTarget(参数 labelSet)。
DoWhileStatement : do Statement while ( Expression ) ;
  1. 返回 Statement 的 ContainsUndefinedBreakTarget(参数 labelSet)。
WhileStatement : while ( Expression ) Statement
  1. 返回 Statement 的 ContainsUndefinedBreakTarget(参数 labelSet)。
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. 返回 Statement 的 ContainsUndefinedBreakTarget(参数 labelSet)。
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. 返回 Statement 的 ContainsUndefinedBreakTarget(参数 labelSet)。
Note

本节由附录 B.3.5 扩展。

BreakStatement : break ;
  1. 返回 false
BreakStatement : break LabelIdentifier ;
  1. labelSet 不包含 LabelIdentifier 的 StringValue,返回 true
  2. 返回 false
WithStatement : with ( Expression ) Statement
  1. 返回 Statement 的 ContainsUndefinedBreakTarget(参数 labelSet)。
SwitchStatement : switch ( Expression ) CaseBlock
  1. 返回 CaseBlock 的 ContainsUndefinedBreakTarget(参数 labelSet)。
CaseBlock : { }
  1. 返回 false
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 若第一个 CaseClauses 存在,则
    1. 若第一个 CaseClauses 的 ContainsUndefinedBreakTarget(参数 labelSet)为 true,返回 true
  2. DefaultClause 的 ContainsUndefinedBreakTarget(参数 labelSet)为 true,返回 true
  3. 若第二个 CaseClauses 不存在,返回 false
  4. 返回第二个 CaseClauses 的 ContainsUndefinedBreakTarget(参数 labelSet)。
CaseClauses : CaseClauses CaseClause
  1. hasUndefinedLabelsCaseClauses 的 ContainsUndefinedBreakTarget(参数 labelSet)。
  2. hasUndefinedLabelstrue,返回 true
  3. 返回 CaseClause 的 ContainsUndefinedBreakTarget(参数 labelSet)。
CaseClause : case Expression : StatementListopt
  1. StatementList 存在,返回其 ContainsUndefinedBreakTarget(参数 labelSet)。
  2. 返回 false
DefaultClause : default : StatementListopt
  1. StatementList 存在,返回其 ContainsUndefinedBreakTarget(参数 labelSet)。
  2. 返回 false
LabelledStatement : LabelIdentifier : LabelledItem
  1. labelLabelIdentifier 的 StringValue。
  2. newLabelSetlabelSet 与 « label » 的列表拼接
  3. 返回 LabelledItem 的 ContainsUndefinedBreakTarget(参数 newLabelSet)。
LabelledItem : FunctionDeclaration
  1. 返回 false
TryStatement : try Block Catch
  1. hasUndefinedLabelsBlock 的 ContainsUndefinedBreakTarget(参数 labelSet)。
  2. hasUndefinedLabelstrue,返回 true
  3. 返回 Catch 的 ContainsUndefinedBreakTarget(参数 labelSet)。
TryStatement : try Block Finally
  1. hasUndefinedLabelsBlock 的 ContainsUndefinedBreakTarget(参数 labelSet)。
  2. hasUndefinedLabelstrue,返回 true
  3. 返回 Finally 的 ContainsUndefinedBreakTarget(参数 labelSet)。
TryStatement : try Block Catch Finally
  1. Block 的 ContainsUndefinedBreakTarget(参数 labelSet)为 true,返回 true
  2. Catch 的 ContainsUndefinedBreakTarget(参数 labelSet)为 true,返回 true
  3. 返回 Finally 的 ContainsUndefinedBreakTarget(参数 labelSet)。
Catch : catch ( CatchParameter ) Block
  1. 返回 Block 的 ContainsUndefinedBreakTarget(参数 labelSet)。
FunctionStatementList : [empty]
  1. 返回 false
ClassStaticBlockStatementList : [empty]
  1. 返回 false
ModuleItemList : ModuleItemList ModuleItem
  1. hasUndefinedLabelsModuleItemList 的 ContainsUndefinedBreakTarget(参数 labelSet)。
  2. hasUndefinedLabelstrue,返回 true
  3. 返回 ModuleItem 的 ContainsUndefinedBreakTarget(参数 labelSet)。
ModuleItem : ImportDeclaration ExportDeclaration
  1. 返回 false

8.3.3 静态语义:ContainsUndefinedContinueTarget

The syntax-directed operation 静态语义:ContainsUndefinedContinueTarget takes arguments iterationSet (一个字符串列表) and labelSet (一个字符串列表) and returns 一个 Boolean. It is defined piecewise over the following productions:

Statement : VariableStatement EmptyStatement ExpressionStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement Block : { } StatementListItem : Declaration
  1. 返回 false
Statement : BlockStatement
  1. 返回 BlockStatement 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
BreakableStatement : IterationStatement
  1. newIterationSetiterationSetlabelSet列表拼接
  2. 返回 IterationStatement 的 ContainsUndefinedContinueTarget(参数 newIterationSet 与 « »)。
StatementList : StatementList StatementListItem
  1. hasUndefinedLabelsStatementList 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
  2. hasUndefinedLabelstrue,返回 true
  3. 返回 StatementListItem 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
IfStatement : if ( Expression ) Statement else Statement
  1. hasUndefinedLabels 为第一个 Statement 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
  2. hasUndefinedLabelstrue,返回 true
  3. 返回第二个 Statement 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
IfStatement : if ( Expression ) Statement
  1. 返回 Statement 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
DoWhileStatement : do Statement while ( Expression ) ;
  1. 返回 Statement 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
WhileStatement : while ( Expression ) Statement
  1. 返回 Statement 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. 返回 Statement 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. 返回 Statement 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
Note

本节由附录 B.3.5 扩展。

ContinueStatement : continue ;
  1. 返回 false
ContinueStatement : continue LabelIdentifier ;
  1. iterationSet 不包含 LabelIdentifier 的 StringValue,返回 true
  2. 返回 false
WithStatement : with ( Expression ) Statement
  1. 返回 Statement 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
SwitchStatement : switch ( Expression ) CaseBlock
  1. 返回 CaseBlock 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
CaseBlock : { }
  1. 返回 false
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 若第一个 CaseClauses 存在,则
    1. 若第一个 CaseClauses 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)为 true,返回 true
  2. DefaultClause 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)为 true,返回 true
  3. 若第二个 CaseClauses 不存在,返回 false
  4. 返回第二个 CaseClauses 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
CaseClauses : CaseClauses CaseClause
  1. hasUndefinedLabelsCaseClauses 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
  2. hasUndefinedLabelstrue,返回 true
  3. 返回 CaseClause 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
CaseClause : case Expression : StatementListopt
  1. StatementList 存在,返回其 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
  2. 返回 false
DefaultClause : default : StatementListopt
  1. StatementList 存在,返回其 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
  2. 返回 false
LabelledStatement : LabelIdentifier : LabelledItem
  1. labelLabelIdentifier 的 StringValue。
  2. newLabelSetlabelSet 与 « label » 的列表拼接
  3. 返回 LabelledItem 的 ContainsUndefinedContinueTarget(参数 iterationSetnewLabelSet)。
LabelledItem : FunctionDeclaration
  1. 返回 false
TryStatement : try Block Catch
  1. hasUndefinedLabelsBlock 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
  2. hasUndefinedLabelstrue,返回 true
  3. 返回 Catch 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
TryStatement : try Block Finally
  1. hasUndefinedLabelsBlock 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
  2. hasUndefinedLabelstrue,返回 true
  3. 返回 Finally 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
TryStatement : try Block Catch Finally
  1. Block 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)为 true,返回 true
  2. Catch 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)为 true,返回 true
  3. 返回 Finally 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
Catch : catch ( CatchParameter ) Block
  1. 返回 Block 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
FunctionStatementList : [empty]
  1. 返回 false
ClassStaticBlockStatementList : [empty]
  1. 返回 false
ModuleItemList : ModuleItemList ModuleItem
  1. hasUndefinedLabelsModuleItemList 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
  2. hasUndefinedLabelstrue,返回 true
  3. 返回 ModuleItem 的 ContainsUndefinedContinueTarget(参数 iterationSet 与 « »)。
ModuleItem : ImportDeclaration ExportDeclaration
  1. 返回 false

8.4 函数名称推断 (Function Name Inference)

8.4.1 静态语义:HasName

The syntax-directed operation 静态语义:HasName takes no arguments and returns 一个 Boolean. It is defined piecewise over the following productions:

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprCoverParenthesizedExpressionAndArrowParameterList覆盖ParenthesizedExpression
  2. 如果 expr 的 IsFunctionDefinition 为 false,返回 false
  3. 返回 expr 的 HasName。
FunctionExpression : function ( FormalParameters ) { FunctionBody } GeneratorExpression : function * ( FormalParameters ) { GeneratorBody } AsyncGeneratorExpression : async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionExpression : async function ( FormalParameters ) { AsyncFunctionBody } ArrowFunction : ArrowParameters => ConciseBody AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody ClassExpression : class ClassTail
  1. 返回 false
FunctionExpression : function BindingIdentifier ( FormalParameters ) { FunctionBody } GeneratorExpression : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionExpression : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } ClassExpression : class BindingIdentifier ClassTail
  1. 返回 true

8.4.2 静态语义:IsFunctionDefinition

The syntax-directed operation 静态语义:IsFunctionDefinition takes no arguments and returns 一个 Boolean. It is defined piecewise over the following productions:

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprCoverParenthesizedExpressionAndArrowParameterList覆盖ParenthesizedExpression
  2. 返回 expr 的 IsFunctionDefinition。
PrimaryExpression : this IdentifierReference Literal ArrayLiteral ObjectLiteral RegularExpressionLiteral TemplateLiteral MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier NewExpression : new NewExpression LeftHandSideExpression : CallExpression OptionalExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression LogicalANDExpression : LogicalANDExpression && BitwiseORExpression LogicalORExpression : LogicalORExpression || LogicalANDExpression CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression AssignmentExpression : YieldExpression LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression Expression : Expression , AssignmentExpression
  1. 返回 false
AssignmentExpression : ArrowFunction AsyncArrowFunction FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody } ClassExpression : class BindingIdentifieropt ClassTail
  1. 返回 true

8.4.3 静态语义:IsAnonymousFunctionDefinition ( expr )

The abstract operation 静态语义:IsAnonymousFunctionDefinition takes argument expr (一个 AssignmentExpression Parse Node、一个 Initializer Parse Node、或一个 Expression Parse Node) and returns 一个 Boolean. 用于判定其参数是否为未绑定名称的函数定义。 It performs the following steps when called:

  1. 如果 expr 的 IsFunctionDefinition 为 false,返回 false
  2. hasNameexpr 的 HasName。
  3. 如果 hasNametrue,返回 false
  4. 返回 true

8.4.4 静态语义:IsIdentifierRef

The syntax-directed operation 静态语义:IsIdentifierRef takes no arguments and returns 一个 Boolean. It is defined piecewise over the following productions:

PrimaryExpression : IdentifierReference
  1. 返回 true
PrimaryExpression : this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral CoverParenthesizedExpressionAndArrowParameterList MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier NewExpression : new NewExpression LeftHandSideExpression : CallExpression OptionalExpression
  1. 返回 false

8.4.5 运行时语义:NamedEvaluation

The syntax-directed operation 运行时语义:NamedEvaluation takes argument name (一个属性键或一个 Private Name) and returns 返回包含一个函数对象正常完成或一个异常完成. It is defined piecewise over the following productions:

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprCoverParenthesizedExpressionAndArrowParameterList覆盖ParenthesizedExpression
  2. 返回 ? expr 的 NamedEvaluation(参数 name)。
ParenthesizedExpression : ( Expression )
  1. 断言:IsAnonymousFunctionDefinition(Expression) 为 true
  2. 返回 ? Expression 的 NamedEvaluation(参数 name)。
FunctionExpression : function ( FormalParameters ) { FunctionBody }
  1. 返回 FunctionExpression 的 InstantiateOrdinaryFunctionExpression(参数 name)。
GeneratorExpression : function * ( FormalParameters ) { GeneratorBody }
  1. 返回 GeneratorExpression 的 InstantiateGeneratorFunctionExpression(参数 name)。
AsyncGeneratorExpression : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. 返回 AsyncGeneratorExpression 的 InstantiateAsyncGeneratorFunctionExpression(参数 name)。
AsyncFunctionExpression : async function ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 AsyncFunctionExpression 的 InstantiateAsyncFunctionExpression(参数 name)。
ArrowFunction : ArrowParameters => ConciseBody
  1. 返回 ArrowFunction 的 InstantiateArrowFunctionExpression(参数 name)。
AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. 返回 AsyncArrowFunction 的 InstantiateAsyncArrowFunctionExpression(参数 name)。
ClassExpression : class ClassTail
  1. sourceTextClassExpression 匹配的源文本。
  2. 返回 ? ClassTail 的 ClassDefinitionEvaluation(参数 undefined, name, sourceText)。

8.5 Contains

8.5.1 静态语义:Contains

The syntax-directed operation 静态语义:Contains takes argument symbol (一个语法符号) and returns 一个 Boolean.

本规范中未列于下表的每个语法产生式替代都隐式具有如下默认的 Contains 定义:

  1. 对该解析节点的每个子节点 child,执行
    1. childsymbol 的一个实例,返回 true
    2. child 是一个非终结符实例,则
      1. containedchild Contains symbol 的结果。
      2. containedtrue,返回 true
  2. 返回 false
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 false
Note 1

依赖子结构的静态语义规则通常不会深入函数定义内部。

ClassTail : ClassHeritageopt { ClassBody }
  1. 如果 symbolClassBody,返回 true
  2. 如果 symbolClassHeritage,则
    1. ClassHeritage 存在,返回 true;否则返回 false
  3. ClassHeritage 存在,则
    1. ClassHeritage Contains symboltrue,返回 true
  4. 返回 ClassBody 的 ComputedPropertyContains(参数 symbol)结果。
Note 2

依赖子结构的静态语义规则通常不会深入类主体,除了 PropertyName

ClassStaticBlock : static { ClassStaticBlockBody }
  1. 返回 false
Note 3

依赖子结构的静态语义规则通常不会深入 static 初始化块。

ArrowFunction : ArrowParameters => ConciseBody
  1. symbol 不在 NewTargetSuperPropertySuperCallsuperthis 之列,返回 false
  2. ArrowParameters Contains symboltrue,返回 true
  3. 返回 ConciseBody Contains symbol
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsCoverParenthesizedExpressionAndArrowParameterList覆盖ArrowFormalParameters
  2. 返回 formals Contains symbol
AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody
  1. symbol 不在 NewTargetSuperPropertySuperCallsuperthis 之列,返回 false
  2. 返回 AsyncConciseBody Contains symbol
AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. symbol 不在 NewTargetSuperPropertySuperCallsuperthis 之列,返回 false
  2. headCoverCallExpressionAndAsyncArrowHead覆盖AsyncArrowHead
  3. head Contains symboltrue,返回 true
  4. 返回 AsyncConciseBody Contains symbol
Note 4

Contains 用于在 ArrowFunctionAsyncArrowFunction 中检测 new.targetthissuper 的使用。

PropertyDefinition : MethodDefinition
  1. 如果 symbolMethodDefinition,返回 true
  2. 返回 MethodDefinition 的 ComputedPropertyContains(参数 symbol)结果。
LiteralPropertyName : IdentifierName
  1. 返回 false
MemberExpression : MemberExpression . IdentifierName
  1. MemberExpression Contains symboltrue,返回 true
  2. 返回 false
SuperProperty : super . IdentifierName
  1. symbol 是保留字 super,返回 true
  2. 返回 false
CallExpression : CallExpression . IdentifierName
  1. CallExpression Contains symboltrue,返回 true
  2. 返回 false
OptionalChain : ?. IdentifierName
  1. 返回 false
OptionalChain : OptionalChain . IdentifierName
  1. OptionalChain Contains symboltrue,返回 true
  2. 返回 false

8.5.2 静态语义:ComputedPropertyContains

The syntax-directed operation 静态语义:ComputedPropertyContains takes argument symbol (一个语法符号) and returns 一个 Boolean. It is defined piecewise over the following productions:

ClassElementName : PrivateIdentifier PropertyName : LiteralPropertyName
  1. 返回 false
PropertyName : ComputedPropertyName
  1. 返回 ComputedPropertyName Contains symbol 的结果。
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. 返回 ClassElementName 的 ComputedPropertyContains(参数 symbol)结果。
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. 返回 ClassElementName 的 ComputedPropertyContains(参数 symbol)结果。
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. 返回 ClassElementName 的 ComputedPropertyContains(参数 symbol)结果。
ClassElementList : ClassElementList ClassElement
  1. inListClassElementList 的 ComputedPropertyContains(参数 symbol)。
  2. inListtrue,返回 true
  3. 返回 ClassElement 的 ComputedPropertyContains(参数 symbol)结果。
ClassElement : ClassStaticBlock
  1. 返回 false
ClassElement : ;
  1. 返回 false
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. 返回 ClassElementName 的 ComputedPropertyContains(参数 symbol)结果。
FieldDefinition : ClassElementName Initializeropt
  1. 返回 ClassElementName 的 ComputedPropertyContains(参数 symbol)结果。

8.6 其它 (Miscellaneous)

这些操作在规范的多个位置被使用。

8.6.1 运行时语义:InstantiateFunctionObject

The syntax-directed operation 运行时语义:InstantiateFunctionObject takes arguments env (一个 Environment Record) and privateEnv (一个 PrivateEnvironment Recordnull) and returns 一个 ECMAScript 函数对象. It is defined piecewise over the following productions:

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody }
  1. 返回 FunctionDeclaration 的 InstantiateOrdinaryFunctionObject(参数 envprivateEnv)。
GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody }
  1. 返回 GeneratorDeclaration 的 InstantiateGeneratorFunctionObject(参数 envprivateEnv)。
AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. 返回 AsyncGeneratorDeclaration 的 InstantiateAsyncGeneratorFunctionObject(参数 envprivateEnv)。
AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 AsyncFunctionDeclaration 的 InstantiateAsyncFunctionObject(参数 envprivateEnv)。

8.6.2 运行时语义:BindingInitialization

The syntax-directed operation 运行时语义:BindingInitialization takes arguments value (一个 ECMAScript 语言值) and environment (一个 Environment Recordundefined) and returns 返回包含 unused正常完成或一个异常完成.

Note

environment 传入 undefined 时表示应使用 PutValue 操作来赋值初始化值。对于 var 语句以及某些非严格函数的形式参数列表即是这种情况(参见 10.2.11)。在这些情况下词法绑定在其初始化器求值前被提升并预初始化。

It is defined piecewise over the following productions:

BindingIdentifier : Identifier
  1. nameIdentifier 的 StringValue。
  2. 返回 ? InitializeBoundName(name, value, environment)。
BindingIdentifier : yield
  1. 返回 ? InitializeBoundName("yield", value, environment)。
BindingIdentifier : await
  1. 返回 ? InitializeBoundName("await", value, environment)。
BindingPattern : ObjectBindingPattern
  1. 执行 ? RequireObjectCoercible(value)。
  2. 返回 ? ObjectBindingPattern 的 BindingInitialization(参数 value, environment)。
BindingPattern : ArrayBindingPattern
  1. iteratorRecord 为 ? GetIterator(value, sync)。
  2. resultCompletion(ArrayBindingPattern 的 IteratorBindingInitialization(参数 iteratorRecord, environment))。
  3. 如果 iteratorRecord.[[Done]]false,返回 ? IteratorClose(iteratorRecord, result)。
  4. 返回 ? result
ObjectBindingPattern : { }
  1. 返回 unused
ObjectBindingPattern : { BindingPropertyList } { BindingPropertyList , }
  1. 执行 ? BindingPropertyList 的 PropertyBindingInitialization(参数 value, environment)。
  2. 返回 unused
ObjectBindingPattern : { BindingRestProperty }
  1. excludedNames 为新的空列表。
  2. 返回 ? BindingRestProperty 的 RestBindingInitialization(参数 value, environment, excludedNames)。
ObjectBindingPattern : { BindingPropertyList , BindingRestProperty }
  1. excludedNames 为 ? BindingPropertyList 的 PropertyBindingInitialization(参数 value, environment)。
  2. 返回 ? BindingRestProperty 的 RestBindingInitialization(参数 value, environment, excludedNames)。

8.6.2.1 InitializeBoundName ( name, value, environment )

The abstract operation InitializeBoundName takes arguments name (一个 String), value (一个 ECMAScript 语言值), and environment (一个 Environment Recordundefined) and returns 返回包含 unused正常完成或一个异常完成. It performs the following steps when called:

  1. 如果 environment 不为 undefined,则
    1. 执行 ! environment.InitializeBinding(name, value)。
    2. 返回 unused
  2. 否则,
    1. lhs 为 ? ResolveBinding(name)。
    2. 返回 ? PutValue(lhs, value)。

8.6.3 运行时语义:IteratorBindingInitialization

The syntax-directed operation 运行时语义:IteratorBindingInitialization takes arguments iteratorRecord (一个 Iterator Record) and environment (一个 Environment Recordundefined) and returns 返回包含 unused正常完成或一个异常完成.

Note

environmentundefined 时表示应使用 PutValue 操作来赋初始化值。这用于非严格函数的形式参数列表,在那种情况下形式参数绑定会被预初始化以应对同名参数出现的可能。

It is defined piecewise over the following productions:

ArrayBindingPattern : [ ]
  1. 返回 unused
ArrayBindingPattern : [ Elision ]
  1. 返回 ? Elision 的 IteratorDestructuringAssignmentEvaluation(参数 iteratorRecord)。
ArrayBindingPattern : [ Elisionopt BindingRestElement ]
  1. 如果 Elision 存在,则
    1. 执行 ? Elision 的 IteratorDestructuringAssignmentEvaluation(参数 iteratorRecord)。
  2. 返回 ? BindingRestElement 的 IteratorBindingInitialization(参数 iteratorRecord, environment)。
ArrayBindingPattern : [ BindingElementList , Elision ]
  1. 执行 ? BindingElementList 的 IteratorBindingInitialization(参数 iteratorRecord, environment)。
  2. 返回 ? Elision 的 IteratorDestructuringAssignmentEvaluation(参数 iteratorRecord)。
ArrayBindingPattern : [ BindingElementList , Elisionopt BindingRestElement ]
  1. 执行 ? BindingElementList 的 IteratorBindingInitialization(参数 iteratorRecord, environment)。
  2. 如果 Elision 存在,则
    1. 执行 ? Elision 的 IteratorDestructuringAssignmentEvaluation(参数 iteratorRecord)。
  3. 返回 ? BindingRestElement 的 IteratorBindingInitialization(参数 iteratorRecord, environment)。
BindingElementList : BindingElementList , BindingElisionElement
  1. 执行 ? BindingElementList 的 IteratorBindingInitialization(参数 iteratorRecord, environment)。
  2. 返回 ? BindingElisionElement 的 IteratorBindingInitialization(参数 iteratorRecord, environment)。
BindingElisionElement : Elision BindingElement
  1. 执行 ? Elision 的 IteratorDestructuringAssignmentEvaluation(参数 iteratorRecord)。
  2. 返回 ? BindingElement 的 IteratorBindingInitialization(参数 iteratorRecord, environment)。
SingleNameBinding : BindingIdentifier Initializeropt
  1. bindingIdBindingIdentifier 的 StringValue。
  2. lhs 为 ? ResolveBinding(bindingId, environment)。
  3. vundefined
  4. 如果 iteratorRecord.[[Done]]false,则
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 next 不是 done,则
      1. vnext
  5. 如果 Initializer 存在且 vundefined,则
    1. 如果 IsAnonymousFunctionDefinition(Initializer) 为 true,则
      1. v 为 ? Initializer 的 NamedEvaluation(参数 bindingId)。
    2. 否则,
      1. defaultValue 为 ? Initializer 的 Evaluation。
      2. v 为 ? GetValue(defaultValue)。
  6. 如果 environmentundefined,返回 ? PutValue(lhs, v)。
  7. 返回 ? InitializeReferencedBinding(lhs, v)。
BindingElement : BindingPattern Initializeropt
  1. vundefined
  2. 如果 iteratorRecord.[[Done]]false,则
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 next 不是 done,则
      1. vnext
  3. 如果 Initializer 存在且 vundefined,则
    1. defaultValue 为 ? Initializer 的 Evaluation。
    2. v 为 ? GetValue(defaultValue)。
  4. 返回 ? BindingPattern 的 BindingInitialization(参数 v, environment)。
BindingRestElement : ... BindingIdentifier
  1. lhs 为 ? ResolveBinding(StringValue of BindingIdentifier, environment)。
  2. A 为 ! ArrayCreate(0)。
  3. n 为 0。
  4. 重复,
    1. nextdone
    2. 如果 iteratorRecord.[[Done]]false,则
      1. next 为 ? IteratorStepValue(iteratorRecord)。
    3. 如果 nextdone,则
      1. 如果 environmentundefined,返回 ? PutValue(lhs, A)。
      2. 返回 ? InitializeReferencedBinding(lhs, A)。
    4. 执行 ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), next)。
    5. nn + 1。
BindingRestElement : ... BindingPattern
  1. A 为 ! ArrayCreate(0)。
  2. n 为 0。
  3. 重复,
    1. nextdone
    2. 如果 iteratorRecord.[[Done]]false,则
      1. next 为 ? IteratorStepValue(iteratorRecord)。
    3. 如果 nextdone,则
      1. 返回 ? BindingPattern 的 BindingInitialization(参数 A, environment)。
    4. 执行 ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), next)。
    5. nn + 1。
FormalParameters : [empty]
  1. 返回 unused
FormalParameters : FormalParameterList , FunctionRestParameter
  1. 执行 ? FormalParameterList 的 IteratorBindingInitialization(参数 iteratorRecord, environment)。
  2. 返回 ? FunctionRestParameter 的 IteratorBindingInitialization(参数 iteratorRecord, environment)。
FormalParameterList : FormalParameterList , FormalParameter
  1. 执行 ? FormalParameterList 的 IteratorBindingInitialization(参数 iteratorRecord, environment)。
  2. 返回 ? FormalParameter 的 IteratorBindingInitialization(参数 iteratorRecord, environment)。
ArrowParameters : BindingIdentifier
  1. vundefined
  2. 断言:iteratorRecord.[[Done]]false
  3. next 为 ? IteratorStepValue(iteratorRecord)。
  4. 如果 next 不是 done,则
    1. vnext
  5. 返回 ? BindingIdentifier 的 BindingInitialization(参数 v, environment)。
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsCoverParenthesizedExpressionAndArrowParameterList覆盖ArrowFormalParameters
  2. 返回 ? formals 的 IteratorBindingInitialization(参数 iteratorRecord, environment)。
AsyncArrowBindingIdentifier : BindingIdentifier
  1. vundefined
  2. 断言:iteratorRecord.[[Done]]false
  3. next 为 ? IteratorStepValue(iteratorRecord)。
  4. 如果 next 不是 done,则
    1. vnext
  5. 返回 ? BindingIdentifier 的 BindingInitialization(参数 v, environment)。

8.6.4 静态语义:AssignmentTargetType

The syntax-directed operation 静态语义:AssignmentTargetType takes no arguments and returns simpleweb-compatinvalid. It is defined piecewise over the following productions:

IdentifierReference : Identifier
  1. 如果 IsStrict(this IdentifierReference) 为 trueIdentifier 的 StringValue 是 "eval""arguments",返回 invalid
  2. 返回 simple
IdentifierReference : yield await CallExpression : CallExpression [ Expression ] CallExpression . IdentifierName CallExpression . PrivateIdentifier MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName SuperProperty MemberExpression . PrivateIdentifier
  1. 返回 simple
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprCoverParenthesizedExpressionAndArrowParameterList覆盖ParenthesizedExpression
  2. 返回 expr 的 AssignmentTargetType。
CallExpression : CoverCallExpressionAndAsyncArrowHead CallExpression Arguments
  1. Normative Optional
    如果宿主是 Web 浏览器或以其他方式支持 函数调用赋值目标的运行时错误 且 IsStrict(this CallExpression) 为 false,则
    1. 返回 web-compat
  2. 返回 invalid
PrimaryExpression : this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral CallExpression : SuperCall ImportCall CallExpression TemplateLiteral NewExpression : new NewExpression MemberExpression : MemberExpression TemplateLiteral new MemberExpression Arguments NewTarget : new . target ImportMeta : import . meta LeftHandSideExpression : OptionalExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression LogicalANDExpression : LogicalANDExpression && BitwiseORExpression LogicalORExpression : LogicalORExpression || LogicalANDExpression CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression AssignmentExpression : YieldExpression ArrowFunction AsyncArrowFunction LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression Expression : Expression , AssignmentExpression
  1. 返回 invalid

8.6.5 静态语义:PropName

The syntax-directed operation 静态语义:PropName takes no arguments and returns 一个 String 或 empty. It is defined piecewise over the following productions:

PropertyDefinition : IdentifierReference
  1. 返回 IdentifierReference 的 StringValue。
PropertyDefinition : ... AssignmentExpression
  1. 返回 empty
PropertyDefinition : PropertyName : AssignmentExpression
  1. 返回 PropertyName 的 PropName。
LiteralPropertyName : IdentifierName AttributeKey : IdentifierName
  1. 返回 IdentifierName 的 StringValue。
LiteralPropertyName : StringLiteral AttributeKey : StringLiteral
  1. 返回 StringLiteral 的 SV。
LiteralPropertyName : NumericLiteral
  1. nbrNumericLiteral 的 NumericValue。
  2. 返回 ! ToString(nbr)。
ComputedPropertyName : [ AssignmentExpression ]
  1. 返回 empty
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. 返回 ClassElementName 的 PropName。
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. 返回 ClassElementName 的 PropName。
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. 返回 ClassElementName 的 PropName。
ClassElement : ClassStaticBlock
  1. 返回 empty
ClassElement : ;
  1. 返回 empty
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. 返回 ClassElementName 的 PropName。
FieldDefinition : ClassElementName Initializeropt
  1. 返回 ClassElementName 的 PropName。
ClassElementName : PrivateIdentifier
  1. 返回 empty

9 可执行代码与执行上下文 (Executable Code and Execution Contexts)

9.1 环境记录 (Environment Records)

Environment Record 是一种规范类型,用于基于 ECMAScript 代码的词法嵌套结构,将 Identifier 与特定变量及函数建立关联。通常一个 Environment Record 与某个特定的 ECMAScript 语法结构关联,如 FunctionDeclarationBlockStatementTryStatementCatch 子句。每当这类代码被求值时,就会新建一个 Environment Record,用来记录该代码创建的标识符绑定。

每个 Environment Record 都有一个 [[OuterEnv]] 字段,其值为 null 或指向一个外层 Environment Record,用来建模 Environment Record 值的逻辑嵌套。一个(内层)Environment Record 的外层引用指向在逻辑上包围它的 Environment Record。外层 Environment Record 当然也可以再有自己的外层引用。一个 Environment Record 可以作为多个内层 Environment Record 的外层环境。例如,若一个 FunctionDeclaration 内含两个嵌套的 FunctionDeclaration,那么这两个嵌套函数的 Environment Record 的外层 Environment Record 都是外层函数当前求值对应的 Environment Record。

Environment Record 纯属规范机制,不需要对应到 ECMAScript 实现中的任何具体产物。ECMAScript 程序无法直接访问或操纵这些值。

9.1.1 Environment Record 类型层次 (The Environment Record Type Hierarchy)

可以将 Environment Record 看作是一个简单的面向对象层次结构:Environment Record 是一个抽象类,具有三个具体子类:Declarative Environment RecordObject Environment RecordGlobal Environment RecordFunction Environment RecordModule Environment RecordDeclarative Environment Record 的子类。

Environment Record 抽象类包含 Table 14 中定义的抽象规范方法。这些抽象方法在各具体子类上有不同的具体算法。

Table 14: Environment Record 的抽象方法
方法 目的
HasBinding(N) 判断 Environment Record 是否存在字符串值 N 的绑定;存在返回 true,否则返回 false
CreateMutableBinding(N, D) 创建一个新的、未初始化的可变绑定。字符串 N 为名称文本。若布尔参数 Dtrue,该绑定之后可删除。
CreateImmutableBinding(N, S) 创建新的、未初始化的不可变绑定。字符串 N 为名称文本。若 Strue,初始化后再设置将始终抛出异常(与引用该绑定的操作是否严格模式无关)。
InitializeBinding(N, V) 为已存在但未初始化的绑定设置值。N 为名称文本,V 为任意 ECMAScript 语言类型的值。
SetMutableBinding(N, V, S) 为已存在的可变绑定设置值 VS 为布尔标记;若 Strue 且绑定无法被设置则抛出 TypeError
GetBindingValue(N, S) 返回已存在绑定的值。S 标记引用是否源自严格模式(或需要严格语义)。若 Strue 且绑定不存在抛 ReferenceError。若绑定存在但未初始化,无论 S 值为何都抛 ReferenceError
DeleteBinding(N) 删除名称为 N 的绑定。存在则移除并返回 true;存在但不可移除返回 false;不存在返回 true
HasThisBinding() 判断是否建立 this 绑定;是返回 true,否则 false
HasSuperBinding() 判断是否建立 super 方法绑定;是返回 true,否则 false。若返回 true 则表明该记录是 Function Environment Record(反之不一定)。
WithBaseObject() 若该 Environment Recordwith 语句关联则返回其对象;否则返回 undefined

9.1.1.1 声明式环境记录 (Declarative Environment Records)

每个 Declarative Environment Record 与一个 ECMAScript 程序作用域关联,该作用域包含变量、常量、let、class、module、import 以及(或)函数声明。Declarative Environment Record 绑定其作用域内声明定义的标识符集合。

9.1.1.1.1 HasBinding ( N )

The HasBinding concrete method of takes argument N (一个 String) and returns 一个包含 Boolean 的正常完成. It performs the following steps when called:

  1. envRecN 有绑定,返回 true
  2. 返回 false

9.1.1.1.2 CreateMutableBinding ( N, D )

The CreateMutableBinding concrete method of takes arguments N (一个 String) and D (一个 Boolean) and returns 一个包含 unused正常完成. It performs the following steps when called:

  1. 断言:envRec 尚无 N 绑定。
  2. envRec 中创建 N 的可变绑定并记录其未初始化。若 Dtrue,记录该绑定可被后续 DeleteBinding 删除。
  3. 返回 unused

9.1.1.1.3 CreateImmutableBinding ( N, S )

The CreateImmutableBinding concrete method of takes arguments N (一个 String) and S (一个 Boolean) and returns 一个包含 unused正常完成. It performs the following steps when called:

  1. 断言:envRec 尚无 N 绑定。
  2. envRec 中创建 N 的不可变绑定并记录其未初始化。若 Strue,记录其为严格绑定。
  3. 返回 unused

9.1.1.1.4 InitializeBinding ( N, V )

The InitializeBinding concrete method of takes arguments N (一个 String) and V (一个 ECMAScript 语言值) and returns 一个包含 unused正常完成. It performs the following steps when called:

  1. 断言:envRec 必须有 N 的未初始化绑定。
  2. envRecN 的绑定值设为 V
  3. 记录 envRecN 的绑定已被初始化。
  4. 返回 unused

9.1.1.1.5 SetMutableBinding ( N, V, S )

The SetMutableBinding concrete method of takes arguments N (一个 String), V (一个 ECMAScript 语言值), and S (一个 Boolean) and returns 一个包含 unused正常完成或一个抛出完成. It performs the following steps when called:

  1. envRecN 绑定,则
    1. Strue,抛 ReferenceError
    2. 执行 ! envRec.CreateMutableBinding(N, true)。
    3. 执行 ! envRec.InitializeBinding(N, V)。
    4. 返回 unused
  2. envRecN 的绑定是严格绑定,将 S 设为 true
  3. envRecN 的绑定尚未初始化,则
    1. ReferenceError
  4. 否则若为可变绑定,
    1. 将其值改为 V
  5. 否则,
    1. 断言:正在尝试修改不可变绑定的值。
    2. Strue,抛 TypeError
  6. 返回 unused
Note

导致在步骤 1 出现缺失绑定的 ECMAScript 示例:

function f() { eval("var x; x = (delete x, 0);"); }

9.1.1.1.6 GetBindingValue ( N, S )

The GetBindingValue concrete method of takes arguments N (一个 String) and S (一个 Boolean) and returns 一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. 断言:envRecN 的绑定。
  2. 若其为未初始化绑定,抛 ReferenceError
  3. 返回当前绑定于 N 的值。

9.1.1.1.7 DeleteBinding ( N )

The DeleteBinding concrete method of takes argument N (一个 String) and returns 一个包含 Boolean 的正常完成. It performs the following steps when called:

  1. 断言:envRecN 的绑定。
  2. 若该绑定不可删除,返回 false
  3. envRec 移除该绑定。
  4. 返回 true

9.1.1.1.8 HasThisBinding ( )

The HasThisBinding concrete method of takes no arguments and returns false. It performs the following steps when called:

  1. 返回 false
Note

普通 Declarative Environment Record(即既不是 Function 也不是 Module Environment Record)不提供 this 绑定。

9.1.1.1.9 HasSuperBinding ( )

The HasSuperBinding concrete method of takes no arguments and returns false. It performs the following steps when called:

  1. 返回 false
Note

普通 Declarative Environment Record 不提供 super 绑定。

9.1.1.1.10 WithBaseObject ( )

The WithBaseObject concrete method of takes no arguments and returns undefined. It performs the following steps when called:

  1. 返回 undefined

9.1.1.2 对象环境记录 (Object Environment Records)

每个 Object Environment Record 关联一个称为其 binding object 的对象。它绑定该对象属性名中与字符串标识符名称直接对应的集合。不是 IdentifierName 形式字符串的属性键不计入。集合包含自有与继承属性,与其 [[Enumerable]] 属性设置无关。由于对象属性可动态添加/删除,对应绑定集合可能随任何添加或删除属性的操作产生副作用而变化。副作用新增的绑定被视为可变绑定,即使对应属性的 Writable 为 false。Object Environment Record 不存在不可变绑定。

with 语句(14.11)创建的 Object Environment Record 可以在函数调用中将其绑定对象作为隐式 this 值。该能力由布尔字段 [[IsWithEnvironment]] 控制。

Object Environment Record 具有 Table 15 所列附加状态字段。

Table 15: Object Environment Record 的附加字段
字段名 含义
[[BindingObject]] 一个 Object Environment Record 的绑定对象。
[[IsWithEnvironment]] 一个 Boolean 指示该记录是否为 with 语句创建。

9.1.1.2.1 HasBinding ( N )

The HasBinding concrete method of takes argument N (一个 String) and returns 一个包含 Boolean 的正常完成或抛出完成. It performs the following steps when called:

  1. bindingObjectenvRec.[[BindingObject]]
  2. foundBinding 为 ? HasProperty(bindingObject, N)。
  3. foundBindingfalse,返回 false
  4. envRec.[[IsWithEnvironment]]false,返回 true
  5. unscopables 为 ? Get(bindingObject, %Symbol.unscopables%)。
  6. unscopables 是 Object,则
    1. blockedToBoolean(? Get(unscopables, N))。
    2. blockedtrue,返回 false
  7. 返回 true

9.1.1.2.2 CreateMutableBinding ( N, D )

The CreateMutableBinding concrete method of takes arguments N (一个 String) and D (一个 Boolean) and returns 一个包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. bindingObjectenvRec.[[BindingObject]]
  2. 执行 ? DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D })。
  3. 返回 unused
Note

通常 envRec 不会已有 N 绑定;若已存在,DefinePropertyOrThrow 的语义可能替换、遮蔽或抛出异常。

9.1.1.2.3 CreateImmutableBinding ( N, S )

Object Environment Record 的 CreateImmutableBinding 具体方法在本规范中从未使用。

9.1.1.2.4 InitializeBinding ( N, V )

The InitializeBinding concrete method of takes arguments N (一个 String) and V (一个 ECMAScript 语言值) and returns 一个包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. 执行 ? envRec.SetMutableBinding(N, V, false)。
  2. 返回 unused
Note

在本规范中,对 Object Environment Record 调用 CreateMutableBinding 后立即调用 InitializeBinding,因此不显式跟踪其初始化状态。

9.1.1.2.5 SetMutableBinding ( N, V, S )

The SetMutableBinding concrete method of takes arguments N (一个 String), V (一个 ECMAScript 语言值), and S (一个 Boolean) and returns 一个包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. bindingObjectenvRec.[[BindingObject]]
  2. stillExists 为 ? HasProperty(bindingObject, N)。
  3. stillExistsfalseStrue,抛 ReferenceError
  4. 执行 ? Set(bindingObject, N, V, S)。
  5. 返回 unused

9.1.1.2.6 GetBindingValue ( N, S )

The GetBindingValue concrete method of takes arguments N (一个 String) and S (一个 Boolean) and returns 一个包含 ECMAScript 语言值正常完成或抛出完成. It performs the following steps when called:

  1. bindingObjectenvRec.[[BindingObject]]
  2. value 为 ? HasProperty(bindingObject, N)。
  3. valuefalse,则
    1. Sfalse,返回 undefined;否则抛 ReferenceError
  4. 返回 ? Get(bindingObject, N)。

9.1.1.2.7 DeleteBinding ( N )

The DeleteBinding concrete method of takes argument N (一个 String) and returns 一个包含 Boolean 的正常完成或抛出完成. It performs the following steps when called:

  1. bindingObjectenvRec.[[BindingObject]]
  2. 返回 ? bindingObject.[[Delete]](N)。

9.1.1.2.8 HasThisBinding ( )

The HasThisBinding concrete method of takes no arguments and returns false. It performs the following steps when called:

  1. 返回 false
Note

Object Environment Record 不提供 this 绑定。

9.1.1.2.9 HasSuperBinding ( )

The HasSuperBinding concrete method of takes no arguments and returns false. It performs the following steps when called:

  1. 返回 false
Note

Object Environment Record 不提供 super 绑定。

9.1.1.2.10 WithBaseObject ( )

The WithBaseObject concrete method of takes no arguments and returns 一个 Object 或 undefined. It performs the following steps when called:

  1. envRec.[[IsWithEnvironment]]true,返回 envRec.[[BindingObject]]
  2. 否则返回 undefined

9.1.1.3 函数环境记录 (Function Environment Records)

Function Environment Record 是一个 Declarative Environment Record,表示函数的顶层作用域,并且若函数不是 ArrowFunction,则提供 this 绑定。若一个非 ArrowFunction 函数引用 super,其 Function Environment Record 也包含执行 super 方法调用所需的状态。

Function Environment Record 有 Table 16 中列出的附加状态字段。

Table 16: Function Environment Record 的附加字段
字段名 含义
[[ThisValue]] 一个 ECMAScript 语言值 此次函数调用使用的 this 值。
[[ThisBindingStatus]] lexical, initialized, 或 uninitialized 若为 lexical,表明是 ArrowFunction,无本地 this
[[FunctionObject]] 一个 ECMAScript 函数对象 其调用导致此 Environment Record 被创建的函数对象
[[NewTarget]] 一个 constructor 或 undefined 若由 [[Construct]] 创建,则为该内部方法 newTarget 参数;否则为 undefined

Function Environment Record 支持 Table 14 中列出的所有 Declarative Environment Record 方法,除 HasThisBinding 与 HasSuperBinding 外与其规范相同;另外支持 Table 17 中列出的方法:

Table 17: Function Environment Record 的附加方法
方法 目的
GetThisBinding() 返回该 Environment Recordthis 绑定值,若尚未初始化则抛 ReferenceError

9.1.1.3.1 BindThisValue ( envRec, V )

The abstract operation BindThisValue takes arguments envRec (一个 Function Environment Record) and V (一个 ECMAScript 语言值) and returns 一个包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. 断言:envRec.[[ThisBindingStatus]] 不为 lexical
  2. envRec.[[ThisBindingStatus]]initialized,抛 ReferenceError
  3. envRec.[[ThisValue]]V
  4. envRec.[[ThisBindingStatus]]initialized
  5. 返回 unused

9.1.1.3.2 HasThisBinding ( )

The HasThisBinding concrete method of takes no arguments and returns 一个 Boolean. It performs the following steps when called:

  1. envRec.[[ThisBindingStatus]]lexical,返回 false;否则返回 true

9.1.1.3.3 HasSuperBinding ( )

The HasSuperBinding concrete method of takes no arguments and returns 一个 Boolean. It performs the following steps when called:

  1. envRec.[[ThisBindingStatus]]lexical,返回 false
  2. envRec.[[FunctionObject]].[[HomeObject]]undefined,返回 false;否则返回 true

9.1.1.3.4 GetThisBinding ( )

The GetThisBinding concrete method of takes no arguments and returns 一个包含 ECMAScript 语言值正常完成或抛出完成. It performs the following steps when called:

  1. 断言:envRec.[[ThisBindingStatus]] 不为 lexical
  2. envRec.[[ThisBindingStatus]]uninitialized,抛 ReferenceError
  3. 返回 envRec.[[ThisValue]]

9.1.1.3.5 GetSuperBase ( envRec )

The abstract operation GetSuperBase takes argument envRec (一个 Function Environment Record) and returns 一个 Object、nullundefined. It performs the following steps when called:

  1. homeenvRec.[[FunctionObject]].[[HomeObject]]
  2. homeundefined,返回 undefined
  3. 断言:home普通对象
  4. 返回 ! home.[[GetPrototypeOf]]()。

9.1.1.4 全局环境记录 (Global Environment Records)

Global Environment Record 表示在同一 realm 中处理的所有 ECMAScript Script 元素共享的最外层作用域。提供内置全局(19)、全局对象属性以及所有顶层声明(8.2.98.2.11)的绑定。

Global Environment Record 在逻辑上是单一记录,但被描述为封装一个 Object Environment Record 和一个 Declarative Environment Record 的复合体。Object Environment Record 的基对象为关联 Realm Record 的全局对象。该全局对象是其 GetThisBinding 具体方法返回的值。Object 组件包含内置全局与由 FunctionDeclarationGeneratorDeclarationAsyncFunctionDeclarationAsyncGeneratorDeclarationVariableStatement 引入的全局代码绑定;其余声明的绑定位于 Declarative 组件。

可以直接在全局对象上创建属性,因此 Object 组件可能同时包含通过声明显式创建的绑定与作为全局对象属性隐式创建的绑定。为区分通过声明显式创建的绑定,Global Environment Record 维护使用 CreateGlobalVarBindingCreateGlobalFunctionBinding 创建的名称列表。

Global Environment Record 具有 Table 18 中的附加字段和 Table 19 中的附加方法。

Table 18: Global Environment Record 的附加字段
字段名 含义
[[ObjectRecord]] 一个 Object Environment Record 绑定对象是全局对象,包含全局内置绑定以及全局代码中 FunctionDeclarationGeneratorDeclarationAsyncFunctionDeclarationAsyncGeneratorDeclarationVariableDeclaration 的绑定。
[[GlobalThisValue]] 一个 Object 全局作用域中 this 返回的值;宿主可提供任意 ECMAScript Object。
[[DeclarativeRecord]] 一个 Declarative Environment Record 包含 全局代码中除 FunctionDeclarationGeneratorDeclarationAsyncFunctionDeclarationAsyncGeneratorDeclarationVariableDeclaration 外所有声明的绑定。
Table 19: Global Environment Record 的附加方法
方法 目的
GetThisBinding() 返回该 Environment Recordthis 绑定。

9.1.1.4.1 HasBinding ( N )

The HasBinding concrete method of takes argument N (一个 String) and returns 一个包含 Boolean 的正常完成或抛出完成. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]
  2. 若 ! DclRec.HasBinding(N) 为 true,返回 true
  3. ObjRecenvRec.[[ObjectRecord]]
  4. 返回 ? ObjRec.HasBinding(N)。

9.1.1.4.2 CreateMutableBinding ( N, D )

The CreateMutableBinding concrete method of takes arguments N (一个 String) and D (一个 Boolean) and returns 一个包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]
  2. 若 ! DclRec.HasBinding(N) 为 true,抛 TypeError
  3. 返回 ! DclRec.CreateMutableBinding(N, D)。

9.1.1.4.3 CreateImmutableBinding ( N, S )

The CreateImmutableBinding concrete method of takes arguments N (一个 String) and S (一个 Boolean) and returns 一个包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]
  2. 若 ! DclRec.HasBinding(N) 为 true,抛 TypeError
  3. 返回 ! DclRec.CreateImmutableBinding(N, S)。

9.1.1.4.4 InitializeBinding ( N, V )

The InitializeBinding concrete method of takes arguments N (一个 String) and V (一个 ECMAScript 语言值) and returns 一个包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]
  2. 若 ! DclRec.HasBinding(N) 为 true,则
    1. 返回 ! DclRec.InitializeBinding(N, V)。
  3. 断言:若存在绑定则位于 Object Environment Record 中。
  4. ObjRecenvRec.[[ObjectRecord]]
  5. 返回 ? ObjRec.InitializeBinding(N, V)。

9.1.1.4.5 SetMutableBinding ( N, V, S )

The SetMutableBinding concrete method of takes arguments N (一个 String), V (一个 ECMAScript 语言值), and S (一个 Boolean) and returns 一个包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]
  2. 若 ! DclRec.HasBinding(N) 为 true,则
    1. 返回 ? DclRec.SetMutableBinding(N, V, S)。
  3. ObjRecenvRec.[[ObjectRecord]]
  4. 返回 ? ObjRec.SetMutableBinding(N, V, S)。

9.1.1.4.6 GetBindingValue ( N, S )

The GetBindingValue concrete method of takes arguments N (一个 String) and S (一个 Boolean) and returns 一个包含 ECMAScript 语言值正常完成或抛出完成. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]
  2. 若 ! DclRec.HasBinding(N) 为 true,则
    1. 返回 ? DclRec.GetBindingValue(N, S)。
  3. ObjRecenvRec.[[ObjectRecord]]
  4. 返回 ? ObjRec.GetBindingValue(N, S)。

9.1.1.4.7 DeleteBinding ( N )

The DeleteBinding concrete method of takes argument N (一个 String) and returns 一个包含 Boolean 的正常完成或抛出完成. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]
  2. 若 ! DclRec.HasBinding(N) 为 true,则
    1. 返回 ! DclRec.DeleteBinding(N)。
  3. ObjRecenvRec.[[ObjectRecord]]
  4. globalObjectObjRec.[[BindingObject]]
  5. existingProp 为 ? HasOwnProperty(globalObject, N)。
  6. existingProptrue,则
    1. 返回 ? ObjRec.DeleteBinding(N)。
  7. 返回 true

9.1.1.4.8 HasThisBinding ( )

The HasThisBinding concrete method of takes no arguments and returns true. It performs the following steps when called:

  1. 返回 true
Note

Global Environment Record 始终提供 this 绑定。

9.1.1.4.9 HasSuperBinding ( )

The HasSuperBinding concrete method of takes no arguments and returns false. It performs the following steps when called:

  1. 返回 false
Note

Global Environment Record 不提供 super 绑定。

9.1.1.4.10 WithBaseObject ( )

The WithBaseObject concrete method of takes no arguments and returns undefined. It performs the following steps when called:

  1. 返回 undefined

9.1.1.4.11 GetThisBinding ( )

The GetThisBinding concrete method of takes no arguments and returns 一个包含 Object 的正常完成. It performs the following steps when called:

  1. 返回 envRec.[[GlobalThisValue]]

9.1.1.4.12 HasLexicalDeclaration ( envRec, N )

The abstract operation HasLexicalDeclaration takes arguments envRec (一个 Global Environment Record) and N (一个 String) and returns 一个 Boolean. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]
  2. 返回 ! DclRec.HasBinding(N)。

9.1.1.4.13 HasRestrictedGlobalProperty ( envRec, N )

The abstract operation HasRestrictedGlobalProperty takes arguments envRec (一个 Global Environment Record) and N (一个 String) and returns 一个包含 Boolean 的正常完成或抛出完成. It performs the following steps when called:

  1. ObjRecenvRec.[[ObjectRecord]]
  2. globalObjectObjRec.[[BindingObject]]
  3. existingProp 为 ? globalObject.[[GetOwnProperty]](N)。
  4. existingPropundefined,返回 false
  5. existingProp.[[Configurable]]true,返回 false
  6. 返回 true
Note

可直接在全局对象上存在非声明创建的属性。不能创建与全局对象不可配置属性同名的全局词法绑定,例如 "undefined"

9.1.1.4.14 CanDeclareGlobalVar ( envRec, N )

The abstract operation CanDeclareGlobalVar takes arguments envRec (一个 Global Environment Record) and N (一个 String) and returns 一个包含 Boolean 的正常完成或抛出完成. It performs the following steps when called:

  1. ObjRecenvRec.[[ObjectRecord]]
  2. globalObjectObjRec.[[BindingObject]]
  3. hasProperty 为 ? HasOwnProperty(globalObject, N)。
  4. hasPropertytrue,返回 true
  5. 返回 ? IsExtensible(globalObject)。

9.1.1.4.15 CanDeclareGlobalFunction ( envRec, N )

The abstract operation CanDeclareGlobalFunction takes arguments envRec (一个 Global Environment Record) and N (一个 String) and returns 一个包含 Boolean 的正常完成或抛出完成. It performs the following steps when called:

  1. ObjRecenvRec.[[ObjectRecord]]
  2. globalObjectObjRec.[[BindingObject]]
  3. existingProp 为 ? globalObject.[[GetOwnProperty]](N)。
  4. existingPropundefined,返回 ? IsExtensible(globalObject)。
  5. existingProp.[[Configurable]]true,返回 true
  6. IsDataDescriptor(existingProp) 为 trueexistingProp 具属性 { [[Writable]]: true, [[Enumerable]]: true },返回 true
  7. 返回 false

9.1.1.4.16 CreateGlobalVarBinding ( envRec, N, D )

The abstract operation CreateGlobalVarBinding takes arguments envRec (一个 Global Environment Record), N (一个 String), and D (一个 Boolean) and returns 一个包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. ObjRecenvRec.[[ObjectRecord]]
  2. globalObjectObjRec.[[BindingObject]]
  3. hasProperty 为 ? HasOwnProperty(globalObject, N)。
  4. extensible 为 ? IsExtensible(globalObject)。
  5. hasPropertyfalseextensibletrue,则
    1. 执行 ? ObjRec.CreateMutableBinding(N, D)。
    2. 执行 ? ObjRec.InitializeBinding(N, undefined)。
  6. 返回 unused

9.1.1.4.17 CreateGlobalFunctionBinding ( envRec, N, V, D )

The abstract operation CreateGlobalFunctionBinding takes arguments envRec (一个 Global Environment Record), N (一个 String), V (一个 ECMAScript 语言值), and D (一个 Boolean) and returns 一个包含 unused正常完成或抛出完成. It performs the following steps when called:

  1. ObjRecenvRec.[[ObjectRecord]]
  2. globalObjectObjRec.[[BindingObject]]
  3. existingProp 为 ? globalObject.[[GetOwnProperty]](N)。
  4. existingPropundefined 或其 [[Configurable]]true,则
    1. desc 为 PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }。
  5. 否则,
    1. desc 为 PropertyDescriptor { [[Value]]: V }。
  6. 执行 ? DefinePropertyOrThrow(globalObject, N, desc)。
  7. 执行 ? Set(globalObject, N, V, false)。
  8. 返回 unused
Note

全局函数声明总以全局对象自有属性表示;若可行,重配置为标准属性集。步骤 7 等价于调用 InitializeBinding,且若 globalObject 为 Proxy 将产生相同的 trap 调用序列。

9.1.1.5 模块环境记录 (Module Environment Records)

Module Environment Record 是一个 Declarative Environment Record,用于表示 ECMAScript Module 的外层作用域。除普通可变与不可变绑定外,还提供不可变的 import 绑定,这些绑定间接访问另一个 Environment Record 中的目标绑定。

Module Environment Record 支持 Table 14 中列出的所有 Declarative Environment Record 方法,除 GetBindingValue、DeleteBinding、HasThisBinding 与 GetThisBinding 外与其规范相同;另外支持 Table 20 中的方法:

Table 20: Module Environment Record 的附加方法
方法 目的
GetThisBinding() 返回该 Environment Recordthis 绑定值。

9.1.1.5.1 GetBindingValue ( N, S )

The GetBindingValue concrete method of takes arguments N (一个 String) and S (一个 Boolean) and returns 一个包含 ECMAScript 语言值正常完成或抛出完成. It performs the following steps when called:

  1. 断言:Strue
  2. 断言:envRecN 绑定。
  3. N 的绑定是间接绑定,则
    1. MN2 为创建该绑定时提供的间接值。
    2. targetEnvM.[[Environment]]
    3. targetEnvempty,抛 ReferenceError
    4. 返回 ? targetEnv.GetBindingValue(N2, true)。
  4. envRecN 的绑定为未初始化,抛 ReferenceError
  5. 返回当前绑定于 N 的值。
Note

S 始终为 true,因为 Module 总是严格模式。

9.1.1.5.2 DeleteBinding ( N )

Module Environment Record 的 DeleteBinding 具体方法在本规范中从未使用。

Note

Module Environment Record 仅用于严格代码,并且早期错误规则阻止在严格代码中对解析到模块环境绑定的 Reference Record 使用 delete。见 13.5.1.1

9.1.1.5.3 HasThisBinding ( )

The HasThisBinding concrete method of takes no arguments and returns true. It performs the following steps when called:

  1. 返回 true
Note

Module Environment Record 始终提供 this 绑定。

9.1.1.5.4 GetThisBinding ( )

The GetThisBinding concrete method of takes no arguments and returns 一个包含 undefined正常完成. It performs the following steps when called:

  1. 返回 undefined

9.1.1.5.5 CreateImportBinding ( envRec, N, M, N2 )

The abstract operation CreateImportBinding takes arguments envRec (一个 Module Environment Record), N (一个 String), M (一个 Module Record), and N2 (一个 String) and returns unused. It performs the following steps when called:

  1. 断言:envRec 尚无 N 绑定。
  2. 断言:当 M.[[Environment]] 实例化时会有 N2 的直接绑定。
  3. envRec 中创建引用 MN2 的不可变间接绑定并记录其已初始化。
  4. 返回 unused

9.1.2 环境记录操作 (Environment Record Operations)

下列抽象操作用于在本规范中对 Environment Record 进行操作:

9.1.2.1 GetIdentifierReference ( env, name, strict )

The abstract operation GetIdentifierReference takes arguments env (一个 Environment Recordnull), name (一个 String), and strict (一个 Boolean) and returns 一个包含 Reference Record正常完成或抛出完成. It performs the following steps when called:

  1. envnull,则
    1. 返回 Reference Record { [[Base]]: unresolvable, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty }。
  2. exists 为 ? env.HasBinding(name)。
  3. existstrue,则
    1. 返回 Reference Record { [[Base]]: env, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty }。
  4. 否则,
    1. outerenv.[[OuterEnv]]
    2. 返回 ? GetIdentifierReference(outer, name, strict)。

9.1.2.2 NewDeclarativeEnvironment ( E )

The abstract operation NewDeclarativeEnvironment takes argument E (一个 Environment Recordnull) and returns 一个 Declarative Environment Record. It performs the following steps when called:

  1. env 为一个不含绑定的新 Declarative Environment Record
  2. env.[[OuterEnv]]E
  3. 返回 env

9.1.2.3 NewObjectEnvironment ( O, W, E )

The abstract operation NewObjectEnvironment takes arguments O (一个 Object), W (一个 Boolean), and E (一个 Environment Recordnull) and returns 一个 Object Environment Record. It performs the following steps when called:

  1. env 为一个新 Object Environment Record
  2. env.[[BindingObject]]O
  3. env.[[IsWithEnvironment]]W
  4. env.[[OuterEnv]]E
  5. 返回 env

9.1.2.4 NewFunctionEnvironment ( F, newTarget )

The abstract operation NewFunctionEnvironment takes arguments F (一个 ECMAScript 函数对象) and newTarget (一个 Object 或 undefined) and returns 一个 Function Environment Record. It performs the following steps when called:

  1. env 为一个不含绑定的新 Function Environment Record
  2. env.[[FunctionObject]]F
  3. F.[[ThisMode]]lexical,设 env.[[ThisBindingStatus]]lexical
  4. 否则设 env.[[ThisBindingStatus]]uninitialized
  5. env.[[NewTarget]]newTarget
  6. env.[[OuterEnv]]F.[[Environment]]
  7. 返回 env

9.1.2.5 NewGlobalEnvironment ( G, thisValue )

The abstract operation NewGlobalEnvironment takes arguments G (一个 Object) and thisValue (一个 Object) and returns 一个 Global Environment Record. It performs the following steps when called:

  1. objRecNewObjectEnvironment(G, false, null)。
  2. dclRecNewDeclarativeEnvironment(null)。
  3. env 为一个新 Global Environment Record
  4. env.[[ObjectRecord]]objRec
  5. env.[[GlobalThisValue]]thisValue
  6. env.[[DeclarativeRecord]]dclRec
  7. env.[[OuterEnv]]null
  8. 返回 env

9.1.2.6 NewModuleEnvironment ( E )

The abstract operation NewModuleEnvironment takes argument E (一个 Environment Record) and returns 一个 Module Environment Record. It performs the following steps when called:

  1. env 为一个不含绑定的新 Module Environment Record
  2. env.[[OuterEnv]]E
  3. 返回 env

9.2 PrivateEnvironment 记录 (PrivateEnvironment Records)

PrivateEnvironment Record 是一种规范机制,用于基于 ECMAScript 代码中 ClassDeclarationClassExpression 的词法嵌套结构跟踪 Private Name。它们与 Environment Record 类似但不同。每个 PrivateEnvironment Record 与一个 ClassDeclarationClassExpression 关联。每次此类 class 被求值时,会创建一个新的 PrivateEnvironment Record 来记录该 class 声明的 Private Name

每个 PrivateEnvironment Record 拥有 Table 21 中定义的字段。

Table 21: PrivateEnvironment Record 字段
字段名 值类型 含义
[[OuterPrivateEnvironment]] 一个 PrivateEnvironment Recordnull 最近包围的 class 的 PrivateEnvironment Record。若与此 PrivateEnvironment Record 关联的 class 未被任何其他 class 包含则为 null
[[Names]] 一个 Private Name 列表 该 class 声明的 Private Name

9.2.1 PrivateEnvironment Record 操作 (PrivateEnvironment Record Operations)

以下抽象操作用于在本规范中对 PrivateEnvironment Record 进行操作:

9.2.1.1 NewPrivateEnvironment ( outerPrivateEnv )

The abstract operation NewPrivateEnvironment takes argument outerPrivateEnv (a PrivateEnvironment Record or null) and returns a PrivateEnvironment Record. It performs the following steps when called:

  1. names 为一个新的空 List
  2. 返回 PrivateEnvironment Record { [[OuterPrivateEnvironment]]: outerPrivateEnv, [[Names]]: names }。

9.2.1.2 ResolvePrivateIdentifier ( privateEnv, identifier )

The abstract operation ResolvePrivateIdentifier takes arguments privateEnv (a PrivateEnvironment Record) and identifier (a String) and returns a Private Name. It performs the following steps when called:

  1. namesprivateEnv.[[Names]]
  2. 对于 names 中每个 Private Name pn,执行
    1. pn.[[Description]]identifier,则
      1. 返回 pn
  3. outerPrivateEnvprivateEnv.[[OuterPrivateEnvironment]]
  4. 断言:outerPrivateEnv 不为 null
  5. 返回 ResolvePrivateIdentifier(outerPrivateEnv, identifier)。

9.3 Realm

在被求值之前,所有 ECMAScript 代码都必须与一个 realm 相关联。概念上,realm 由一组内在对象、一个 ECMAScript 全局环境、在该全局环境作用域内加载的所有 ECMAScript 代码,以及其他关联状态与资源组成。

在本规范中,一个 realm 表示为具有 Table 22 中字段的 Realm Record

Table 22: Realm Record 字段
字段名 含义
[[AgentSignifier]] 一个 agent 标识符 拥有该 realm 的 agent
[[Intrinsics]] 一个 Record,其字段名为内在 key,值为对象 与该 realm 关联的代码使用的内在值
[[GlobalObject]] 一个 Object realm 的全局对象
[[GlobalEnv]] 一个 Global Environment Record realm 的全局环境
[[TemplateMap]] 一个 Record 列表,字段 [[Site]] (一个 TemplateLiteral Parse Node) 与 [[Array]] (一个 Array)

模板对象按 realm 独立规范化,使用其 Realm Record[[TemplateMap]]。每个 [[Site]] 值是一个 TemplateLiteral Parse Node。其关联的 [[Array]] 是传递给 tag 函数的对应模板对象。

Note 1
一旦某 Parse Node 变为不可达,对应 [[Array]] 也不可达;实现移除该对条目将不可观察。
[[LoadedModules]] 一个 LoadedModuleRequest Record 列表

从该 realm 导入的 specifier 字符串到解析后 Module Record 的映射。该列表不包含两个不同 Record r1r2 使得 ModuleRequestsEqual(r1, r2) 为 true

Note 2
HostLoadImportedModule 中所述 (16.2.1.10 Note 1),Realm Record 中的 [[LoadedModules]] 仅在在没有活动 script 或 module 的上下文中运行 import() 表达式时使用。
[[HostDefined]] 任意 (默认值为 undefined) 为需要与 Realm Record 关联附加信息的宿主保留的字段。

9.3.1 InitializeHostDefinedRealm ( )

The abstract operation InitializeHostDefinedRealm takes no arguments and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. realm 为一个新的 Realm Record
  2. 执行 CreateIntrinsics(realm)。
  3. realm.[[AgentSignifier]]AgentSignifier()。
  4. realm.[[TemplateMap]] 为一个新的空 List
  5. newContext 为一个新的执行上下文。
  6. newContext 的 Function 设为 null
  7. newContextRealm 设为 realm
  8. newContext 的 ScriptOrModule 设为 null
  9. newContext 压入执行上下文栈;newContext 现在是运行执行上下文。
  10. 宿主要求使用一个特殊对象作为 realm 的全局对象,则
    1. global 为以宿主定义方式创建的此对象。
  11. 否则,
    1. globalOrdinaryObjectCreate(realm.[[Intrinsics]].[[%Object.prototype%]])。
  12. 宿主要求 realm 全局作用域中的 this 绑定返回不同于全局对象的对象,则
    1. thisValue 为以宿主定义方式创建的该对象。
  13. 否则,
    1. thisValueglobal
  14. realm.[[GlobalObject]]global
  15. realm.[[GlobalEnv]]NewGlobalEnvironment(global, thisValue)。
  16. 执行 ? SetDefaultGlobalBindings(realm)。
  17. global 上创建任意宿主定义的全局对象属性。
  18. 返回 unused

9.3.2 CreateIntrinsics ( realmRec )

The abstract operation CreateIntrinsics takes argument realmRec (a Realm Record) and returns unused. It performs the following steps when called:

  1. realmRec.[[Intrinsics]] 设为一个新的 Record
  2. Table 6 中的值设置 realmRec.[[Intrinsics]] 的字段。字段名为该表第一列列出的名称。每个字段的值为一个根据 1928 中各对象规范完全递归填充属性值的新对象。所有对象属性值均为新创建对象。所有内置函数对象通过执行 CreateBuiltinFunction(steps, length, name, slots, realmRec, prototype) 创建,其中 steps 是本规范给出的该函数定义,name 是函数 "name" 属性初始值,length 是函数 "length" 属性初始值,slots 是函数指定内部槽名称列表(若有),prototype 是指定的 [[Prototype]] 内部槽值。内在对象及其属性的创建顺序必须避免依赖尚未创建的对象。
  3. 执行 AddRestrictedFunctionProperties(realmRec.[[Intrinsics]].[[%Function.prototype%]], realmRec)。
  4. 返回 unused

9.3.3 SetDefaultGlobalBindings ( realmRec )

The abstract operation SetDefaultGlobalBindings takes argument realmRec (a Realm Record) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. globalrealmRec.[[GlobalObject]]
  2. 19 条款中指定的全局对象的每个属性,执行
    1. name 为该属性名的 String 值。
    2. desc 为该属性的完全填充数据属性描述符,包含该属性指定的特性。对于 19.219.319.4 中列出的属性,其 [[Value]] 为来自 realmRec 的对应内在对象。
    3. 执行 ? DefinePropertyOrThrow(global, name, desc)。
  3. 返回 unused

9.4 执行上下文 (Execution Contexts)

execution context 是规范装置,用于跟踪 ECMAScript 实现对代码的运行时求值。在任意时刻,每个 agent 最多只有一个实际执行代码的执行上下文,称为该 agent 的 运行执行上下文 (running execution context)。本规范中所有对运行执行上下文的引用均指当前 agent 的运行执行上下文。

执行上下文栈 (execution context stack) 用于跟踪执行上下文。运行执行上下文始终是该栈的顶部元素。当控制从当前运行执行上下文关联的可执行代码转移到不与其关联的可执行代码时,会创建一个新的执行上下文。新执行上下文被压入栈顶并成为运行执行上下文。

执行上下文包含跟踪其关联代码执行进度所需的实现特定状态。每个执行上下文至少具有 Table 23 中列出的状态组成部分。

Table 23: 所有执行上下文的状态组成部分
组成部分 目的
code evaluation state 执行、暂停与恢复该上下文关联代码求值所需的任意状态。
Function 若该上下文正在求值某函数对象的代码,则为该函数对象;若求值 ScriptModule,该值为 null
Realm 关联代码访问 ECMAScript 资源所用的 Realm Record
ScriptOrModule 关联代码来源的 Module Record 或 Script Record。若不存在来源脚本或模块(如 InitializeHostDefinedRealm 创建的初始执行上下文),该值为 null

运行执行上下文对代码的求值可在本规范定义的各种点被挂起。一旦挂起,另一个执行上下文可成为运行执行上下文并开始求值其代码。之后某个时间,被挂起的执行上下文可再次成为运行执行上下文并从之前挂起的位置继续。运行执行上下文在不同上下文间的转换通常按堆栈后进先出方式,但某些 ECMAScript 特性需要非 LIFO 的转换。

运行执行上下文 Realm 组成部分的值也称为 当前 Realm Record。运行执行上下文 Function 组成部分的值也称为 活动函数对象 (active function object)

ECMAScript 代码执行上下文 具有 Table 24 中列出的附加状态组成部分。

Table 24: ECMAScript 代码执行上下文的附加状态组成部分
组成部分 目的
LexicalEnvironment 标识用于解析该上下文中代码标识符引用的 Environment Record
VariableEnvironment 标识在该上下文中由 VariableStatement 创建绑定的 Environment Record
PrivateEnvironment 标识持有最近包围 class 中 ClassElement 创建的 Private NamePrivateEnvironment Record。若无包围 class 则为 null

执行上下文的 LexicalEnvironment 与 VariableEnvironment 组成部分始终是 Environment Record

表示 Generator 求值的执行上下文具有 Table 25 中列出的附加状态组成部分。

Table 25: Generator 执行上下文的附加状态组成部分
组成部分 目的
Generator 该执行上下文正在求值的 Generator。

大多数情况下,只有运行执行上下文(执行上下文栈顶)被本规范内算法直接操作。因此当未限定使用 “LexicalEnvironment” 与 “VariableEnvironment” 时,指的是运行执行上下文的那些组成部分。

执行上下文纯属规范机制,不必对应 ECMAScript 实现中的具体实体。ECMAScript 代码无法直接访问或观察执行上下文。

9.4.1 GetActiveScriptOrModule ( )

The abstract operation GetActiveScriptOrModule takes no arguments and returns a Script Record, a Module Record, or null. 基于运行执行上下文确定运行脚本或模块。 It performs the following steps when called:

  1. 若执行上下文栈为空,返回 null
  2. ec 为执行上下文栈顶端第一个其 ScriptOrModule 组成部分不为 null 的执行上下文。
  3. 若不存在此执行上下文,返回 null;否则返回 ec 的 ScriptOrModule。

9.4.2 ResolveBinding ( name [ , env ] )

The abstract operation ResolveBinding takes argument name (a String) and optional argument env (an Environment Record or undefined) and returns either a normal completion containing a Reference Record or a throw completion. 用于确定 name 的绑定。env 可显式提供要搜索绑定的 Environment Record。 It performs the following steps when called:

  1. env 未提供或 envundefined,则
    1. env 为运行执行上下文的 LexicalEnvironment。
  2. 断言:env 是一个 Environment Record
  3. strict 为正被求值的语法产生式的 IsStrict 结果。
  4. 返回 ? GetIdentifierReference(env, name, strict)。
Note

ResolveBinding 的结果始终是一个 [[ReferencedName]] 字段为 nameReference Record

9.4.3 GetThisEnvironment ( )

The abstract operation GetThisEnvironment takes no arguments and returns an Environment Record. 查找当前提供关键字 this 绑定的 Environment Record。 It performs the following steps when called:

  1. env 为运行执行上下文的 LexicalEnvironment。
  2. 重复,
    1. existsenv.HasThisBinding()。
    2. existstrue,返回 env
    3. outerenv.[[OuterEnv]]
    4. 断言:outer 不为 null
    5. envouter
Note

步骤 2 中的循环总会终止,因为环境链最后以具有 this 绑定的全局环境结束。

9.4.4 ResolveThisBinding ( )

The abstract operation ResolveThisBinding takes no arguments and returns either a normal completion containing an ECMAScript language value or a throw completion. 使用运行执行上下文的 LexicalEnvironment 确定关键字 this 的绑定。 It performs the following steps when called:

  1. envRecGetThisEnvironment()。
  2. 返回 ? envRec.GetThisBinding()。

9.4.5 GetNewTarget ( )

The abstract operation GetNewTarget takes no arguments and returns an Object or undefined. 使用运行执行上下文的 LexicalEnvironment 确定 NewTarget 值。 It performs the following steps when called:

  1. envRecGetThisEnvironment()。
  2. 断言:envRec[[NewTarget]] 字段。
  3. 返回 envRec.[[NewTarget]]

9.4.6 GetGlobalObject ( )

The abstract operation GetGlobalObject takes no arguments and returns an Object. 返回当前运行执行上下文使用的全局对象。 It performs the following steps when called:

  1. currentRealm当前 Realm Record
  2. 返回 currentRealm.[[GlobalObject]]

9.5 作业 (Jobs) 以及用于入队作业的宿主操作

Job(作业) 是一个无参数的抽象闭包(Abstract Closure),当当前没有其它 ECMAScript 计算正在进行时,它会启动一次 ECMAScript 计算。

作业由 ECMAScript 宿主环境在特定 agent 中调度执行。本规范描述宿主挂钩 HostEnqueueGenericJobHostEnqueueFinalizationRegistryCleanupJobHostEnqueuePromiseJobHostEnqueueTimeoutJob 来调度作业。本规范中的宿主挂钩按对作业调度施加的附加约束进行组织。宿主可定义额外的抽象操作来调度作业。此类操作接受一个 Job 抽象闭包和一个 realm(一个 Realm Recordnull)作为参数。若提供了 Realm Record,则这些操作会在拥有该 realm 的 agent 中,于未来某个时间安排执行该作业。若改为为 realm 提供 null,则该作业不求值 ECMAScript 代码。它们的实现必须符合以下要求:

  • 在未来某个时间点,当相应 agent 中没有正在运行的上下文且该 agent 的执行上下文栈为空时,实现必须:
    1. 执行任何宿主定义的准备步骤。
    2. 调用该 Job 抽象闭包。
    3. 执行任何宿主定义的清理步骤,之后执行上下文栈必须再次为空。
  • 在一个 agent 中任意时间只能有一个 Job 正在被求值。
  • 一旦开始求值某个 Job,在该 agent 中必须先运行至完成,之后才可开始另一个 Job 的求值。
  • 该抽象闭包必须返回一个正常完成(normal completion),并自行处理错误。
Note 1
宿主环境在调度方面不需要对所有 Job 一视同仁。例如,Web 浏览器与 Node.js 将处理 Promise 的 Job 视为比其它工作更高的优先级;未来特性可能添加不会设为如此高优先级的 Job。

在任意时间,若下列条件全部成立,则 scriptOrModule(一个 Script RecordModule Recordnull)是活动脚本或模块 (active script or module)

  • GetActiveScriptOrModule() 的结果为 scriptOrModule
  • scriptOrModule 是 Script RecordModule Record,令 ec 为执行上下文栈顶端第一个其 ScriptOrModule 组成部分为 scriptOrModule 的执行上下文。ecRealm 组成部分为 scriptOrModule.[[Realm]]

在任意时间,若以下条件全部成立,则某次执行已准备好求值 ECMAScript 代码 (prepared to evaluate ECMAScript code)

  • 执行上下文栈不为空。
  • 执行上下文栈顶端执行上下文的 Realm 组成部分是一个 Realm Record
Note 2

宿主环境可以通过向执行上下文栈压入执行上下文来准备执行求值代码。具体步骤由实现定义。

Realm 的具体选择由宿主环境决定。这个初始执行上下文与 Realm 仅在任何回调函数被调用之前使用。当与某个 Job 相关的回调(如 Promise 处理器)被调用时,该调用会压入其自身的执行上下文与 Realm

特定种类的 Job 还有额外的一致性要求。

9.5.1 JobCallback 记录 (JobCallback Records)

JobCallback Record 是用于存储一个函数对象与一个宿主定义值的 Record。通过宿主入队的 Job 调用的函数对象可能具备额外的宿主定义上下文。为传播该状态,Job 抽象闭包不应直接捕获并调用函数对象;应改用 HostMakeJobCallbackHostCallJobCallback

Note

例如,WHATWG HTML 规范(https://html.spec.whatwg.org/)使用该宿主定义值来传播 Promise 回调的 incumbent settings object。

JobCallback Record 具有 Table 26 中列出的字段。

Table 26: JobCallback Record 字段
字段名 含义
[[Callback]] 一个函数对象 当该 Job 被调用时要调用的函数。
[[HostDefined]] 任意(默认值 empty 保留给宿主使用的字段。

9.5.2 HostMakeJobCallback ( callback )

The host-defined abstract operation HostMakeJobCallback takes argument callback (a function object) and returns a JobCallback Record.

HostMakeJobCallback 的实现必须符合以下要求:

HostMakeJobCallback 的默认实现被调用时执行下列步骤:

  1. 返回 JobCallback Record { [[Callback]]: callback, [[HostDefined]]: empty }。

不是 Web 浏览器的 ECMAScript 宿主必须使用 HostMakeJobCallback 的默认实现。

Note

调用发生在回调被传入负责最终调度并运行它的函数之时。例如,promise.then(thenAction) 在调用 Promise.prototype.then 时对 thenAction 调用 MakeJobCallback,而不是在调度 reaction Job 时。

9.5.3 HostCallJobCallback ( jobCallback, V, argumentsList )

The host-defined abstract operation HostCallJobCallback takes arguments jobCallback (a JobCallback Record), V (an ECMAScript language value), and argumentsList (a List of ECMAScript language values) and returns either a normal completion containing an ECMAScript language value or a throw completion.

HostCallJobCallback 的实现必须符合以下要求:

  • 它必须执行并返回 Call(jobCallback.[[Callback]], V, argumentsList) 的结果。
Note

该要求意味着宿主不能改变本规范定义的函数对象[[Call]] 行为。

HostCallJobCallback 的默认实现被调用时执行下列步骤:

  1. 断言:IsCallable(jobCallback.[[Callback]]) 为 true
  2. 返回 ? Call(jobCallback.[[Callback]], V, argumentsList)。

不是 Web 浏览器的 ECMAScript 宿主必须使用 HostCallJobCallback 的默认实现。

9.5.4 HostEnqueueGenericJob ( job, realm )

The host-defined abstract operation HostEnqueueGenericJob takes arguments job (a Job Abstract Closure) and realm (a Realm Record) and returns unused. 在 realm.[[AgentSignifier]] 所指示的 agent 中,将 job 安排于未来某个时间在 realm realm 中执行。与该算法一起使用的抽象闭包意在不带额外约束(如优先级与排序)地调度。

HostEnqueueGenericJob 的实现必须符合 9.5 中的要求。

9.5.5 HostEnqueuePromiseJob ( job, realm )

The host-defined abstract operation HostEnqueuePromiseJob takes arguments job (a Job Abstract Closure) and realm (a Realm Record or null) and returns unused. 安排 job 于未来某个时间执行。与该算法一起使用的抽象闭包意在与 Promise 处理相关,或以与 Promise 处理操作同等优先级被调度。

HostEnqueuePromiseJob 的实现必须符合 9.5 中的要求并且满足以下附加要求:

  • realm 不为 null,则每次 job 被调用时,实现必须执行实现定义步骤,使得在 job 调用时执行已准备好求值 ECMAScript 代码。
  • scriptOrModule 为调用 HostEnqueuePromiseJob 时的 GetActiveScriptOrModule()。若 realm 不为 null,则每次 job 被调用时,实现必须执行实现定义步骤,使得在 job 调用时 scriptOrModule 为活动脚本或模块。
  • 作业必须按调度它们的各次 HostEnqueuePromiseJob 调用的顺序运行。
Note

NewPromiseResolveThenableJob 返回的 Job 的 realm 通常是对 then 函数对象调用 GetFunctionRealm 的结果。由 NewPromiseReactionJob 返回的 Job 的 realm 通常是对处理器(若该处理器不为 undefined)调用 GetFunctionRealm 的结果。若处理器为 undefinedrealmnull。对于这两类 Job,当 GetFunctionRealm 异常完成(例如在被撤销的 Proxy 上调用)时,realm 为调用 GetFunctionRealm 时的当前 Realm Record。当 realmnull 时,不会执行用户 ECMAScript 代码,也不会创建新的 ECMAScript 对象(例如 Error 对象)。例如,WHATWG HTML 规范(https://html.spec.whatwg.org/)使用 realm 来检查脚本是否可运行,以及与 entry 概念相关。

9.5.6 HostEnqueueTimeoutJob ( timeoutJob, realm, milliseconds )

The host-defined abstract operation HostEnqueueTimeoutJob takes arguments timeoutJob (a Job Abstract Closure), realm (a Realm Record), and milliseconds (a non-negative finite Number) and returns unused. 在 realm.[[AgentSignifier]] 所指示的 agent 中,将 timeoutJob 安排于至少 milliseconds 毫秒之后在 realm realm 中执行。

HostEnqueueTimeoutJob 的实现必须符合 9.5 中的要求。

9.6 Agents(代理)

agent(代理) 由一组 ECMAScript 执行上下文、一个执行上下文栈、一个运行执行上下文、一个 Agent Record 以及一个 执行线程 (executing thread) 组成。除执行线程外,agent 的各组成部分只属于该 agent 本身。

agent 的执行线程独立于其它 agent 在其执行上下文上执行算法步骤;但是一个执行线程可被多个 agent 共享,前提是共享该线程的 agent 中没有其 Agent Record[[CanBlock]] 字段为 true 的。

Note 1

例如,一些 Web 浏览器会在多个互不相关的标签页间共享单一执行线程。

当一个 agent 的执行线程在执行算法步骤时,该 agent 就是这些步骤的 包围 agent (surrounding agent)。这些步骤通过该包围 agent 访问其持有的规范级执行对象:运行执行上下文、执行上下文栈以及 Agent Record 的字段。

agent signifier(代理标识符) 是用于标识一个 Agent 的全局唯一不透明值。

Table 27: Agent Record 字段
字段名 含义
[[LittleEndian]] a Boolean 用于算法 GetValueFromBufferSetValueInBuffer 所需参数 isLittleEndian 的默认值。选择由实现定义,应为实现效率最高的选项。一旦被观察到便不可改变。
[[CanBlock]] a Boolean 决定该 agent 是否可以阻塞。
[[Signifier]] an agent signifier 在其 agent 集群内唯一标识该 agent。
[[IsLockFree1]] a Boolean 若对单字节值的原子操作无锁则为 true,否则 false
[[IsLockFree2]] a Boolean 若对双字节值的原子操作无锁则为 true,否则 false
[[IsLockFree8]] a Boolean 若对八字节值的原子操作无锁则为 true,否则 false
[[CandidateExecution]] a candidate execution Record 参见内存模型
[[KeptAlive]] a List of either Objects or Symbols 初始为空 List,表示在当前 Job 结束前需保持存活的对象和/或 symbol 列表。
[[ModuleAsyncEvaluationCount]] an integer 初始为 0,用于为异步或具有异步依赖的模块的 [[AsyncEvaluationOrder]] 字段分配递增唯一值。

一旦 [[Signifier]][[IsLockFree1]][[IsLockFree2]] 的值被 agent 集群中的任一 agent 观察到,它们就不可更改。

Note 2

[[IsLockFree1]][[IsLockFree2]] 的值不一定由硬件决定,也可反映可能随时间与实现而变的实现选择。

没有 [[IsLockFree4]] 字段:4 字节原子操作总是无锁。

实际上,如果某原子操作用任何形式的锁实现,该操作就不是无锁的。无锁不意味着无等待(wait-free):完成一个无锁原子操作需要的机器步骤数没有上界。

某大小 n 的原子访问无锁并不意味着对同大小 n 的非原子访问具备(感知的)原子性;具体来说,非原子访问仍可能分解为多个独立的内存访问。详见 ReadSharedMemoryWriteSharedMemory

Note 3

agent 是规范机制,不需对应 ECMAScript 实现中的实际产物。

9.6.1 AgentSignifier ( )

The abstract operation AgentSignifier takes no arguments and returns an agent signifier. It performs the following steps when called:

  1. AR 为包围 agent 的 Agent Record
  2. 返回 AR.[[Signifier]]

9.6.2 AgentCanSuspend ( )

The abstract operation AgentCanSuspend takes no arguments and returns a Boolean. It performs the following steps when called:

  1. AR 为包围 agent 的 Agent Record
  2. 返回 AR.[[CanBlock]]
Note

在某些环境中,对某个 agent 来说暂停可能并不合适。例如,在 Web 浏览器环境中,可能不允许暂停文档的主事件处理线程,但允许 worker 的事件处理线程暂停。

9.6.3 IncrementModuleAsyncEvaluationCount ( )

The abstract operation IncrementModuleAsyncEvaluationCount takes no arguments and returns an integer. It performs the following steps when called:

  1. AR 为包围 agent 的 Agent Record
  2. countAR.[[ModuleAsyncEvaluationCount]]
  3. AR.[[ModuleAsyncEvaluationCount]]count + 1。
  4. 返回 count
Note

该值仅用于追踪待定模块之间的相对求值顺序。实现可在没有待定模块时不可观察地将 [[ModuleAsyncEvaluationCount]] 重置为 0。

9.7 Agent Clusters(代理集群)

agent cluster(代理集群) 是能够通过操作共享内存进行通信的最大化的一组 agent。

Note 1

不同 agent 内的程序可能通过未指明的方式共享内存。至少,共享内存可包含 SharedArrayBuffer 的底层存储。

可能存在只能通过消息传递通信而不能共享内存的 agent;它们永远不在同一个 agent cluster 中。

每个 agent 恰好属于一个 agent cluster。

Note 2

集群中的 agent 不必在某个时间点全部“活着”。如果 agent A 创建了 agent B,随后 A 终止,而 B 又创建 agent C,如果 A 可以与 B 共享某些内存且 B 可以与 C 共享某些内存,则三个 agent 仍在同一集群。

同一集群内所有 agent 在其各自 Agent Record[[LittleEndian]] 字段上必须具有相同的值。

Note 3

若集群中不同 agent 的 [[LittleEndian]] 值不同,就难以在多字节数据上使用共享内存。

同一集群内所有 agent 在其 [[IsLockFree1]] 字段上必须具有相同值;[[IsLockFree2]] 字段同理。

同一集群内所有 agent 在其 [[Signifier]] 字段上必须具有不同值。

嵌入环境可在 agent 不知情或不配合的情况下停用(停止前向进展)或激活(恢复前向进展)一个 agent。若这样做,不得使集群中某些 agent 长期保持激活而另一些被无限期停用。

Note 4

上述限制的目的是避免某个 agent 因另一个被停用的 agent 而死锁或饥饿。例如,若一个生命周期独立于任何窗口文档的 HTML shared worker 被允许与这样一个独立文档的 dedicated worker 共享内存,而该文档及其 dedicated worker 被停用时 dedicated worker 持有某个锁(如文档被推入窗口历史),随后 shared worker 尝试获取该锁,那么 shared worker 会被阻塞直到 dedicated worker 被重新激活(如果会的话)。同时其它试图从其它窗口访问该 shared worker 的 worker 会饥饿。

该限制意味着无法在不属于同一“暂停/唤醒”集体的 agent 之间共享内存。

嵌入环境可以在未提前通知或未获得集群内其它 agent 协作的情况下终止某个 agent。若某 agent 的终止不是其自身或集群内其它 agent 的程序化行为,而是由集群外部因素导致,则嵌入环境必须在两个策略中择一:要么终止该集群所有 agent,要么提供可靠的 API 让集群内 agent 协调,以便至少一个仍存活的成员能够检测到该终止,并且终止数据中包含足以标识被终止 agent 的信息。

Note 5

此类终止的例子包括:操作系统或用户终止在独立进程中运行的 agent;当按 agent 资源统计显示某 agent 失控时,嵌入环境终止与其它 agent 在同一进程内运行的该 agent。

下列每个规范值以及从它们可传递抵达的值,恰好属于一个 agent cluster:

在集群中任何 agent 求值任意 ECMAScript 代码之前,集群中所有 agent 的 Agent Record[[CandidateExecution]] 字段被设为初始 candidate execution。初始 candidate execution 是一个空的 candidate execution,其 [[EventsRecords]] 字段是一个 List,其中为每个 agent 含有一个 Agent Events Record,其 [[AgentSignifier]] 字段为该 agent 的 agent signifier,而 [[EventList]][[AgentSynchronizesWith]] 字段是空 List

Note 6

同一 agent cluster 中所有 agent 在其 Agent Record[[CandidateExecution]] 字段共享同一个 candidate executioncandidate execution内存模型使用的规范机制。

Note 7

agent cluster 是规范机制,不需对应 ECMAScript 实现中的实际产物。

9.8 Forward Progress(前向进展)

某 agent 取得前向进展 (make forward progress) 指其执行根据本规范的一次求值步骤。

当一个 agent 的运行执行上下文同步且无限期地等待外部事件时,该 agent 变为 阻塞 (blocked)。只有 Agent Record[[CanBlock]] 字段为 true 的 agent 才能以此方式阻塞。未阻塞 (unblocked) 的 agent 指未阻塞的。

实现必须确保:

  • 每个拥有专用执行线程且未阻塞的 agent 最终取得前向进展
  • 共享一个执行线程的一组 agent 中,总有一个 agent 最终取得前向进展
  • 一个 agent 不得导致另一个 agent 阻塞,除非通过提供阻塞的显式 API
Note

这一点与内存模型中的活性保证一起,确保所有 seq-cst 写入最终对所有 agent 可观察。

9.9 WeakRef 与 FinalizationRegistry 目标的处理模型

9.9.1 目标 (Objectives)

本规范不保证任何对象或 symbol 会被垃圾回收。非存活的对象或 symbol 可能在很长时间后才被释放,甚至永不释放。基于此,本规范在描述被垃圾回收触发的行为时使用 “may”。

WeakRefFinalizationRegistry 的语义基于在特定时间点发生的两个操作:

上述两个动作(ClearKeptObjectsCleanupFinalizationRegistry)都不得打断同步 ECMAScript 执行。由于宿主可以组合更长的同步 ECMAScript 执行段,本规范将 ClearKeptObjectsCleanupFinalizationRegistry 的调度推迟到宿主环境

一些 ECMAScript 实现包含在后台(包括 ECMAScript 空闲时)运行的垃圾回收器。让宿主环境调度 CleanupFinalizationRegistry 允许其恢复 ECMAScript 执行以运行 finalizer 工作,可能释放被持有的值,降低整体内存占用。

9.9.2 存活性 (Liveness)

对于一组对象和/或 symbol S,相对于 S 的一次 假设的 WeakRef-oblivious(弱引用无感) 执行是指:任何将其 referent 属于 SWeakRef抽象操作 WeakRefDeref 总是返回 undefined 的执行。

Note 1
WeakRef-obliviousness 与 liveness 一起捕获两个概念:其一,WeakRef 本身不会保持其 referent 存活;其二,存活性中的循环不意味着某值存活。具体地,若判定 v 的存活性依赖判定某 WeakRef referent r 的存活性,则 r 的存活性不能假定 v 的存活性,否则是循环论证。
Note 2
WeakRef-obliviousness 针对对象或 symbol 的集合而不是单个值定义,以处理循环。若对单个值定义,则一个循环中的 WeakRef referent 会被视为存活,即便其身份仅通过循环中其它 WeakRef referent 被观察。
Note 3
口语化地,若包含某个对象或 symbol 的每个集合都是存活的,则我们说该对象或 symbol 存活。

在求值任意时刻,若下列任一条件成立,则对象和/或 symbol 集合 S 被视为 live(存活)

  • S 中任一元素包含于任一 agent 的 [[KeptAlive]] List 中。
  • 存在相对于 S 的某个未来合法的假设 WeakRef-oblivious 执行,在其中观察到 S 中任一值的身份。
Note 4
第二个条件旨在捕获这样的直觉:若一个值的身份可通过非 WeakRef 手段观察到,则该值是存活的。值的身份可通过严格相等比较或作为 Map 的键被观察到。
Note 5

对象或 symbol 出现在某字段、内部槽或属性中并不意味着该值存活。例如若该值从未被返回给程序,则不可被观察。

这适用于 WeakMap 的键、WeakSet 的成员,以及 FinalizationRegistry Cell 记录的 [[WeakRefTarget]][[UnregisterToken]] 字段。

上述定义意味着:若 WeakMap 中的某键不存活,则其对应的值也不必定存活。

Note 6
Liveness 是保证引擎不得清空哪些 WeakRef 的下界。此处定义的 liveness 是不可判定的。实际中,引擎使用 reachability 等保守近似,存在较大实现自由度。

9.9.3 执行 (Execution)

在任意时刻,若一组对象和/或 symbol S 不存活,ECMAScript 实现可原子地执行以下步骤:

  1. 对于 S 的每个元素 value,执行
    1. 对每个 WeakRef refref.[[WeakRefTarget]]value),执行
      1. ref.[[WeakRefTarget]]empty
    2. 对每个 FinalizationRegistry fgfg.[[Cells]] 含有记录 cellcell.[[WeakRefTarget]]value),执行
      1. cell.[[WeakRefTarget]]empty
      2. 可选:执行 HostEnqueueFinalizationRegistryCleanupJob(fg)。
    3. 对每个 WeakMap mapmap.[[WeakMapData]] 含有记录 rr.[[Key]]value),执行
      1. r.[[Key]]empty
      2. r.[[Value]]empty
    4. 对每个 WeakSet setset.[[WeakSetData]] 含有 value),执行
      1. set.[[WeakSetData]] 中值为 value 的元素替换为值为 empty 的元素。
Note 1

结合存活性的定义,本条款规定了实现可针对 WeakRef 应用的优化。

可能存在在不观察对象身份的情况下访问对象的情形。诸如死变量消除、对非逃逸对象属性的标量替换等优化在对象身份未被观察时允许进行。因此,这些优化可在可观察范围内清空指向此类对象的 WeakRef

另一方面,若对象身份可被观察且该对象位于某 WeakRef[[WeakRefTarget]] 内部槽中,则诸如重新物化(rematerialization)等会在可观察层面清空该 WeakRef 的优化被禁止。

由于调用 HostEnqueueFinalizationRegistryCleanupJob 是可选的,注册在 FinalizationRegistry 中的对象不必定保持该 FinalizationRegistry 存活。实现可基于任何理由省略 FinalizationRegistry 回调,例如 FinalizationRegistry 自身变为“死”,或应用正在关闭。

Note 2

实现不要求针对最大的不存活对象或 symbol 集合清空 WeakRef

若实现选择一个不存活集合 S 来清空 WeakRef,此定义要求它同时清空 S 中所有值的 WeakRef。换言之,实现不能只清空指向值 vWeakRef 而保留其它可能在执行中观察到 vWeakRef 未清空。

9.9.4 宿主挂钩 (Host Hooks)

9.9.4.1 HostEnqueueFinalizationRegistryCleanupJob ( finalizationRegistry )

The host-defined abstract operation HostEnqueueFinalizationRegistryCleanupJob takes argument finalizationRegistry (a FinalizationRegistry) and returns unused.

cleanupJob 为一个无参数的新 Job 抽象闭包,它捕获 finalizationRegistry 并在被调用时执行以下步骤:

  1. cleanupResultCompletion(CleanupFinalizationRegistry(finalizationRegistry))。
  2. cleanupResult异常完成,执行任意宿主定义步骤以报告错误。
  3. 返回 unused

HostEnqueueFinalizationRegistryCleanupJob 的实现将 cleanupJob 安排于未来某个时间(若可能)执行,并且还必须符合 9.5 中的要求。

9.10 ClearKeptObjects ( )

The abstract operation ClearKeptObjects takes no arguments and returns unused. 期望 ECMAScript 实现在一次同步的 ECMAScript 执行序列完成后调用 ClearKeptObjects。 It performs the following steps when called:

  1. agentRecord 为包围 agent 的 Agent Record
  2. agentRecord.[[KeptAlive]] 为一个新的空 List
  3. 返回 unused

9.11 AddToKeptObjects ( value )

The abstract operation AddToKeptObjects takes argument value (an Object or a Symbol) and returns unused. It performs the following steps when called:

  1. agentRecord 为包围 agent 的 Agent Record
  2. value 追加到 agentRecord.[[KeptAlive]]
  3. 返回 unused
Note
抽象操作 AddToKeptObjects 以某目标对象或 symbol 被调用时,它把该目标加入一个列表;在调用 ClearKeptObjects 之前,该列表会对目标保持强引用。

9.12 CleanupFinalizationRegistry ( finalizationRegistry )

The abstract operation CleanupFinalizationRegistry takes argument finalizationRegistry (a FinalizationRegistry) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. 断言:finalizationRegistry 具有 [[Cells]][[CleanupCallback]] 内部槽。
  2. callbackfinalizationRegistry.[[CleanupCallback]]
  3. finalizationRegistry.[[Cells]] 含有某记录 cellcell.[[WeakRefTarget]]empty 时,实现可以执行以下步骤:
    1. 任选一个这样的 cell
    2. finalizationRegistry.[[Cells]] 中移除 cell
    3. 执行 ? HostCallJobCallback(callback, undefined, « cell.[[HeldValue]] »)。
  4. 返回 unused

9.13 CanBeHeldWeakly ( v )

The abstract operation CanBeHeldWeakly takes argument v (an ECMAScript language value) and returns a Boolean. 当且仅当 v 适合作为弱引用使用时返回 true。只有适合作为弱引用使用的值才能成为 WeakMap 的键、WeakSet 的元素、WeakRef 的 target,或 FinalizationRegistry 的某个 target。 It performs the following steps when called:

  1. v 是一个 Object,返回 true
  2. v 是一个 Symbol 且 KeyForSymbol(v) 为 undefined,返回 true
  3. 返回 false
Note

没有 语言身份 (language identity) 的语言值可以在没有先前引用的情况下被重新生成,不适合作为弱引用。由 Symbol.for 产生的 Symbol 值与其他 Symbol 不同,它不具有语言身份,因此也不适合作为弱引用。Well-known symbols 很可能永远不会被回收,但由于其数量有限,仍被视为适合用作弱引用,可通过多种实现手段管理。然而,在一个存活的 WeakMap 中与某个 well-known symbol 关联的任何值都不太可能被回收,可能在实现中“泄漏”内存资源。

10 普通与特异(Exotic)对象的行为 (Ordinary and Exotic Objects Behaviours)

10.1 普通对象的内部方法与内部槽 (Ordinary Object Internal Methods and Internal Slots)

所有普通对象都有名为 [[Prototype]] 的内部槽。该内部槽的值要么是 null 要么是一个对象,用于实现继承。假设一个名为 P 的属性在普通对象 O 上缺失,但存在于其 [[Prototype]] 对象上。如果 P 指向 [[Prototype]] 对象上的数据属性,则 O 在“取值”访问(get access)时继承它,使其表现得仿佛 PO 的一个属性。如果 P 指向 [[Prototype]] 对象上的可写数据属性,在 O 上对 P 进行“设值”访问(set access)会在 O 上创建一个名为 P 的新数据属性。如果 P 指向 [[Prototype]] 对象上的不可写数据属性,在 O 上对 P 的设值访问会失败。如果 P 指向 [[Prototype]] 对象上的访问器属性(accessor property),则该访问器在 O 上同时被继承用于 get 与 set 访问。

每个普通对象都有一个布尔值内部槽 [[Extensible]],用于满足 6.1.7.3 中规定的与可扩展性相关的内部方法不变式。也就是说,一旦对象的 [[Extensible]] 内部槽被设为 false,就不再可能向该对象添加属性、修改该对象 [[Prototype]] 内部槽的值,或随后将 [[Extensible]] 的值重新改为 true

在下面的算法描述中,假设 O 是一个普通对象P 是一个属性键值,V 是任意 ECMAScript 语言值Desc 是一个 Property Descriptor 记录。

每个普通对象内部方法委派给一个同名的抽象操作。如果该抽象操作依赖另一个内部方法,那么会在 O 上调用该内部方法,而不是直接调用同名的抽象操作。这些语义确保当普通对象的内部方法应用到特异(exotic)对象时,被重写的内部方法能够被调用。

10.1.1 [[GetPrototypeOf]] ( )

The [[GetPrototypeOf]] internal method of 一个普通对象 O takes no arguments and returns 一个正常完成,包含一个 Object 或 null. It performs the following steps when called:

  1. 返回 OrdinaryGetPrototypeOf(O)。

10.1.1.1 OrdinaryGetPrototypeOf ( O )

The abstract operation OrdinaryGetPrototypeOf takes argument O (an Object) and returns an Object or null. It performs the following steps when called:

  1. 返回 O.[[Prototype]]

10.1.2 [[SetPrototypeOf]] ( V )

The [[SetPrototypeOf]] internal method of 一个普通对象 O takes argument V (an Object or null) and returns 一个正常完成,包含一个 Boolean. It performs the following steps when called:

  1. 返回 OrdinarySetPrototypeOf(O, V)。

10.1.2.1 OrdinarySetPrototypeOf ( O, V )

The abstract operation OrdinarySetPrototypeOf takes arguments O (an Object) and V (an Object or null) and returns a Boolean. It performs the following steps when called:

  1. currentO.[[Prototype]]
  2. SameValue(V, current) 为 true,返回 true
  3. extensibleO.[[Extensible]]
  4. extensiblefalse,返回 false
  5. pV
  6. donefalse
  7. donefalse 重复,
    1. pnull,则
      1. donetrue
    2. 否则若 SameValue(p, O) 为 true,则
      1. 返回 false
    3. 否则,
      1. p.[[GetPrototypeOf]] 不是 10.1.1 中定义的普通对象内部方法,设 donetrue
      2. 否则,将 p 设为 p.[[Prototype]]
  8. O.[[Prototype]]V
  9. 返回 true
Note

步骤 7 中的循环保证:任何仅包含使用普通对象定义之 [[GetPrototypeOf]][[SetPrototypeOf]] 的对象的原型链中不会出现循环。

10.1.3 [[IsExtensible]] ( )

The [[IsExtensible]] internal method of 一个普通对象 O takes no arguments and returns 一个正常完成,包含一个 Boolean. It performs the following steps when called:

  1. 返回 OrdinaryIsExtensible(O)。

10.1.3.1 OrdinaryIsExtensible ( O )

The abstract operation OrdinaryIsExtensible takes argument O (an Object) and returns a Boolean. It performs the following steps when called:

  1. 返回 O.[[Extensible]]

10.1.4 [[PreventExtensions]] ( )

The [[PreventExtensions]] internal method of 一个普通对象 O takes no arguments and returns 一个正常完成,包含 true. It performs the following steps when called:

  1. 返回 OrdinaryPreventExtensions(O)。

10.1.4.1 OrdinaryPreventExtensions ( O )

The abstract operation OrdinaryPreventExtensions takes argument O (an Object) and returns true. It performs the following steps when called:

  1. O.[[Extensible]] 设为 false
  2. 返回 true

10.1.5 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of 一个普通对象 O takes argument P (a property key) and returns 一个正常完成,包含一个 Property Descriptorundefined. It performs the following steps when called:

  1. 返回 OrdinaryGetOwnProperty(O, P)。

10.1.5.1 OrdinaryGetOwnProperty ( O, P )

The abstract operation OrdinaryGetOwnProperty takes arguments O (an Object) and P (a property key) and returns a Property Descriptor or undefined. It performs the following steps when called:

  1. O 不存在键为 P 的自身属性,返回 undefined
  2. D 为一个新建的无字段 Property Descriptor
  3. XO 的键为 P 的自身属性。
  4. X数据属性,则
    1. D.[[Value]]X[[Value]] 特性的值。
    2. D.[[Writable]]X[[Writable]] 特性的值。
  5. 否则,
    1. 断言:X访问器属性
    2. D.[[Get]]X[[Get]] 特性的值。
    3. D.[[Set]]X[[Set]] 特性的值。
  6. D.[[Enumerable]]X[[Enumerable]] 特性的值。
  7. D.[[Configurable]]X[[Configurable]] 特性的值。
  8. 返回 D

10.1.6 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of 一个普通对象 O takes arguments P (a property key) and Desc (a Property Descriptor) and returns 一个正常完成(包含 Boolean)或一个抛出完成. It performs the following steps when called:

  1. 返回 ? OrdinaryDefineOwnProperty(O, P, Desc)。

10.1.6.1 OrdinaryDefineOwnProperty ( O, P, Desc )

The abstract operation OrdinaryDefineOwnProperty takes arguments O (an Object), P (a property key), and Desc (a Property Descriptor) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. current 为 ? O.[[GetOwnProperty]](P)。
  2. extensible 为 ? IsExtensible(O)。
  3. 返回 ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current)。

10.1.6.2 IsCompatiblePropertyDescriptor ( Extensible, Desc, Current )

The abstract operation IsCompatiblePropertyDescriptor takes arguments Extensible (a Boolean), Desc (a Property Descriptor), and Current (a Property Descriptor or undefined) and returns a Boolean. It performs the following steps when called:

  1. 返回 ValidateAndApplyPropertyDescriptor(undefined, "", Extensible, Desc, Current)。

10.1.6.3 ValidateAndApplyPropertyDescriptor ( O, P, extensible, Desc, current )

The abstract operation ValidateAndApplyPropertyDescriptor takes arguments O (an Object or undefined), P (a property key), extensible (a Boolean), Desc (a Property Descriptor), and current (a Property Descriptor or undefined) and returns a Boolean. 当且仅当 Desc 可以在指定 extensibility 与当前属性 current 的条件下,作为某对象的属性(维护 不变式)被应用时,返回 true。当应用可行且 O 不为 undefined 时,会对名为 P 的属性执行(必要时创建)。 It performs the following steps when called:

  1. 断言:P 是一个属性键
  2. currentundefined,则
    1. extensiblefalse,返回 false
    2. Oundefined,返回 true
    3. IsAccessorDescriptor(Desc) 为 true,则
      1. 在对象 O 上创建名为 P 的自身访问器属性,其 [[Get]][[Set]][[Enumerable]][[Configurable]] 特性若 Desc 含该字段则取其值,否则取该特性的 默认值
    4. 否则,
      1. 在对象 O 上创建名为 P 的自身数据属性,其 [[Value]][[Writable]][[Enumerable]][[Configurable]] 特性若 Desc 含该字段则取其值,否则取该特性的 默认值
    5. 返回 true
  3. 断言:current 为一个完全填充的 Property Descriptor
  4. Desc 不含任何字段,返回 true
  5. current.[[Configurable]]false,则
    1. Desc[[Configurable]]Desc.[[Configurable]]true,返回 false
    2. Desc[[Enumerable]]Desc.[[Enumerable]] 不等于 current.[[Enumerable]],返回 false
    3. IsGenericDescriptor(Desc) 为 falseIsAccessorDescriptor(Desc) 不等于 IsAccessorDescriptor(current),返回 false
    4. IsAccessorDescriptor(current) 为 true,则
      1. Desc[[Get]]SameValue(Desc.[[Get]], current.[[Get]]) 为 false,返回 false
      2. Desc[[Set]]SameValue(Desc.[[Set]], current.[[Set]]) 为 false,返回 false
    5. 否则若 current.[[Writable]]false,则
      1. Desc[[Writable]]Desc.[[Writable]]true,返回 false
      2. NOTE: SameValueNaN 返回 true(可能通过其他方式区分)。此处返回可确保 O 任何已有属性保持不变。
      3. Desc[[Value]] 字段,返回 SameValue(Desc.[[Value]], current.[[Value]])。
  6. O 不为 undefined,则
    1. IsDataDescriptor(current) 为 trueIsAccessorDescriptor(Desc) 为 true,则
      1. Desc[[Configurable]],令 configurableDesc.[[Configurable]];否则令 configurablecurrent.[[Configurable]]
      2. Desc[[Enumerable]],令 enumerableDesc.[[Enumerable]];否则令 enumerablecurrent.[[Enumerable]]
      3. 用一个访问器属性替换对象 O 上名为 P 的属性,其 [[Configurable]][[Enumerable]] 分别设为 configurableenumerable,其 [[Get]][[Set]] 特性若 Desc 含该字段则取其值,否则取该特性的 默认值
    2. 否则若 IsAccessorDescriptor(current) 为 trueIsDataDescriptor(Desc) 为 true,则
      1. Desc[[Configurable]],令 configurableDesc.[[Configurable]];否则令 configurablecurrent.[[Configurable]]
      2. Desc[[Enumerable]],令 enumerableDesc.[[Enumerable]];否则令 enumerablecurrent.[[Enumerable]]
      3. 用一个数据属性替换对象 O 上名为 P 的属性,其 [[Configurable]][[Enumerable]] 分别设为 configurableenumerable,其 [[Value]][[Writable]] 特性若 Desc 含该字段则取其值,否则取该特性的 默认值
    3. 否则,
      1. Desc 的每个字段,将对象 O 上名为 P 的属性对应特性设为该字段的值。
  7. 返回 true

10.1.7 [[HasProperty]] ( P )

The [[HasProperty]] internal method of 一个普通对象 O takes argument P (a property key) and returns 一个正常完成(包含 Boolean)或一个抛出完成. It performs the following steps when called:

  1. 返回 ? OrdinaryHasProperty(O, P)。

10.1.7.1 OrdinaryHasProperty ( O, P )

The abstract operation OrdinaryHasProperty takes arguments O (an Object) and P (a property key) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. hasOwn 为 ? O.[[GetOwnProperty]](P)。
  2. hasOwn 不为 undefined,返回 true
  3. parent 为 ? O.[[GetPrototypeOf]]()。
  4. parent 不为 null,则
    1. 返回 ? parent.[[HasProperty]](P)。
  5. 返回 false

10.1.8 [[Get]] ( P, Receiver )

The [[Get]] internal method of 一个普通对象 O takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns 一个正常完成(包含 ECMAScript 语言值)或一个抛出完成. It performs the following steps when called:

  1. 返回 ? OrdinaryGet(O, P, Receiver)。

10.1.8.1 OrdinaryGet ( O, P, Receiver )

The abstract operation OrdinaryGet takes arguments O (an Object), P (a property key), and Receiver (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. desc 为 ? O.[[GetOwnProperty]](P)。
  2. descundefined,则
    1. parent 为 ? O.[[GetPrototypeOf]]()。
    2. parentnull,返回 undefined
    3. 返回 ? parent.[[Get]](P, Receiver)。
  3. IsDataDescriptor(desc) 为 true,返回 desc.[[Value]]
  4. 断言:IsAccessorDescriptor(desc) 为 true
  5. getterdesc.[[Get]]
  6. getterundefined,返回 undefined
  7. 返回 ? Call(getter, Receiver)。

10.1.9 [[Set]] ( P, V, Receiver )

The [[Set]] internal method of 一个普通对象 O takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns 一个正常完成(包含 Boolean)或一个抛出完成. It performs the following steps when called:

  1. 返回 ? OrdinarySet(O, P, V, Receiver)。

10.1.9.1 OrdinarySet ( O, P, V, Receiver )

The abstract operation OrdinarySet takes arguments O (an Object), P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. ownDesc 为 ? O.[[GetOwnProperty]](P)。
  2. 返回 ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc)。

10.1.9.2 OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc )

The abstract operation OrdinarySetWithOwnDescriptor takes arguments O (an Object), P (a property key), V (an ECMAScript language value), Receiver (an ECMAScript language value), and ownDesc (a Property Descriptor or undefined) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. ownDescundefined,则
    1. parent 为 ? O.[[GetPrototypeOf]]()。
    2. parent 不为 null,则
      1. 返回 ? parent.[[Set]](P, V, Receiver)。
    3. 否则,
      1. ownDesc 设为 PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }。
  2. IsDataDescriptor(ownDesc) 为 true,则
    1. ownDesc.[[Writable]]false,返回 false
    2. Receiver 不是 Object,返回 false
    3. existingDescriptor 为 ? Receiver.[[GetOwnProperty]](P)。
    4. existingDescriptor 不为 undefined,则
      1. IsAccessorDescriptor(existingDescriptor) 为 true,返回 false
      2. existingDescriptor.[[Writable]]false,返回 false
      3. valueDesc 为 PropertyDescriptor { [[Value]]: V }。
      4. 返回 ? Receiver.[[DefineOwnProperty]](P, valueDesc)。
    5. 否则,
      1. 断言:Receiver 目前没有属性 P
      2. 返回 ? CreateDataProperty(Receiver, P, V)。
  3. 断言:IsAccessorDescriptor(ownDesc) 为 true
  4. setterownDesc.[[Set]]
  5. setterundefined,返回 false
  6. 执行 ? Call(setter, Receiver, « V »)。
  7. 返回 true

10.1.10 [[Delete]] ( P )

The [[Delete]] internal method of 一个普通对象 O takes argument P (a property key) and returns 一个正常完成(包含 Boolean)或一个抛出完成. It performs the following steps when called:

  1. 返回 ? OrdinaryDelete(O, P)。

10.1.10.1 OrdinaryDelete ( O, P )

The abstract operation OrdinaryDelete takes arguments O (an Object) and P (a property key) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. desc 为 ? O.[[GetOwnProperty]](P)。
  2. descundefined,返回 true
  3. desc.[[Configurable]]true,则
    1. O 中移除名为 P 的自身属性。
    2. 返回 true
  4. 返回 false

10.1.11 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of 一个普通对象 O takes no arguments and returns 一个正常完成,包含一个属性键 List. It performs the following steps when called:

  1. 返回 OrdinaryOwnPropertyKeys(O)。

10.1.11.1 OrdinaryOwnPropertyKeys ( O )

The abstract operation OrdinaryOwnPropertyKeys takes argument O (an Object) and returns a List of property keys. It performs the following steps when called:

  1. keys 为一个新的空 List
  2. O 的每个自身属性键 P,若 P数组索引,按数字索引升序:
    1. P 追加至 keys
  3. O 的每个自身属性键 P,若 P 是 String 且不是数组索引,按属性创建的时间顺序:
    1. P 追加至 keys
  4. O 的每个自身属性键 P,若 P 是 Symbol,按属性创建时间顺序:
    1. P 追加至 keys
  5. 返回 keys

10.1.12 OrdinaryObjectCreate ( proto [ , additionalInternalSlotsList ] )

The abstract operation OrdinaryObjectCreate takes argument proto (an Object or null) and optional argument additionalInternalSlotsList (a List of names of internal slots) and returns an Object. 用于指定在运行时创建新的普通对象additionalInternalSlotsList 包含必须定义为该对象一部分的额外内部槽名称(除 [[Prototype]][[Extensible]] 之外)。若未提供 additionalInternalSlotsList,则使用一个新的空 List。 It performs the following steps when called:

  1. internalSlotsList 为 « [[Prototype]], [[Extensible]] »。
  2. additionalInternalSlotsList 存在,将 internalSlotsList 设为 internalSlotsListadditionalInternalSlotsList 的列表连接。
  3. OMakeBasicObject(internalSlotsList)。
  4. O.[[Prototype]] 设为 proto
  5. 返回 O
Note

尽管 OrdinaryObjectCreate 除调用 MakeBasicObject 外做的事情很少,使用它明确传达了要创建一个“普通”对象而非特异对象的意图。因此,在本规范中,它不会被任何随后修改对象内部方法、从而使结果变为“非普通”的算法调用。创建特异对象的操作会直接调用 MakeBasicObject

10.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )

The abstract operation OrdinaryCreateFromConstructor takes arguments constructor (a function object) and intrinsicDefaultProto (a String) and optional argument internalSlotsList (a List of names of internal slots) and returns either a normal completion containing an Object or a throw completion. 它创建一个普通对象,其 [[Prototype]] 值取自构造函数"prototype" 属性(若存在)。否则使用由 intrinsicDefaultProto 命名的内在对象作为 [[Prototype]]internalSlotsList 包含需要定义的额外内部槽名称。若未提供 internalSlotsList,则使用新的空 List。 It performs the following steps when called:

  1. 断言:intrinsicDefaultProto 是本规范对某内在对象的名称;对应对象必须是用作 [[Prototype]] 值的内在对象。
  2. proto 为 ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto)。
  3. internalSlotsList 存在,令 slotsListinternalSlotsList
  4. 否则,令 slotsList 为一个新的空 List
  5. 返回 OrdinaryObjectCreate(proto, slotsList)。

10.1.14 GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )

The abstract operation GetPrototypeFromConstructor takes arguments constructor (a function object) and intrinsicDefaultProto (a String) and returns either a normal completion containing an Object or a throw completion. 决定与特定构造函数对应之对象应使用的 [[Prototype]] 值。该值若构造函数具有 "prototype" 属性则从中取得,否则使用由 intrinsicDefaultProto 命名的内在对象作为 [[Prototype]]。 It performs the following steps when called:

  1. 断言:intrinsicDefaultProto 是本规范对某内在对象的名称;对应对象必须是用作对象 [[Prototype]] 值的内在对象。
  2. proto 为 ? Get(constructor, "prototype")。
  3. proto 不是 Object,则
    1. realm 为 ? GetFunctionRealm(constructor)。
    2. proto 设为 realm 中名为 intrinsicDefaultProto 的内在对象。
  4. 返回 proto
Note

constructor 未提供 [[Prototype]] 值,则使用的默认值取自 constructor 函数所属的 realm,而非当前运行执行上下文。

10.1.15 RequireInternalSlot ( O, internalSlot )

The abstract operation RequireInternalSlot takes arguments O (an ECMAScript language value) and internalSlot (an internal slot name) and returns either a normal completion containing unused or a throw completion. 除非 O 是一个 Object 且拥有给定内部槽,否则抛出异常。 It performs the following steps when called:

  1. O 不是 Object,抛出 TypeError 异常。
  2. O 不具有内部槽 internalSlot,抛出 TypeError 异常。
  3. 返回 unused

10.2 ECMAScript 函数对象 (ECMAScript Function Objects)

ECMAScript 函数对象封装了带参数的、闭包于某词法环境之上的 ECMAScript 代码,并支持对该代码的动态求值。一个 ECMAScript 函数对象是一个普通对象,具有与其它普通对象相同的内部槽与内部方法。ECMAScript 函数对象的代码可以是严格模式代码(11.2.2)或非严格代码。其代码为严格模式代码的 ECMAScript 函数对象称为 严格函数 (strict function)。其代码不是严格模式代码的称为 非严格函数 (non-strict function)

[[Extensible]][[Prototype]] 之外,ECMAScript 函数对象还具有 Table 28 中列出的内部槽。

Table 28: ECMAScript 函数对象的内部槽 (Internal Slots of ECMAScript Function Objects)
内部槽 (Internal Slot) 类型 (Type) 描述 (Description)
[[Environment]] an Environment Record 函数闭包所捕获的 Environment Record。作为求值该函数代码时的外层环境。
[[PrivateEnvironment]] a PrivateEnvironment Record or null 函数闭包所捕获的 Private NamesPrivateEnvironment Record。若函数在语法上不被包含于 class 内则为 null。在求值该函数代码时,作为内部类的外层 PrivateEnvironment。
[[FormalParameters]] a Parse Node 定义函数形式参数列表的源文本根解析节点
[[ECMAScriptCode]] a Parse Node 定义函数函数体的源文本根解析节点
[[ConstructorKind]] base or derived 指示该函数是否为派生类构造器。
[[Realm]] a Realm Record 函数被创建时所在的 realm;在求值该函数时提供所有被访问的内在对象。
[[ScriptOrModule]] a Script Record or a Module Record 函数被创建所在的脚本或模块。
[[ThisMode]] lexical, strict, or global 定义在函数形式参数与函数体内 this 引用如何解释。lexical 表示 this 引用词法包围函数的 this 值。strict 表示使用调用该函数时提供的 this 值而不加修改。global 表示 undefinednullthis 值被解释为对全局对象的引用,其它 this 值会先传入 ToObject
[[Strict]] a Boolean 若该函数为严格函数则为 true,若为非严格函数则为 false
[[HomeObject]] an Object 若函数使用 super,此槽为其 super 属性查找起始的对象(通过该对象的 [[GetPrototypeOf]])。
[[SourceText]] a sequence of Unicode code points 定义该函数的源文本
[[Fields]] a List of ClassFieldDefinition Records 若该函数是一个 class,则此列表为该类的非静态字段及其初始化器的记录。
[[PrivateMethods]] a List of PrivateElements 若该函数是一个 class,则此列表表示该类的非静态私有方法与访问器。
[[ClassFieldInitializerName]] a String, a Symbol, a Private Name, or empty 若函数作为类字段的初始化器创建,则为对该字段进行 NamedEvaluation 所使用的名称;否则为 empty
[[IsClassConstructor]] a Boolean 指示该函数是否为类构造器。(若为 true,调用其 [[Call]] 将立即抛出 TypeError 异常。)

所有 ECMAScript 函数对象都具有此处定义的 [[Call]] 内部方法。作为构造器的 ECMAScript 函数还额外具有 [[Construct]] 内部方法。

10.2.1 [[Call]] ( thisArgument, argumentsList )

The [[Call]] internal method of 一个 ECMAScript 函数对象 F takes arguments thisArgument (an ECMAScript language value) and argumentsList (a List of ECMAScript language values) and returns 一个正常完成(包含 ECMAScript 语言值)或一个抛出完成. It performs the following steps when called:

  1. callerContext 为当前运行执行上下文。
  2. calleeContextPrepareForOrdinaryCall(F, undefined)。
  3. 断言:calleeContext 现在是运行执行上下文。
  4. F.[[IsClassConstructor]]true,则
    1. error 为一个新创建的 TypeError 对象。
    2. NOTE: errorcalleeContext 中、使用 F 关联的 Realm Record 创建。
    3. 从执行上下文栈移除 calleeContext 并恢复 callerContext 为运行执行上下文。
    4. 返回 ThrowCompletion(error)。
  5. 执行 OrdinaryCallBindThis(F, calleeContext, thisArgument)。
  6. resultCompletion(OrdinaryCallEvaluateBody(F, argumentsList))。
  7. 从执行上下文栈移除 calleeContext 并恢复 callerContext 为运行执行上下文。
  8. result 是一个 return completion,返回 result.[[Value]]
  9. 断言:result 是一个 throw completion。
  10. 返回 ? result
Note

当在步骤 7 中把 calleeContext 自执行上下文栈移除时,若它被一个可访问的 Generator 挂起并保留以供后续恢复,则不得销毁它。

10.2.1.1 PrepareForOrdinaryCall ( F, newTarget )

The abstract operation PrepareForOrdinaryCall takes arguments F (an ECMAScript function object) and newTarget (an Object or undefined) and returns an execution context. It performs the following steps when called:

  1. callerContext 为当前运行执行上下文。
  2. calleeContext 为一个新的 ECMAScript 代码执行上下文
  3. calleeContext 的 Function 设为 F
  4. calleeRealmF.[[Realm]]
  5. calleeContextRealm 设为 calleeRealm
  6. calleeContext 的 ScriptOrModule 设为 F.[[ScriptOrModule]]
  7. localEnvNewFunctionEnvironment(F, newTarget)。
  8. calleeContext 的 LexicalEnvironment 设为 localEnv
  9. calleeContext 的 VariableEnvironment 设为 localEnv
  10. calleeContext 的 PrivateEnvironment 设为 F.[[PrivateEnvironment]]
  11. callerContext 尚未被挂起,则挂起 callerContext
  12. calleeContext 压入执行上下文栈;calleeContext 现在是运行执行上下文。
  13. NOTE: 之后产生的任何异常对象与 calleeRealm 关联。
  14. 返回 calleeContext

10.2.1.2 OrdinaryCallBindThis ( F, calleeContext, thisArgument )

The abstract operation OrdinaryCallBindThis takes arguments F (an ECMAScript function object), calleeContext (an execution context), and thisArgument (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. thisModeF.[[ThisMode]]
  2. thisModelexical,返回 unused
  3. calleeRealmF.[[Realm]]
  4. localEnvcalleeContext 的 LexicalEnvironment。
  5. thisModestrict,则
    1. thisValuethisArgument
  6. 否则,
    1. thisArgumentundefinednull,则
      1. globalEnvcalleeRealm.[[GlobalEnv]]
      2. 断言:globalEnv 是一个 Global Environment Record
      3. thisValueglobalEnv.[[GlobalThisValue]]
    2. 否则,
      1. thisValue 为 ! ToObject(thisArgument)。
      2. NOTE: ToObject 使用 calleeRealm 产生包装对象。
  7. 断言:localEnv 是一个 Function Environment Record
  8. 断言:下一步不会返回一个 abrupt completion,因为 localEnv.[[ThisBindingStatus]] 不是 initialized
  9. 执行 ! BindThisValue(localEnv, thisValue)。
  10. 返回 unused

10.2.1.3 运行时语义:EvaluateBody

The syntax-directed operation 运行时语义:EvaluateBody takes arguments functionObject (an ECMAScript function object) and argumentsList (a List of ECMAScript language values) and returns a return completion or a throw completion. It is defined piecewise over the following productions:

FunctionBody : FunctionStatementList
  1. Return ? EvaluateFunctionBody of FunctionBody with arguments functionObject and argumentsList.
ConciseBody : ExpressionBody
  1. Return ? EvaluateConciseBody of ConciseBody with arguments functionObject and argumentsList.
GeneratorBody : FunctionBody
  1. Return ? EvaluateGeneratorBody of GeneratorBody with arguments functionObject and argumentsList.
AsyncGeneratorBody : FunctionBody
  1. Return ? EvaluateAsyncGeneratorBody of AsyncGeneratorBody with arguments functionObject and argumentsList.
AsyncFunctionBody : FunctionBody
  1. Return ? EvaluateAsyncFunctionBody of AsyncFunctionBody with arguments functionObject and argumentsList.
AsyncConciseBody : ExpressionBody
  1. Return ? EvaluateAsyncConciseBody of AsyncConciseBody with arguments functionObject and argumentsList.
Initializer : = AssignmentExpression
  1. Assert: argumentsList is empty.
  2. Assert: functionObject.[[ClassFieldInitializerName]] is not empty.
  3. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
    1. Let value be ? NamedEvaluation of Initializer with argument functionObject.[[ClassFieldInitializerName]].
  4. Else,
    1. Let rhs be ? Evaluation of AssignmentExpression.
    2. Let value be ? GetValue(rhs).
  5. Return ReturnCompletion(value).
Note

尽管字段初始化器构成了函数边界,调用 FunctionDeclarationInstantiation 没有可观察效果,因此省略。

ClassStaticBlockBody : ClassStaticBlockStatementList
  1. Assert: argumentsList is empty.
  2. Return ? EvaluateClassStaticBlockBody of ClassStaticBlockBody with argument functionObject.

10.2.1.4 OrdinaryCallEvaluateBody ( F, argumentsList )

The abstract operation OrdinaryCallEvaluateBody takes arguments F (an ECMAScript function object) and argumentsList (a List of ECMAScript language values) and returns a return completion or a throw completion. It performs the following steps when called:

  1. Return ? EvaluateBody of F.[[ECMAScriptCode]] with arguments F and argumentsList.

10.2.2 [[Construct]] ( argumentsList, newTarget )

The [[Construct]] internal method of 一个 ECMAScript 函数对象 F takes arguments argumentsList (a List of ECMAScript language values) and newTarget (a constructor) and returns 一个正常完成(包含 Object)或一个抛出完成. It performs the following steps when called:

  1. callerContext 为当前运行执行上下文。
  2. kindF.[[ConstructorKind]]
  3. kindbase,则
    1. thisArgument 为 ? OrdinaryCreateFromConstructor(newTarget, "%Object.prototype%")。
  4. calleeContextPrepareForOrdinaryCall(F, newTarget)。
  5. 断言:calleeContext 现在是运行执行上下文。
  6. kindbase,则
    1. 执行 OrdinaryCallBindThis(F, calleeContext, thisArgument)。
    2. initializeResultCompletion(InitializeInstanceElements(thisArgument, F))。
    3. initializeResult 是一个 abrupt completion,则
      1. 从执行上下文栈移除 calleeContext 并恢复 callerContext 为运行执行上下文。
      2. 返回 ? initializeResult
  7. constructorEnvcalleeContext 的 LexicalEnvironment。
  8. resultCompletion(OrdinaryCallEvaluateBody(F, argumentsList))。
  9. 从执行上下文栈移除 calleeContext 并恢复 callerContext 为运行执行上下文。
  10. result 是一个 throw completion,则
    1. 返回 ? result
  11. 断言:result 是一个 return completion。
  12. result.[[Value]] 是一个 Object,返回 result.[[Value]]
  13. kindbase,返回 thisArgument
  14. result.[[Value]] 不是 undefined,抛出 TypeError 异常。
  15. thisBinding 为 ? constructorEnv.GetThisBinding()。
  16. 断言:thisBinding 是一个 Object。
  17. 返回 thisBinding

10.2.3 OrdinaryFunctionCreate ( functionPrototype, sourceText, ParameterList, Body, thisMode, env, privateEnv )

The abstract operation OrdinaryFunctionCreate takes arguments functionPrototype (an Object), sourceText (a sequence of Unicode code points), ParameterList (a Parse Node), Body (a Parse Node), thisMode (lexical-this or non-lexical-this), env (an Environment Record), and privateEnv (a PrivateEnvironment Record or null) and returns an ECMAScript function object. 用于在运行时创建一个具有默认 [[Call]] 内部方法且无 [[Construct]] 内部方法(但后续可通过诸如 MakeConstructor 的操作增加)的新函数。sourceText 是待创建函数语法定义的源文本。 It performs the following steps when called:

  1. internalSlotsListTable 28 中列出的内部槽。
  2. FOrdinaryObjectCreate(functionPrototype, internalSlotsList)。
  3. F.[[Call]] 设为 10.2.1 中指定的定义。
  4. F.[[SourceText]] 设为 sourceText
  5. F.[[FormalParameters]] 设为 ParameterList
  6. F.[[ECMAScriptCode]] 设为 Body
  7. Strict 为 IsStrict(Body)。
  8. F.[[Strict]] 设为 Strict
  9. thisModelexical-this,将 F.[[ThisMode]] 设为 lexical
  10. 否则若 Stricttrue,将 F.[[ThisMode]] 设为 strict
  11. 否则,将 F.[[ThisMode]] 设为 global
  12. F.[[IsClassConstructor]] 设为 false
  13. F.[[Environment]] 设为 env
  14. F.[[PrivateEnvironment]] 设为 privateEnv
  15. F.[[ScriptOrModule]] 设为 GetActiveScriptOrModule()。
  16. F.[[Realm]] 设为当前 Realm Record
  17. F.[[HomeObject]] 设为 undefined
  18. F.[[Fields]] 设为一个新的空 List
  19. F.[[PrivateMethods]] 设为一个新的空 List
  20. F.[[ClassFieldInitializerName]] 设为 empty
  21. lenParameterList 的 ExpectedArgumentCount。
  22. 执行 SetFunctionLength(F, len)。
  23. 返回 F

10.2.4 AddRestrictedFunctionProperties ( F, realm )

The abstract operation AddRestrictedFunctionProperties takes arguments F (a function object) and realm (a Realm Record) and returns unused. It performs the following steps when called:

  1. 断言:realm.[[Intrinsics]].[[%ThrowTypeError%]] 存在并已初始化。
  2. throwerrealm.[[Intrinsics]].[[%ThrowTypeError%]]。
  3. 执行 ! DefinePropertyOrThrow(F, "caller", PropertyDescriptor { [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true })。
  4. 执行 ! DefinePropertyOrThrow(F, "arguments", PropertyDescriptor { [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true })。
  5. 返回 unused

10.2.4.1 %ThrowTypeError% ( )

该函数是 %ThrowTypeError% 内在对象。

它是一个匿名内置函数对象,并在每个 realm 中各定义一次。

当被调用时执行以下步骤:

  1. 抛出 TypeError 异常。

此函数的 [[Extensible]] 内部槽的值为 false

该函数的 "length" 属性具备特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

该函数的 "name" 属性具备特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

10.2.5 MakeConstructor ( F [ , writablePrototype [ , prototype ] ] )

The abstract operation MakeConstructor takes argument F (an ECMAScript function object or a built-in function object) and optional arguments writablePrototype (a Boolean) and prototype (an Object) and returns unused. 将 F 转换为构造器。 It performs the following steps when called:

  1. F 是 ECMAScript 函数对象,则
    1. 断言:IsConstructor(F) 为 false
    2. 断言:F 是一个可扩展对象且无 "prototype" 自身属性。
    3. F.[[Construct]] 设为 10.2.2 中指定的定义。
  2. 否则,
    1. F.[[Construct]] 设为 10.3.2 中指定的定义。
  3. F.[[ConstructorKind]] 设为 base
  4. 若未提供 writablePrototype,将 writablePrototype 设为 true
  5. 若未提供 prototype,则
    1. prototype 设为 OrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! DefinePropertyOrThrow(prototype, "constructor", PropertyDescriptor { [[Value]]: F, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: true })。
  6. 执行 ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: false })。
  7. 返回 unused

10.2.6 MakeClassConstructor ( F )

The abstract operation MakeClassConstructor takes argument F (an ECMAScript function object) and returns unused. It performs the following steps when called:

  1. 断言:F.[[IsClassConstructor]]false
  2. F.[[IsClassConstructor]] 设为 true
  3. 返回 unused

10.2.7 MakeMethod ( F, homeObject )

The abstract operation MakeMethod takes arguments F (an ECMAScript function object) and homeObject (an Object) and returns unused. 将 F 配置为一个方法。 It performs the following steps when called:

  1. 断言:homeObject 是一个普通对象
  2. F.[[HomeObject]] 设为 homeObject
  3. 返回 unused

10.2.8 DefineMethodProperty ( homeObject, key, closure, enumerable )

The abstract operation DefineMethodProperty takes arguments homeObject (an Object), key (a property key or Private Name), closure (a function object), and enumerable (a Boolean) and returns either a normal completion containing either a PrivateElement or unused, or an abrupt completion. It performs the following steps when called:

  1. 断言:homeObject 是一个普通、可扩展对象。
  2. key 是一个 Private Name,则
    1. 返回 PrivateElement { [[Key]]: key, [[Kind]]: method, [[Value]]: closure }。
  3. 否则,
    1. desc 为 PropertyDescriptor { [[Value]]: closure, [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true }。
    2. 执行 ? DefinePropertyOrThrow(homeObject, key, desc)。
    3. NOTE: DefinePropertyOrThrow 只有在尝试定义 key"prototype" 的类静态方法时才会返回一个 abrupt completion。
    4. 返回 unused

10.2.9 SetFunctionName ( F, name [ , prefix ] )

The abstract operation SetFunctionName takes arguments F (a function object) and name (a property key or Private Name) and optional argument prefix (a String) and returns unused. 为 F 添加一个 "name" 属性。 It performs the following steps when called:

  1. 断言:F 是一个可扩展对象,且没有 "name" 自身属性。
  2. name 是一个 Symbol,则
    1. descriptionname.[[Description]]
    2. descriptionundefined,将 name 设为空字符串。
    3. 否则,将 name 设为 "["description" ]" 的字符串连接。
  3. 否则若 name 是一个 Private Name,则
    1. name 设为 name.[[Description]]
  4. F 具有 [[InitialName]] 内部槽,则
    1. F.[[InitialName]] 设为 name
  5. 若提供了 prefix,则
    1. name 设为 prefix、代码单元 0x0020 (SPACE)、name 的字符串连接。
    2. F 具有 [[InitialName]] 内部槽,则
      1. NOTE: 下述步骤中的选择在本抽象操作每次执行时独立决定。
      2. 可选地,将 F.[[InitialName]] 设为 name
  6. 执行 ! DefinePropertyOrThrow(F, "name", PropertyDescriptor { [[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true })。
  7. 返回 unused

10.2.10 SetFunctionLength ( F, length )

The abstract operation SetFunctionLength takes arguments F (a function object) and length (a non-negative integer or +∞) and returns unused. 为 F 添加一个 "length" 属性。 It performs the following steps when called:

  1. 断言:F 是一个可扩展对象,且没有 "length" 自身属性。
  2. 执行 ! DefinePropertyOrThrow(F, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true })。
  3. 返回 unused

10.2.11 FunctionDeclarationInstantiation ( func, argumentsList )

The abstract operation FunctionDeclarationInstantiation takes arguments func (an ECMAScript function object) and argumentsList (a List of ECMAScript language values) and returns either a normal completion containing unused or a throw completion. func 是为其建立执行上下文的函数对象

Note

当为求值一个 ECMAScript 函数建立执行上下文时,会创建一个新的 Function Environment Record,并在其中实例化每个形式参数的绑定。函数体内的每个声明也会被实例化。若函数形式参数不包含任何默认值初始化器,则函数体声明与参数在同一个 Environment Record 中实例化。若存在默认值参数初始化器,则为函数体声明创建第二个 Environment Record。形式参数与函数在 FunctionDeclarationInstantiation 过程中被初始化。所有其它绑定在函数体求值期间初始化。

被调用时执行以下步骤:

  1. calleeContext 为当前运行执行上下文。
  2. codefunc.[[ECMAScriptCode]]
  3. strictfunc.[[Strict]]
  4. formalsfunc.[[FormalParameters]]
  5. parameterNamesformals 的 BoundNames。
  6. parameterNames 含有任意重复项,令 hasDuplicatestrue;否则令其为 false
  7. simpleParameterList 为 IsSimpleParameterList of formals
  8. hasParameterExpressions 为 ContainsExpression of formals
  9. varNamescode 的 VarDeclaredNames。
  10. varDeclarationscode 的 VarScopedDeclarations。
  11. lexicalNamescode 的 LexicallyDeclaredNames。
  12. functionNames 为一个新的空 List
  13. functionsToInitialize 为一个新的空 List
  14. 依逆序遍历 varDeclarations 中每个元素 d,执行
    1. d 既不是 VariableDeclaration 也不是 ForBinding 也不是 BindingIdentifier,则
      1. 断言:dFunctionDeclarationGeneratorDeclarationAsyncFunctionDeclarationAsyncGeneratorDeclaration 之一。
      2. fnd 的 BoundNames 唯一元素。
      3. functionNames 不包含 fn,则
        1. fn 插入 functionNames 首部。
        2. NOTE: 若同名函数声明出现多次,使用最后一个声明。
        3. d 插入 functionsToInitialize 首部。
  15. argumentsObjectNeededtrue
  16. func.[[ThisMode]]lexical,则
    1. NOTE: 箭头函数永远没有 arguments 对象。
    2. argumentsObjectNeeded 设为 false
  17. 否则若 parameterNames 包含 "arguments",则
    1. argumentsObjectNeeded 设为 false
  18. 否则若 hasParameterExpressionsfalse,则
    1. functionNames 包含 "arguments"lexicalNames 包含 "arguments",则
      1. argumentsObjectNeeded 设为 false
  19. stricttruehasParameterExpressionsfalse,则
    1. NOTE: 参数只需一个 Environment Record,因为严格模式代码中的 eval 调用不能创建对外可见的新绑定。
    2. envcalleeContext 的 LexicalEnvironment。
  20. 否则,
    1. NOTE: 需要单独的 Environment Record 以确保形式参数列表中的直接 eval 创建的绑定不在参数声明的环境内。
    2. calleeEnvcalleeContext 的 LexicalEnvironment。
    3. envNewDeclarativeEnvironment(calleeEnv)。
    4. 断言:calleeContext 的 VariableEnvironment 与 calleeEnv 相同。
    5. calleeContext 的 LexicalEnvironment 设为 env
  21. parameterNames 中每个字符串 paramName,执行
    1. alreadyDeclared 为 ! env.HasBinding(paramName)。
    2. NOTE: 早期错误确保重复参数名只可出现在无参数默认值或 rest 参数的非严格函数中。
    3. alreadyDeclaredfalse,则
      1. 执行 ! env.CreateMutableBinding(paramName, false)。
      2. hasDuplicatestrue,则
        1. 执行 ! env.InitializeBinding(paramName, undefined)。
  22. argumentsObjectNeededtrue,则
    1. stricttruesimpleParameterListfalse,则
      1. aoCreateUnmappedArgumentsObject(argumentsList)。
    2. 否则,
      1. NOTE: 仅对没有 rest 参数、没有任何参数默认值初始化器、且无解构参数的非严格函数提供映射 arguments 对象。
      2. aoCreateMappedArgumentsObject(func, formals, argumentsList, env)。
    3. stricttrue,则
      1. 执行 ! env.CreateImmutableBinding("arguments", false)。
      2. NOTE: 严格模式代码的早期错误阻止对该绑定的赋值,因此其可变性不可观察。
    4. 否则,
      1. 执行 ! env.CreateMutableBinding("arguments", false)。
    5. 执行 ! env.InitializeBinding("arguments", ao)。
    6. parameterBindingsparameterNames 与 « "arguments" » 的列表连接。
  23. 否则,
    1. parameterBindingsparameterNames
  24. iteratorRecordCreateListIteratorRecord(argumentsList)。
  25. hasDuplicatestrue,则
    1. usedEnvundefined
  26. 否则,
    1. usedEnvenv
  27. NOTE: 下列步骤不会返回 ReturnCompletion,因为在表达式位置唯一产生此类完成的方式是使用 YieldExpression,而其在参数列表中已由 15.5.115.6.1早期错误规则禁止。
  28. 执行 ? IteratorBindingInitialization of formals with arguments iteratorRecord and usedEnv
  29. hasParameterExpressionsfalse,则
    1. NOTE: 参数与顶层 var 只需一个 Environment Record
    2. instantiatedVarNamesparameterBindings 的拷贝。
    3. varNames 中每个元素 n,执行
      1. instantiatedVarNames 不含 n,则
        1. n 追加至 instantiatedVarNames
        2. 执行 ! env.CreateMutableBinding(n, false)。
        3. 执行 ! env.InitializeBinding(n, undefined)。
    4. varEnvenv
  30. 否则,
    1. NOTE: 需要单独的 Environment Record 以确保形式参数列表中的表达式创建的闭包无法见到函数体内的声明。
    2. varEnvNewDeclarativeEnvironment(env)。
    3. calleeContext 的 VariableEnvironment 设为 varEnv
    4. instantiatedVarNames 为一个新的空 List
    5. varNames 中每个元素 n,执行
      1. instantiatedVarNames 不含 n,则
        1. n 追加至 instantiatedVarNames
        2. 执行 ! varEnv.CreateMutableBinding(n, false)。
        3. parameterBindings 不含 n,或 functionNamesn,则
          1. initialValueundefined
        4. 否则,
          1. initialValue 为 ! env.GetBindingValue(n, false)。
        5. 执行 ! varEnv.InitializeBinding(n, initialValue)。
        6. NOTE: 与形式参数同名的 var 最初具有与对应已初始化参数相同的值。
  31. stricttrue,则
    1. lexEnvvarEnv
  32. 否则,
    1. Normative Optional
      宿主是 Web 浏览器或以其它方式支持 块级函数声明 Web 历史兼容语义,则
      1. 对任意 BlockCaseClauseDefaultClause xStatementList 中直接包含,且 code Contains xtrue 的每个 FunctionDeclaration f,执行
        1. FfBindingIdentifier 的 StringValue。
        2. 若用以 FBindingIdentifierVariableStatement 替换该 FunctionDeclaration f 不会为 func 产生早期错误,且 parameterNames 不含 F,则
          1. NOTE: 仅当 F 既不是 VarDeclaredName、也不是形式参数名、也不是另一个 FunctionDeclaration 时才在此实例化 F 的 var 绑定。
          2. instantiatedVarNames 不含 FF 不是 "arguments",则
            1. 执行 ! varEnv.CreateMutableBinding(F, false)。
            2. 执行 ! varEnv.InitializeBinding(F, undefined)。
            3. F 追加至 instantiatedVarNames
          3. FunctionDeclaration f 被求值时,用以下步骤取代 15.2.6 中的 FunctionDeclaration Evaluation 算法:
            1. fEnv 为当前运行执行上下文的 VariableEnvironment。
            2. bEnv 为当前运行执行上下文的 LexicalEnvironment。
            3. fObj 为 ! bEnv.GetBindingValue(F, false)。
            4. 执行 ! fEnv.SetMutableBinding(F, fObj, false)。
            5. 返回 unused
    2. lexEnvNewDeclarativeEnvironment(varEnv)。
    3. NOTE: 非严格函数为顶层词法声明使用一个单独的 Environment Record,以便直接 eval 能确定 eval 代码引入的 var 作用域声明是否与预先存在的顶层词法作用域声明冲突。严格函数不需要此步骤,因为严格直接 eval 总是将所有声明放入新的 Environment Record
  33. calleeContext 的 LexicalEnvironment 设为 lexEnv
  34. lexDeclarationscode 的 LexicallyScopedDeclarations。
  35. lexDeclarations 中每个元素 d,执行
    1. NOTE: 词法声明的名字不可能与函数/生成器声明、形式参数或 var 名相同。词法声明的名字在此仅被实例化但未初始化。
    2. d 的 BoundNames 中每个元素 dn,执行
      1. 若 IsConstantDeclaration of dtrue,则
        1. 执行 ! lexEnv.CreateImmutableBinding(dn, true)。
      2. 否则,
        1. 执行 ! lexEnv.CreateMutableBinding(dn, false)。
  36. privateEnvcalleeContext 的 PrivateEnvironment。
  37. functionsToInitialize 中每个 Parse Node f,执行
    1. fnf 的 BoundNames 唯一元素。
    2. fo 为 InstantiateFunctionObject of f with arguments lexEnv and privateEnv
    3. 执行 ! varEnv.SetMutableBinding(fn, fo, false)。
  38. 返回 unused

10.3 内置函数对象 (Built-in Function Objects)

内置函数对象普通对象;它必须符合 10.1 中对普通对象的要求。

除每个普通对象所需的内部槽(见 10.1)外,内置函数对象还必须具有下列内部槽:

  • [[Realm]]:一个 Realm Record,表示创建该函数的 realm
  • [[InitialName]]:一个 String,函数的初始名称,被 20.2.3.5 使用。

内置函数对象[[Prototype]] 内部槽初始值为 %Function.prototype%,除非另有规定。

内置函数对象必须具有符合 10.3.1 定义的 [[Call]] 内部方法。

仅当被描述为 “constructor” 或本规范中的某个算法显式设置其 [[Construct]] 内部方法时,内置函数对象才具有 [[Construct]]。该 [[Construct]] 必须符合 10.3.2 的定义。

实现可以提供未在本规范中定义的额外内置函数对象

10.3.1 [[Call]] ( thisArgument, argumentsList )

The [[Call]] internal method of 内置函数对象 F takes arguments thisArgument (an ECMAScript language value) and argumentsList (a List of ECMAScript language values) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. 返回 ? BuiltinCallOrConstruct(F, thisArgument, argumentsList, undefined)。

10.3.2 [[Construct]] ( argumentsList, newTarget )

The [[Construct]] internal method of 内置函数对象 F(当该方法存在时) takes arguments argumentsList (a List of ECMAScript language values) and newTarget (a constructor) and returns 返回一个包含 Object 的正常完成或一个抛出完成. It performs the following steps when called:

  1. result 为 ? BuiltinCallOrConstruct(F, uninitialized, argumentsList, newTarget)。
  2. 断言:result 是一个 Object。
  3. 返回 result

10.3.3 BuiltinCallOrConstruct ( F, thisArgument, argumentsList, newTarget )

The abstract operation BuiltinCallOrConstruct takes arguments F (a built-in function object), thisArgument (an ECMAScript language value or uninitialized), argumentsList (a List of ECMAScript language values), and newTarget (a constructor or undefined) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. callerContext 为正在运行的执行上下文。
  2. callerContext 尚未被挂起,则挂起 callerContext
  3. calleeContext 为一个新的执行上下文。
  4. calleeContext 的 Function 设为 F
  5. calleeRealmF.[[Realm]]
  6. calleeContextRealm 设为 calleeRealm
  7. calleeContext 的 ScriptOrModule 设为 null
  8. 执行任何实现定义的、对 calleeContext 必要的初始化。
  9. calleeContext 压入执行上下文栈;calleeContext 现在为运行执行上下文。
  10. resultF 的求值 且符合其规范描述的完成记录结果。若 thisArgumentuninitialized,则 this 值未初始化;否则由 thisArgument 提供 this 值。argumentsList 提供具名参数。newTarget 提供 NewTarget 值。
  11. 注:若 F 在本文档中定义,其“规范描述”即通过算法步骤或其他方式给出的行为。
  12. calleeContext 自执行上下文栈移除并恢复 callerContext 为运行执行上下文。
  13. 返回 ? result
Note

calleeContext 被自执行上下文栈移除时,若其已被可访问的 Generator 挂起并被保留以供后续恢复,则不得销毁它。

10.3.4 CreateBuiltinFunction ( behaviour, length, name, additionalInternalSlotsList [ , realm [ , prototype [ , prefix ] ] ] )

The abstract operation CreateBuiltinFunction takes arguments behaviour (an Abstract Closure, a set of algorithm steps, or some other definition of a function's behaviour provided in this specification), length (a non-negative integer or +∞), name (a property key or a Private Name), and additionalInternalSlotsList (a List of names of internal slots) and optional arguments realm (a Realm Record), prototype (an Object or null), and prefix (a String) and returns 一个内置函数对象. additionalInternalSlotsList 含必须作为该对象一部分定义的额外内部槽名称。此操作创建一个内置函数对象。 It performs the following steps when called:

  1. 若未提供 realm,则将 realm 设为当前 Realm Record
  2. 若未提供 prototype,则将 prototype 设为 realm.[[Intrinsics]].[[%Function.prototype%]]。
  3. internalSlotsList 为包含 10.3 要求的全部内部槽名称的列表,用于即将创建的内置函数对象
  4. additionalInternalSlotsList 的各元素追加到 internalSlotsList
  5. func 为一个新的内置函数对象;当被调用时,使用所提供实参作为 behaviour 指定的对应形参值执行 behaviour 描述的动作。该新函数对象具有名称为 internalSlotsList 各元素的内部槽,以及一个 [[InitialName]] 内部槽。
  6. func.[[Prototype]] 设为 prototype
  7. func.[[Extensible]] 设为 true
  8. func.[[Realm]] 设为 realm
  9. func.[[InitialName]] 设为 null
  10. 执行 SetFunctionLength(func, length)。
  11. 若未提供 prefix,则
    1. 执行 SetFunctionName(func, name)。
  12. 否则,
    1. 执行 SetFunctionName(func, name, prefix)。
  13. 返回 func

本规范中定义的每个内置函数均通过调用 CreateBuiltinFunction 抽象操作创建。

10.4 内置特异对象的内部方法与内部槽 (Built-in Exotic Object Internal Methods and Slots)

本规范定义了多种内置特异对象。除少数特定情形外,它们与普通对象的行为相似。以下特异对象除非下文明确另行规定,否则使用普通对象的内部方法:

10.4.1 绑定函数特异对象 (Bound Function Exotic Objects)

绑定函数特异对象是包装另一个函数对象的特异对象。它是可调用的(具有 [[Call]],可能具有 [[Construct]])。调用它通常导致调用其被包装的函数。

若对象的 [[Call]] 与(若适用)[[Construct]] 内部方法使用以下实现,且其他基本内部方法使用 10.1 中的定义,则该对象是一个 绑定函数特异对象。这些方法在 BoundFunctionCreate 中安装。

绑定函数特异对象不具有 Table 28 中 ECMAScript 函数对象的内部槽;它们改为(除 [[Prototype]][[Extensible]] 外)具有 Table 29 所列的内部槽。

Table 29: 绑定函数特异对象的内部槽 (Internal Slots of Bound Function Exotic Objects)
Internal Slot Type Description
[[BoundTargetFunction]] a callable Object 被包装的函数对象
[[BoundThis]] an ECMAScript language value 调用被包装函数时始终作为 this 的值。
[[BoundArguments]] a List of ECMAScript language values 在任何调用中用作被包装函数前置实参的值列表。

10.4.1.1 [[Call]] ( thisArgument, argumentsList )

The [[Call]] internal method of 绑定函数特异对象 F takes arguments thisArgument (an ECMAScript language value) and argumentsList (a List of ECMAScript language values) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. targetF.[[BoundTargetFunction]]
  2. boundThisF.[[BoundThis]]
  3. boundArgsF.[[BoundArguments]]
  4. argsboundArgsargumentsList 的列表连接。
  5. 返回 ? Call(target, boundThis, args)。

10.4.1.2 [[Construct]] ( argumentsList, newTarget )

The [[Construct]] internal method of 绑定函数特异对象 F takes arguments argumentsList (a List of ECMAScript language values) and newTarget (a constructor) and returns 返回一个包含 Object 的正常完成或一个抛出完成. It performs the following steps when called:

  1. targetF.[[BoundTargetFunction]]
  2. 断言:IsConstructor(target) 为 true
  3. boundArgsF.[[BoundArguments]]
  4. argsboundArgsargumentsList 的列表连接。
  5. SameValue(F, newTarget) 为 true,则将 newTarget 设为 target
  6. 返回 ? Construct(target, args, newTarget)。

10.4.1.3 BoundFunctionCreate ( targetFunction, boundThis, boundArgs )

The abstract operation BoundFunctionCreate takes arguments targetFunction (a function object), boundThis (an ECMAScript language value), and boundArgs (a List of ECMAScript language values) and returns 返回一个包含 function object 的正常完成或一个抛出完成. 用于指定创建新的绑定函数特异对象。 It performs the following steps when called:

  1. proto 为 ? targetFunction.[[GetPrototypeOf]]()。
  2. internalSlotsList 为 « [[Prototype]], [[Extensible]] » 与 Table 29 中内部槽列表的连接。
  3. objMakeBasicObject(internalSlotsList)。
  4. obj.[[Prototype]] 设为 proto
  5. 10.4.1.1 所述设置 obj.[[Call]]
  6. IsConstructor(targetFunction) 为 true,则
    1. 10.4.1.2 所述设置 obj.[[Construct]]
  7. obj.[[BoundTargetFunction]] 设为 targetFunction
  8. obj.[[BoundThis]] 设为 boundThis
  9. obj.[[BoundArguments]] 设为 boundArgs
  10. 返回 obj

10.4.2 数组特异对象 (Array Exotic Objects)

Array 是对数组索引属性键(见 6.1.7)做特殊处理的特异对象。属性名数组索引的属性也称为 element。每个 Array 有一个不可配置的 "length" 属性,其值始终是数学值严格小于 232 的非负整数 Number。"length" 的值在数值上大于其每个名称为数组索引的自身属性的名称;当 Array 的自身属性被创建或改变时,为保持该不变式,会按需要调整其他属性。具体地,当添加一个名称为数组索引的自身属性时,必要时将 "length" 的值改为该索引数值加一;当 "length" 值被改变时,删除所有名称为数组索引且其值不小于新 length 的自身属性。该约束仅适用于 Array 的自身属性,不受其原型链上继承的 "length"数组索引属性影响。

若对象的 [[DefineOwnProperty]] 内部方法使用以下实现,且其其它基本内部方法使用 10.1 中的定义,则其为 数组特异对象(简称 Array)。这些方法在 ArrayCreate 中安装。

10.4.2.1 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of 数组特异对象 A takes arguments P (a property key) and Desc (a Property Descriptor) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. P"length",则
    1. 返回 ? ArraySetLength(A, Desc)。
  2. 否则若 P数组索引,则
    1. lengthDescOrdinaryGetOwnProperty(A, "length")。
    2. 断言:lengthDesc 不为 undefined
    3. 断言:IsDataDescriptor(lengthDesc) 为 true
    4. 断言:lengthDesc.[[Configurable]]false
    5. lengthlengthDesc.[[Value]]
    6. 断言:length 是非负整数 Number。
    7. index 为 ! ToUint32(P)。
    8. indexlengthlengthDesc.[[Writable]]false,返回 false
    9. succeeded 为 ! OrdinaryDefineOwnProperty(A, P, Desc)。
    10. succeededfalse,返回 false
    11. indexlength,则
      1. lengthDesc.[[Value]] 设为 index + 1𝔽
      2. succeeded 设为 ! OrdinaryDefineOwnProperty(A, "length", lengthDesc)。
      3. 断言:succeededtrue
    12. 返回 true
  3. 返回 ? OrdinaryDefineOwnProperty(A, P, Desc)。

10.4.2.2 ArrayCreate ( length [ , proto ] )

The abstract operation ArrayCreate takes argument length (a non-negative integer) and optional argument proto (an Object) and returns 返回一个包含数组特异对象正常完成或一个抛出完成. 用于指定创建新的 Array。 It performs the following steps when called:

  1. length > 232 - 1,抛出 RangeError 异常。
  2. 若未提供 proto,则设 proto%Array.prototype%
  3. AMakeBasicObject[[Prototype]], [[Extensible]] »)。
  4. A.[[Prototype]] 设为 proto
  5. 10.4.2.1 规定设置 A.[[DefineOwnProperty]]
  6. 执行 ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  7. 返回 A

10.4.2.3 ArraySpeciesCreate ( originalArray, length )

The abstract operation ArraySpeciesCreate takes arguments originalArray (an Object) and length (a non-negative integer) and returns 返回一个包含 Object 的正常完成或一个抛出完成. 用于指定通过由 originalArray 派生的构造函数创建新的 Array 或相似对象;不强制该构造函数返回 Array。 It performs the following steps when called:

  1. isArray 为 ? IsArray(originalArray)。
  2. isArrayfalse,返回 ? ArrayCreate(length)。
  3. C 为 ? Get(originalArray, "constructor")。
  4. IsConstructor(C) 为 true,则
    1. thisRealm当前 Realm Record
    2. realmC 为 ? GetFunctionRealm(C)。
    3. thisRealmrealmC 不是同一 Realm Record,则
      1. SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) 为 true,将 C 设为 undefined
  5. C 是一个 Object,则
    1. C 设为 ? Get(C, %Symbol.species%)。
    2. Cnull,将 C 设为 undefined
  6. Cundefined,返回 ? ArrayCreate(length)。
  7. IsConstructor(C) 为 false,抛出 TypeError 异常。
  8. 返回 ? Construct(C, « 𝔽(length) »)。
Note

originalArray 使用非当前执行上下文 realm 的标准内置 Array 构造器创建,则新 Array 使用当前执行上下文的 realm 创建,以保持与历史浏览器行为兼容。

10.4.2.4 ArraySetLength ( A, Desc )

The abstract operation ArraySetLength takes arguments A (an Array) and Desc (a Property Descriptor) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. Desc 不含 [[Value]] 字段,则
    1. 返回 ! OrdinaryDefineOwnProperty(A, "length", Desc)。
  2. newLenDescDesc 的拷贝。
  3. newLen 为 ? ToUint32(Desc.[[Value]])。
  4. numberLen 为 ? ToNumber(Desc.[[Value]])。
  5. SameValueZero(newLen, numberLen) 为 false,抛出 RangeError 异常。
  6. newLenDesc.[[Value]] 设为 newLen
  7. oldLenDescOrdinaryGetOwnProperty(A, "length")。
  8. 断言:oldLenDesc 不为 undefined
  9. 断言:IsDataDescriptor(oldLenDesc) 为 true
  10. 断言:oldLenDesc.[[Configurable]]false
  11. oldLenoldLenDesc.[[Value]]
  12. newLenoldLen,则
    1. 返回 ! OrdinaryDefineOwnProperty(A, "length", newLenDesc)。
  13. oldLenDesc.[[Writable]]false,返回 false
  14. newLenDesc[[Writable]] 字段或 newLenDesc.[[Writable]]true,则
    1. newWritabletrue
  15. 否则,
    1. 注:若某些元素无法删除,则延迟将 [[Writable]] 设为 false
    2. newWritablefalse
    3. newLenDesc.[[Writable]] 设为 true
  16. succeeded 为 ! OrdinaryDefineOwnProperty(A, "length", newLenDesc)。
  17. succeededfalse,返回 false
  18. A 的每个自身属性键 P,若 P数组索引且 ! ToUint32(P) ≥ newLen,按递减数值索引顺序:
    1. deleteSucceeded 为 ! A.[[Delete]](P)。
    2. deleteSucceededfalse,则
      1. newLenDesc.[[Value]] 设为 ! ToUint32(P) + 1𝔽
      2. newWritablefalse,将 newLenDesc.[[Writable]] 设为 false
      3. 执行 ! OrdinaryDefineOwnProperty(A, "length", newLenDesc)。
      4. 返回 false
  19. newWritablefalse,则
    1. succeeded 设为 ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Writable]]: false })。
    2. 断言:succeededtrue
  20. 返回 true
Note

在步骤 34 中,若 Desc.[[Value]] 是对象,其 valueOf 方法被调用两次(历史遗留行为)。

10.4.3 字符串特异对象 (String Exotic Objects)

String 对象是封装一个 String 值并暴露与该值中各代码单元元素对应的虚拟整数索引数据属性的特异对象。字符串特异对象始终具有名为 "length"数据属性,其值为封装的 String 长度。代码单元数据属性"length" 属性均不可写且不可配置。

若对象的 [[GetOwnProperty]][[DefineOwnProperty]][[OwnPropertyKeys]] 内部方法使用以下实现,且其他基本内部方法使用 10.1 中的定义,则该对象是 字符串特异对象(或简称 String 对象)。这些方法在 StringCreate 中安装。

字符串特异对象拥有与普通对象相同的内部槽,另有 [[StringData]] 内部槽。

10.4.3.1 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of 字符串特异对象 S takes argument P (a property key) and returns 返回一个包含 Property Descriptorundefined正常完成. It performs the following steps when called:

  1. descOrdinaryGetOwnProperty(S, P)。
  2. desc 不为 undefined,返回 desc
  3. 返回 StringGetOwnProperty(S, P)。

10.4.3.2 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of 字符串特异对象 S takes arguments P (a property key) and Desc (a Property Descriptor) and returns 返回一个包含 Boolean 的正常完成. It performs the following steps when called:

  1. stringDescStringGetOwnProperty(S, P)。
  2. stringDesc 不为 undefined,则
    1. extensibleS.[[Extensible]]
    2. 返回 IsCompatiblePropertyDescriptor(extensible, Desc, stringDesc)。
  3. 返回 ! OrdinaryDefineOwnProperty(S, P, Desc)。

10.4.3.3 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of 字符串特异对象 O takes no arguments and returns 返回一个包含属性键列表的正常完成. It performs the following steps when called:

  1. keys 为一个新的空列表。
  2. strO.[[StringData]]
  3. 断言:str 是一个 String。
  4. lenstr 的长度。
  5. 对每个整数 i(0 ≤ i < len,按升序):
    1. 追加 ! ToString(𝔽(i)) 至 keys
  6. O 的每个自身属性键 PP数组索引 且 ! ToIntegerOrInfinity(P) ≥ len,按数值索引升序):
    1. 追加 Pkeys
  7. O 的每个自身属性键 PP 为 String 且非数组索引,按创建时间升序):
    1. 追加 Pkeys
  8. O 的每个自身属性键 PP 为 Symbol,按创建时间升序):
    1. 追加 Pkeys
  9. 返回 keys

10.4.3.4 StringCreate ( value, prototype )

The abstract operation StringCreate takes arguments value (a String) and prototype (an Object) and returns 一个字符串特异对象. 用于指定创建新的字符串特异对象。 It performs the following steps when called:

  1. SMakeBasicObject[[Prototype]], [[Extensible]], [[StringData]] »)。
  2. S.[[Prototype]] 设为 prototype
  3. S.[[StringData]] 设为 value
  4. 10.4.3.1 规定设置 S.[[GetOwnProperty]]
  5. 10.4.3.2 规定设置 S.[[DefineOwnProperty]]
  6. 10.4.3.3 规定设置 S.[[OwnPropertyKeys]]
  7. lengthvalue 的长度。
  8. 执行 ! DefinePropertyOrThrow(S, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })。
  9. 返回 S

10.4.3.5 StringGetOwnProperty ( S, P )

The abstract operation StringGetOwnProperty takes arguments S (an Object that has a [[StringData]] internal slot) and P (a property key) and returns 一个 Property Descriptorundefined. It performs the following steps when called:

  1. P 不是 String,返回 undefined
  2. indexCanonicalNumericIndexString(P)。
  3. index 不是整数 Number,返回 undefined
  4. index-0𝔽index < -0𝔽,返回 undefined
  5. strS.[[StringData]]
  6. 断言:str 是 String。
  7. lenstr 的长度。
  8. (index) ≥ len,返回 undefined
  9. resultStr 为从 (index) 到 (index) + 1 的 str 子串。
  10. 返回 PropertyDescriptor { [[Value]]: resultStr, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }。

10.4.4 Arguments 特异对象 (Arguments Exotic Objects)

大多数 ECMAScript 函数向其代码提供一个 arguments 对象。依据函数定义特征,该对象要么是普通对象,要么是 arguments 特异对象arguments 特异对象数组索引属性映射到其关联函数一次调用的形式参数绑定。

若对象的内部方法按以下实现(未指明者使用 10.1 的定义),则为 arguments 特异对象。这些方法在 CreateMappedArgumentsObject 中安装。

Note 1

CreateUnmappedArgumentsObject 归入本条款,但它创建的是普通对象而非 arguments 特异对象

Arguments 特异对象普通对象具有相同内部槽,并另有 [[ParameterMap]]。普通 arguments 对象也有 [[ParameterMap]],其值恒为 undefined,仅被 Object.prototype.toString (20.1.3.6) 用来识别。

Note 2

数值名称小于对应函数形式参数个数的整数索引数据属性初始与执行上下文中的参数绑定共享其值;修改其一会影响另一方。删除并重新定义该属性或将其改为访问器属性会打破这种对应。普通 arguments 对象的属性值仅是实参副本,不与形式参数动态联动。

Note 3

ParameterMap 对象及其属性值是描述 arguments 对象与参数绑定对应关系的机制;它们对 ECMAScript 代码不可直接观察,实现无需实际创建。

Note 4

普通 arguments 对象定义一个名为 "callee" 的不可配置访问器属性,访问时抛出 TypeError。在 arguments 特异对象"callee" 有更具体含义。普通变体的定义防止实现以其他方式定义它。

Note 5

历史上 arguments 特异对象实现包含 "caller" 访问器。ECMAScript 2017 之前规范在普通 arguments 对象上要求其抛出。此扩展已弃用,相关要求被移除。

10.4.4.1 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of arguments 特异对象 args takes argument P (a property key) and returns 返回包含 Property Descriptorundefined正常完成. It performs the following steps when called:

  1. descOrdinaryGetOwnProperty(args, P)。
  2. descundefined,返回 undefined
  3. mapargs.[[ParameterMap]]
  4. isMapped 为 ! HasOwnProperty(map, P)。
  5. isMappedtrue,则
    1. desc.[[Value]] 设为 ! Get(map, P)。
  6. 返回 desc

10.4.4.2 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of arguments 特异对象 args takes arguments P (a property key) and Desc (a Property Descriptor) and returns 返回包含 Boolean 的正常完成. It performs the following steps when called:

  1. mapargs.[[ParameterMap]]
  2. isMapped 为 ! HasOwnProperty(map, P)。
  3. newArgDescDesc
  4. isMappedtrueIsDataDescriptor(Desc) 为 true,则
    1. Desc 不含 [[Value]] 字段、含 [[Writable]] 字段且 Desc.[[Writable]]false,则
      1. newArgDesc 设为 Desc 的拷贝。
      2. newArgDesc.[[Value]] 设为 ! Get(map, P)。
  5. allowed 为 ! OrdinaryDefineOwnProperty(args, P, newArgDesc)。
  6. allowedfalse,返回 false
  7. isMappedtrue,则
    1. IsAccessorDescriptor(Desc) 为 true,则
      1. 执行 ! map.[[Delete]](P)。
    2. 否则,
      1. Desc[[Value]] 字段,则
        1. 断言:下面的 Set 会成功,因为被映射的形式参数总是可写。
        2. 执行 ! Set(map, P, Desc.[[Value]], false)。
      2. Desc[[Writable]] 字段且 Desc.[[Writable]]false,则
        1. 执行 ! map.[[Delete]](P)。
  8. 返回 true

10.4.4.3 [[Get]] ( P, Receiver )

The [[Get]] internal method of arguments 特异对象 args takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. mapargs.[[ParameterMap]]
  2. isMapped 为 ! HasOwnProperty(map, P)。
  3. isMappedfalse,则
    1. 返回 ? OrdinaryGet(args, P, Receiver)。
  4. 否则,
    1. 断言:map 包含 P 的形式参数映射。
    2. 返回 ! Get(map, P)。

10.4.4.4 [[Set]] ( P, V, Receiver )

The [[Set]] internal method of arguments 特异对象 args takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. SameValue(args, Receiver) 为 false,则
    1. isMappedfalse
  2. 否则,
    1. mapargs.[[ParameterMap]]
    2. isMapped 为 ! HasOwnProperty(map, P)。
  3. isMappedtrue,则
    1. 断言:以下 Set 会成功,因为被映射形式参数总是可写。
    2. 执行 ! Set(map, P, V, false)。
  4. 返回 ? OrdinarySet(args, P, V, Receiver)。

10.4.4.5 [[Delete]] ( P )

The [[Delete]] internal method of arguments 特异对象 args takes argument P (a property key) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. mapargs.[[ParameterMap]]
  2. isMapped 为 ! HasOwnProperty(map, P)。
  3. result 为 ? OrdinaryDelete(args, P)。
  4. resulttrueisMappedtrue,则
    1. 执行 ! map.[[Delete]](P)。
  5. 返回 result

10.4.4.6 CreateUnmappedArgumentsObject ( argumentsList )

The abstract operation CreateUnmappedArgumentsObject takes argument argumentsList (a List of ECMAScript language values) and returns 一个普通对象. It performs the following steps when called:

  1. lenargumentsList 中元素个数。
  2. objOrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] »)。
  3. obj.[[ParameterMap]] 设为 undefined
  4. 执行 ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  5. index 为 0。
  6. index < len 重复:
    1. valargumentsList[index]。
    2. 执行 ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val)。
    3. index 设为 index + 1。
  7. 执行 ! DefinePropertyOrThrow(obj, %Symbol.iterator%, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  8. 执行 ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false })。
  9. 返回 obj

10.4.4.7 CreateMappedArgumentsObject ( func, formals, argumentsList, env )

The abstract operation CreateMappedArgumentsObject takes arguments func (an Object), formals (a Parse Node), argumentsList (a List of ECMAScript language values), and env (an Environment Record) and returns 一个 arguments 特异对象. It performs the following steps when called:

  1. 断言:formals 不含 rest 参数、任何绑定模式或初始化器;可包含重复标识符。
  2. lenargumentsList 元素个数。
  3. objMakeBasicObject[[Prototype]], [[Extensible]], [[ParameterMap]] »)。
  4. 10.4.4.1 设置 obj.[[GetOwnProperty]]
  5. 10.4.4.2 设置 obj.[[DefineOwnProperty]]
  6. 10.4.4.3 设置 obj.[[Get]]
  7. 10.4.4.4 设置 obj.[[Set]]
  8. 10.4.4.5 设置 obj.[[Delete]]
  9. obj.[[Prototype]] 设为 %Object.prototype%
  10. mapOrdinaryObjectCreate(null)。
  11. obj.[[ParameterMap]] 设为 map
  12. parameterNamesformals 的 BoundNames。
  13. numberOfParametersparameterNames 元素个数。
  14. index 为 0。
  15. index < len 重复:
    1. valargumentsList[index]。
    2. 执行 ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val)。
    3. index 设为 index + 1。
  16. 执行 ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  17. mappedNames 为新空列表。
  18. index 设为 numberOfParameters - 1。
  19. index ≥ 0 重复:
    1. nameparameterNames[index]。
    2. mappedNames 不含 name,则
      1. 追加 namemappedNames
      2. index < len,则
        1. gMakeArgGetter(name, env)。
        2. pMakeArgSetter(name, env)。
        3. 执行 ! map.[[DefineOwnProperty]](! ToString(𝔽(index)), PropertyDescriptor { [[Set]]: p, [[Get]]: g, [[Enumerable]]: false, [[Configurable]]: true })。
    3. index 设为 index - 1。
  20. 执行 ! DefinePropertyOrThrow(obj, %Symbol.iterator%, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  21. 执行 ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  22. 返回 obj

10.4.4.7.1 MakeArgGetter ( name, env )

The abstract operation MakeArgGetter takes arguments name (a String) and env (an Environment Record) and returns 一个函数对象. 创建一个内置函数对象,执行时返回 env 中对 name 的绑定值。 It performs the following steps when called:

  1. getterClosure 为一个新的无参数 Abstract Closure,捕获 nameenv,调用时执行:
    1. 返回 NormalCompletion(! env.GetBindingValue(name, false))。
  2. getterCreateBuiltinFunction(getterClosure, 0, "", « »)。
  3. 注:getter 不会被 ECMAScript 代码直接访问。
  4. 返回 getter

10.4.4.7.2 MakeArgSetter ( name, env )

The abstract operation MakeArgSetter takes arguments name (a String) and env (an Environment Record) and returns 一个函数对象. 创建一个内置函数对象,执行时设置 envname 的绑定值。 It performs the following steps when called:

  1. setterClosure 为一个带参数 (value) 的新 Abstract Closure,捕获 nameenv,调用时执行:
    1. 返回 NormalCompletion(! env.SetMutableBinding(name, value, false))。
  2. setterCreateBuiltinFunction(setterClosure, 1, "", « »)。
  3. 注:setter 不会被 ECMAScript 代码直接访问。
  4. 返回 setter

10.4.5 TypedArray 特异对象 (TypedArray Exotic Objects)

TypedArray 是对规范数字字符串属性键做特殊处理的特异对象,使用其中属于界内整数索引的子集访问同类型元素,并在不遍历原型链的情况下确保其余索引缺失的不变式。

Note

由于对任意 Number nToString(n) 为规范数字字符串,实现可在无需真实字符串转换的情况下将 Number 当作属性键

TypedArrays 拥有普通对象的内部槽,并额外具有 [[ViewedArrayBuffer]][[TypedArrayName]][[ContentType]][[ByteLength]][[ByteOffset]][[ArrayLength]]

若对象的 [[PreventExtensions]][[GetOwnProperty]][[HasProperty]][[DefineOwnProperty]][[Get]][[Set]][[Delete]][[OwnPropertyKeys]] 内部方法使用本节定义,且其它基本内部方法使用 10.1 的定义,则其为 TypedArray。这些方法由 TypedArrayCreate 安装。

10.4.5.1 [[PreventExtensions]] ( )

The [[PreventExtensions]] internal method of TypedArray O takes no arguments and returns 返回一个包含 Boolean 的正常完成. It performs the following steps when called:

  1. 注:6.1.7.3 中的可扩展性不变式不允许在 O 仍可能获得(或失去后再获得)属性时返回 true;当底层缓冲区重分配且涉及整数索引属性时可能发生该情况。
  2. IsTypedArrayFixedLength(O) 为 false,返回 false
  3. 返回 OrdinaryPreventExtensions(O)。

10.4.5.2 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of TypedArray O takes argument P (a property key) and returns 返回包含 Property Descriptorundefined正常完成. It performs the following steps when called:

  1. P 是 String,则
    1. numericIndexCanonicalNumericIndexString(P)。
    2. numericIndex 不为 undefined,则
      1. valueTypedArrayGetElement(O, numericIndex)。
      2. valueundefined,返回 undefined
      3. 返回 PropertyDescriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }。
  2. 返回 OrdinaryGetOwnProperty(O, P)。

10.4.5.3 [[HasProperty]] ( P )

The [[HasProperty]] internal method of TypedArray O takes argument P (a property key) and returns 返回包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. P 是 String,则
    1. numericIndexCanonicalNumericIndexString(P)。
    2. numericIndex 不为 undefined,返回 IsValidIntegerIndex(O, numericIndex)。
  2. 返回 ? OrdinaryHasProperty(O, P)。

10.4.5.4 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of TypedArray O takes arguments P (a property key) and Desc (a Property Descriptor) and returns 返回包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. P 是 String,则
    1. numericIndexCanonicalNumericIndexString(P)。
    2. numericIndex 不为 undefined,则
      1. IsValidIntegerIndex(O, numericIndex) 为 false,返回 false
      2. Desc[[Configurable]] 且为 false,返回 false
      3. Desc[[Enumerable]] 且为 false,返回 false
      4. IsAccessorDescriptor(Desc) 为 true,返回 false
      5. Desc[[Writable]] 且为 false,返回 false
      6. Desc[[Value]] 字段,执行 ? TypedArraySetElement(O, numericIndex, Desc.[[Value]])。
      7. 返回 true
  2. 返回 ! OrdinaryDefineOwnProperty(O, P, Desc)。

10.4.5.5 [[Get]] ( P, Receiver )

The [[Get]] internal method of TypedArray O takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns 返回包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. P 是 String,则
    1. numericIndexCanonicalNumericIndexString(P)。
    2. numericIndex 不为 undefined,则
      1. 返回 TypedArrayGetElement(O, numericIndex)。
  2. 返回 ? OrdinaryGet(O, P, Receiver)。

10.4.5.6 [[Set]] ( P, V, Receiver )

The [[Set]] internal method of TypedArray O takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns 返回包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. P 是 String,则
    1. numericIndexCanonicalNumericIndexString(P)。
    2. numericIndex 不为 undefined,则
      1. SameValue(O, Receiver) 为 true,则
        1. 执行 ? TypedArraySetElement(O, numericIndex, V)。
        2. 返回 true
      2. IsValidIntegerIndex(O, numericIndex) 为 false,返回 true
  2. 返回 ? OrdinarySet(O, P, V, Receiver)。

10.4.5.7 [[Delete]] ( P )

The [[Delete]] internal method of TypedArray O takes argument P (a property key) and returns 返回包含 Boolean 的正常完成. It performs the following steps when called:

  1. P 是 String,则
    1. numericIndexCanonicalNumericIndexString(P)。
    2. numericIndex 不为 undefined,则
      1. IsValidIntegerIndex(O, numericIndex) 为 false,返回 true;否则返回 false
  2. 返回 ! OrdinaryDelete(O, P)。

10.4.5.8 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of TypedArray O takes no arguments and returns 返回包含属性键列表的正常完成. It performs the following steps when called:

  1. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)。
  2. keys 为新空列表。
  3. IsTypedArrayOutOfBounds(taRecord) 为 false,则
    1. lengthTypedArrayLength(taRecord)。
    2. 对每个整数 i(0 ≤ i < length,升序):
      1. 追加 ! ToString(𝔽(i)) 至 keys
  4. O 的每个自身属性键 PP 为 String 且不是整数索引,按创建时间升序):
    1. 追加 Pkeys
  5. O 的每个自身属性键 PP 为 Symbol,按创建时间升序):
    1. 追加 Pkeys
  6. 返回 keys

10.4.5.9 带缓冲区见证记录的 TypedArray (TypedArray With Buffer Witness Records)

TypedArray With Buffer Witness Record 是用于封装一个 TypedArray 及其被查看缓冲区缓存字节长度的 Record;当缓冲区为可增长 SharedArrayBuffer 时用于确保字节长度数据块的共享内存读取仅发生一次。

其字段列于 Table 30

Table 30: TypedArray With Buffer Witness Record 字段
Field Name Value Meaning
[[Object]] a TypedArray 其缓冲区字节长度被加载的 TypedArray
[[CachedBufferByteLength]] a non-negative integer or detached 记录创建时对象 [[ViewedArrayBuffer]] 的字节长度。

10.4.5.10 MakeTypedArrayWithBufferWitnessRecord ( obj, order )

The abstract operation MakeTypedArrayWithBufferWitnessRecord takes arguments obj (a TypedArray) and order (seq-cst or unordered) and returns 一个 TypedArray With Buffer Witness Record. It performs the following steps when called:

  1. bufferobj.[[ViewedArrayBuffer]]
  2. IsDetachedBuffer(buffer) 为 true,则
    1. byteLengthdetached
  3. 否则,
    1. byteLengthArrayBufferByteLength(buffer, order)。
  4. 返回 TypedArray With Buffer Witness Record { [[Object]]: obj, [[CachedBufferByteLength]]: byteLength }。

10.4.5.11 TypedArrayCreate ( prototype )

The abstract operation TypedArrayCreate takes argument prototype (an Object) and returns 一个 TypedArray. 用于指定创建新的 TypedArray。 It performs the following steps when called:

  1. internalSlotsList 为 « [[Prototype]], [[Extensible]], [[ViewedArrayBuffer]], [[TypedArrayName]], [[ContentType]], [[ByteLength]], [[ByteOffset]], [[ArrayLength]] »。
  2. AMakeBasicObject(internalSlotsList)。
  3. 10.4.5.1 设置 A.[[PreventExtensions]]
  4. 10.4.5.2 设置 A.[[GetOwnProperty]]
  5. 10.4.5.3 设置 A.[[HasProperty]]
  6. 10.4.5.4 设置 A.[[DefineOwnProperty]]
  7. 10.4.5.5 设置 A.[[Get]]
  8. 10.4.5.6 设置 A.[[Set]]
  9. 10.4.5.7 设置 A.[[Delete]]
  10. 10.4.5.8 设置 A.[[OwnPropertyKeys]]
  11. A.[[Prototype]] 设为 prototype
  12. 返回 A

10.4.5.12 TypedArrayByteLength ( taRecord )

The abstract operation TypedArrayByteLength takes argument taRecord (a TypedArray With Buffer Witness Record) and returns 一个非负整数. It performs the following steps when called:

  1. IsTypedArrayOutOfBounds(taRecord) 为 true,返回 0。
  2. lengthTypedArrayLength(taRecord)。
  3. length = 0,返回 0。
  4. OtaRecord.[[Object]]
  5. O.[[ByteLength]] 不为 auto,返回 O.[[ByteLength]]
  6. elementSizeTypedArrayElementSize(O)。
  7. 返回 length × elementSize

10.4.5.13 TypedArrayLength ( taRecord )

The abstract operation TypedArrayLength takes argument taRecord (a TypedArray With Buffer Witness Record) and returns 一个非负整数. It performs the following steps when called:

  1. 断言:IsTypedArrayOutOfBounds(taRecord) 为 false
  2. OtaRecord.[[Object]]
  3. O.[[ArrayLength]] 不为 auto,返回 O.[[ArrayLength]]
  4. 断言:IsFixedLengthArrayBuffer(O.[[ViewedArrayBuffer]]) 为 false
  5. byteOffsetO.[[ByteOffset]]
  6. elementSizeTypedArrayElementSize(O)。
  7. byteLengthtaRecord.[[CachedBufferByteLength]]
  8. 断言:byteLength 不为 detached
  9. 返回 floor((byteLength - byteOffset) / elementSize)。

10.4.5.14 IsTypedArrayOutOfBounds ( taRecord )

The abstract operation IsTypedArrayOutOfBounds takes argument taRecord (a TypedArray With Buffer Witness Record) and returns 一个 Boolean. 检查任一数值属性是否引用了底层缓冲区边界外的索引。 It performs the following steps when called:

  1. OtaRecord.[[Object]]
  2. bufferByteLengthtaRecord.[[CachedBufferByteLength]]
  3. 断言:IsDetachedBuffer(O.[[ViewedArrayBuffer]]) 为 true 当且仅当 bufferByteLengthdetached
  4. bufferByteLengthdetached,返回 true
  5. byteOffsetStartO.[[ByteOffset]]
  6. O.[[ArrayLength]]auto,则
    1. byteOffsetEndbufferByteLength
  7. 否则,
    1. elementSizeTypedArrayElementSize(O)。
    2. byteOffsetEndbyteOffsetStart + O.[[ArrayLength]] × elementSize
  8. byteOffsetStart > bufferByteLengthbyteOffsetEnd > bufferByteLength,返回 true
  9. 注:长度为 0 的 TypedArray 不视为越界。
  10. 返回 false

10.4.5.15 IsTypedArrayFixedLength ( O )

The abstract operation IsTypedArrayFixedLength takes argument O (a TypedArray) and returns 一个 Boolean. It performs the following steps when called:

  1. O.[[ArrayLength]]auto,返回 false
  2. bufferO.[[ViewedArrayBuffer]]
  3. IsFixedLengthArrayBuffer(buffer) 为 falseIsSharedArrayBuffer(buffer) 为 false,返回 false
  4. 返回 true

10.4.5.16 IsValidIntegerIndex ( O, index )

The abstract operation IsValidIntegerIndex takes arguments O (a TypedArray) and index (a Number) and returns 一个 Boolean. It performs the following steps when called:

  1. IsDetachedBuffer(O.[[ViewedArrayBuffer]]) 为 true,返回 false
  2. index 不是整数 Number,返回 false
  3. index-0𝔽index < -0𝔽,返回 false
  4. taRecordMakeTypedArrayWithBufferWitnessRecord(O, unordered)。
  5. 注:当 O 的底层缓冲是可增长 SharedArrayBuffer 时,边界检查不是同步操作。
  6. IsTypedArrayOutOfBounds(taRecord) 为 true,返回 false
  7. lengthTypedArrayLength(taRecord)。
  8. (index) ≥ length,返回 false
  9. 返回 true

10.4.5.17 TypedArrayGetElement ( O, index )

The abstract operation TypedArrayGetElement takes arguments O (a TypedArray) and index (a Number) and returns a Number, a BigInt, 或 undefined. It performs the following steps when called:

  1. IsValidIntegerIndex(O, index) 为 false,返回 undefined
  2. offsetO.[[ByteOffset]]
  3. elementSizeTypedArrayElementSize(O)。
  4. byteIndexInBuffer 为 ((index) × elementSize) + offset
  5. elementTypeTypedArrayElementType(O)。
  6. 返回 GetValueFromBuffer(O.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, true, unordered)。

10.4.5.18 TypedArraySetElement ( O, index, value )

The abstract operation TypedArraySetElement takes arguments O (a TypedArray), index (a Number), and value (an ECMAScript language value) and returns 返回包含 unused正常完成或一个抛出完成. It performs the following steps when called:

  1. O.[[ContentType]]bigint,令 numValue 为 ? ToBigInt(value);否则令 numValue 为 ? ToNumber(value)。
  2. IsValidIntegerIndex(O, index) 为 true,则
    1. offsetO.[[ByteOffset]]
    2. elementSizeTypedArrayElementSize(O)。
    3. byteIndexInBuffer 为 ((index) × elementSize) + offset
    4. elementTypeTypedArrayElementType(O)。
    5. 执行 SetValueInBuffer(O.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, numValue, true, unordered)。
  3. 返回 unused
Note

此操作表面上总是成功;当写入越界或底层 ArrayBuffer 已分离时不产生效果。

10.4.5.19 IsArrayBufferViewOutOfBounds ( O )

The abstract operation IsArrayBufferViewOutOfBounds takes argument O (a TypedArray or a DataView) and returns 一个 Boolean. 检查 TypedArray 的数值属性或 DataView 方法是否可能引用底层数据块范围之外的值;为上游规范提供便利。 It performs the following steps when called:

  1. O 具有 [[DataView]] 内部槽,则
    1. viewRecordMakeDataViewWithBufferWitnessRecord(O, seq-cst)。
    2. 返回 IsViewOutOfBounds(viewRecord)。
  2. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)。
  3. 返回 IsTypedArrayOutOfBounds(taRecord)。

10.4.6 模块命名空间特异对象 (Module Namespace Exotic Objects)

模块命名空间特异对象是一个暴露 ECMAScript Module 导出绑定的特异对象(见 16.2.3)。其字符串键自身属性与该 Module 导出的绑定名一一对应,包括通过 export * 间接导出的绑定。每个字符串键属性的键即对应导出绑定名的 StringValue。这些是其全部字符串键属性。每个此类属性特性为 { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }。模块命名空间特异对象不可扩展。

若对象的 [[GetPrototypeOf]][[SetPrototypeOf]][[IsExtensible]][[PreventExtensions]][[GetOwnProperty]][[DefineOwnProperty]][[HasProperty]][[Get]][[Set]][[Delete]][[OwnPropertyKeys]] 内部方法使用本节定义,且其它基本内部方法使用 10.1 的定义,则其为 模块命名空间特异对象。这些方法由 ModuleNamespaceCreate 安装。

模块命名空间特异对象具有 Table 31 定义的内部槽。

Table 31: 模块命名空间特异对象的内部槽 (Internal Slots of Module Namespace Exotic Objects)
Internal Slot Type Description
[[Module]] a Module Record 此命名空间暴露其导出的 Module Record
[[Exports]] a List of Strings 作为该对象自身属性暴露的导出名称字符串列表,按字典序代码单元顺序排序。

10.4.6.1 [[GetPrototypeOf]] ( )

The [[GetPrototypeOf]] internal method of 模块命名空间特异对象 takes no arguments and returns 返回一个包含 null正常完成. It performs the following steps when called:

  1. 返回 null

10.4.6.2 [[SetPrototypeOf]] ( V )

The [[SetPrototypeOf]] internal method of 模块命名空间特异对象 O takes argument V (an Object or null) and returns 返回一个包含 Boolean 的正常完成. It performs the following steps when called:

  1. 返回 ! SetImmutablePrototype(O, V)。

10.4.6.3 [[IsExtensible]] ( )

The [[IsExtensible]] internal method of 模块命名空间特异对象 takes no arguments and returns 返回一个包含 false正常完成. It performs the following steps when called:

  1. 返回 false

10.4.6.4 [[PreventExtensions]] ( )

The [[PreventExtensions]] internal method of 模块命名空间特异对象 takes no arguments and returns 返回一个包含 true正常完成. It performs the following steps when called:

  1. 返回 true

10.4.6.5 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of 模块命名空间特异对象 O takes argument P (a property key) and returns 返回一个包含 Property Descriptorundefined正常完成,或一个抛出完成. It performs the following steps when called:

  1. P 是 Symbol,返回 OrdinaryGetOwnProperty(O, P)。
  2. exportsO.[[Exports]]
  3. exports 不含 P,返回 undefined
  4. value 为 ? O.[[Get]](P, O)。
  5. 返回 PropertyDescriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }。

10.4.6.6 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of 模块命名空间特异对象 O takes arguments P (a property key) and Desc (a Property Descriptor) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. P 是 Symbol,返回 ! OrdinaryDefineOwnProperty(O, P, Desc)。
  2. current 为 ? O.[[GetOwnProperty]](P)。
  3. currentundefined,返回 false
  4. Desc[[Configurable]] 且为 true,返回 false
  5. Desc[[Enumerable]] 且为 false,返回 false
  6. IsAccessorDescriptor(Desc) 为 true,返回 false
  7. Desc[[Writable]] 且为 false,返回 false
  8. Desc[[Value]] 字段,返回 SameValue(Desc.[[Value]], current.[[Value]])。
  9. 返回 true

10.4.6.7 [[HasProperty]] ( P )

The [[HasProperty]] internal method of 模块命名空间特异对象 O takes argument P (a property key) and returns 返回一个包含 Boolean 的正常完成. It performs the following steps when called:

  1. P 是 Symbol,返回 ! OrdinaryHasProperty(O, P)。
  2. exportsO.[[Exports]]
  3. exportsP,返回 true
  4. 返回 false

10.4.6.8 [[Get]] ( P, Receiver )

The [[Get]] internal method of 模块命名空间特异对象 O takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. P 是 Symbol,则
    1. 返回 ! OrdinaryGet(O, P, Receiver)。
  2. exportsO.[[Exports]]
  3. exports 不含 P,返回 undefined
  4. mO.[[Module]]
  5. bindingm.ResolveExport(P)。
  6. 断言:bindingResolvedBinding Record
  7. targetModulebinding.[[Module]]
  8. 断言:targetModule 不为 undefined
  9. binding.[[BindingName]]namespace,则
    1. 返回 GetModuleNamespace(targetModule)。
  10. targetEnvtargetModule.[[Environment]]
  11. targetEnvempty,抛出 ReferenceError 异常。
  12. 返回 ? targetEnv.GetBindingValue(binding.[[BindingName]], true)。
Note

ResolveExport 无副作用;对相同参数组合多次调用结果必须一致。实现可预先计算或缓存每个命名空间对象 [[Exports]] 的 ResolveExport 结果。

10.4.6.9 [[Set]] ( P, V, Receiver )

The [[Set]] internal method of 模块命名空间特异对象 takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns 返回一个包含 false正常完成. It performs the following steps when called:

  1. 返回 false

10.4.6.10 [[Delete]] ( P )

The [[Delete]] internal method of 模块命名空间特异对象 O takes argument P (a property key) and returns 返回一个包含 Boolean 的正常完成. It performs the following steps when called:

  1. P 是 Symbol,则
    1. 返回 ! OrdinaryDelete(O, P)。
  2. exportsO.[[Exports]]
  3. exportsP,返回 false
  4. 返回 true

10.4.6.11 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of 模块命名空间特异对象 O takes no arguments and returns 返回一个包含属性键列表的正常完成. It performs the following steps when called:

  1. exportsO.[[Exports]]
  2. symbolKeysOrdinaryOwnPropertyKeys(O)。
  3. 返回 exportssymbolKeys 的列表连接结果。

10.4.6.12 ModuleNamespaceCreate ( module, exports )

The abstract operation ModuleNamespaceCreate takes arguments module (a Module Record) and exports (a List of Strings) and returns 一个模块命名空间特异对象. 用于指定创建新的模块命名空间特异对象。 It performs the following steps when called:

  1. 断言:module.[[Namespace]]empty
  2. internalSlotsListTable 31 中列出的内部槽列表。
  3. MMakeBasicObject(internalSlotsList)。
  4. M 的基本内部方法设为 10.4.6 中的定义。
  5. M.[[Module]] 设为 module
  6. sortedExports 为对 exports 元素按字典序代码单元排序后的列表。
  7. M.[[Exports]] 设为 sortedExports
  8. 创建 M 的自身属性以对应 28.3 中的定义。
  9. module.[[Namespace]] 设为 M
  10. 返回 M

10.4.7 不可变原型特异对象 (Immutable Prototype Exotic Objects)

不可变原型特异对象是其 [[Prototype]] 内部槽一旦初始化即不再改变的特异对象。

若对象的 [[SetPrototypeOf]] 内部方法使用以下实现(其它基本内部方法可视具体对象采用任意实现),则该对象是 不可变原型特异对象

Note

与其它特异对象不同,不可变原型特异对象没有专门的创建抽象操作;因它们仅用于 %Object.prototype%宿主环境宿主环境中相关对象可能在其它方面也是特异的,需单独的创建过程。

10.4.7.1 [[SetPrototypeOf]] ( V )

The [[SetPrototypeOf]] internal method of 不可变原型特异对象 O takes argument V (an Object or null) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 返回 ? SetImmutablePrototype(O, V)。

10.4.7.2 SetImmutablePrototype ( O, V )

The abstract operation SetImmutablePrototype takes arguments O (an Object) and V (an Object or null) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. current 为 ? O.[[GetPrototypeOf]]()。
  2. SameValue(V, current) 为 true,返回 true
  3. 返回 false

10.5 Proxy 对象的内部方法与内部槽 (Proxy Object Internal Methods and Internal Slots)

Proxy 对象是一种特异对象,其关键内部方法部分由 ECMAScript 代码实现。每个 Proxy 对象都有名为 [[ProxyHandler]] 的内部槽。[[ProxyHandler]] 的值要么是一个对象(称为该 proxy 的 handler 对象),要么是 null。handler 对象的方法(见 Table 32)可用于增强一个或多个 Proxy 内部方法的实现。每个 Proxy 对象还具有名为 [[ProxyTarget]] 的内部槽,其值是一个对象或 null。该对象称为 proxy 的 target 对象

若一个对象的关键内部方法(若适用包括 [[Call]][[Construct]])使用本节的定义,则该对象为 Proxy 特异对象。这些内部方法在 ProxyCreate 中安装。

Table 32: Proxy 处理器方法 (Proxy Handler Methods)
内部方法 (Internal Method) 处理器方法 (Handler Method)
[[GetPrototypeOf]] getPrototypeOf
[[SetPrototypeOf]] setPrototypeOf
[[IsExtensible]] isExtensible
[[PreventExtensions]] preventExtensions
[[GetOwnProperty]] getOwnPropertyDescriptor
[[DefineOwnProperty]] defineProperty
[[HasProperty]] has
[[Get]] get
[[Set]] set
[[Delete]] deleteProperty
[[OwnPropertyKeys]] ownKeys
[[Call]] apply
[[Construct]] construct

当调用某个 handler 方法以提供 Proxy 内部方法的实现时,会将该 proxy 的 target 对象作为参数传入。handler 对象不一定具备每个关键内部方法对应的 trap;如果缺少对应 trap,则在 proxy 上调用该内部方法会转发到 target 对象上的对应内部方法。

Proxy 对象的 [[ProxyHandler]][[ProxyTarget]] 内部槽在创建时总被初始化,通常不可再修改。某些 Proxy 被创建为可随后被 撤销(revoked)。当一个 proxy 被撤销时,其 [[ProxyHandler]][[ProxyTarget]] 被设为 null,使得后续对该 Proxy 的内部方法调用抛出 TypeError 异常。

由于 Proxy 允许内部方法实现由任意 ECMAScript 代码提供,可能定义出其 handler 方法违反 6.1.7.3 中不变式的 Proxy。该处定义的一些内部方法不变式是关键完整性不变式;本节给出的 Proxy 内部方法会显式强制这些不变式。ECMAScript 实现必须在所有可能的不变式违例情况下保持健壮。

以下算法中,假设 O 为一个 ECMAScript Proxy 对象,P属性键值,V 为任意 ECMAScript 语言值Desc 为一个 Property Descriptor 记录。

10.5.1 [[GetPrototypeOf]] ( )

The [[GetPrototypeOf]] internal method of Proxy 特异对象 O takes no arguments and returns 返回一个包含 Object 或 null正常完成,或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "getPrototypeOf")。
  6. trapundefined,则
    1. 返回 ? target.[[GetPrototypeOf]]()。
  7. handlerProto 为 ? Call(trap, handler, « target »)。
  8. handlerProto不是 Object 且也不是 null,抛出 TypeError 异常。
  9. extensibleTarget 为 ? IsExtensible(target)。
  10. extensibleTargettrue,返回 handlerProto
  11. targetProto 为 ? target.[[GetPrototypeOf]]()。
  12. SameValue(handlerProto, targetProto) 为 false,抛出 TypeError 异常。
  13. 返回 handlerProto
Note

Proxy 的 [[GetPrototypeOf]] 强制以下不变式:

  • 结果必须是 Objectnull
  • 若 target 不可扩展,对 Proxy 调用 [[GetPrototypeOf]] 的结果须与对其 target 调用的结果相同。

10.5.2 [[SetPrototypeOf]] ( V )

The [[SetPrototypeOf]] internal method of Proxy 特异对象 O takes argument V (an Object or null) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "setPrototypeOf")。
  6. trapundefined,则
    1. 返回 ? target.[[SetPrototypeOf]](V)。
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target, V »))。
  8. booleanTrapResultfalse,返回 false
  9. extensibleTarget 为 ? IsExtensible(target)。
  10. extensibleTargettrue,返回 true
  11. targetProto 为 ? target.[[GetPrototypeOf]]()。
  12. SameValue(V, targetProto) 为 false,抛出 TypeError 异常。
  13. 返回 true
Note

Proxy 的 [[SetPrototypeOf]] 强制以下不变式:

  • 结果是一个 Boolean。
  • 若 target 不可扩展,参数值必须与对 target 调用 [[GetPrototypeOf]] 的结果相同。

10.5.3 [[IsExtensible]] ( )

The [[IsExtensible]] internal method of Proxy 特异对象 O takes no arguments and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "isExtensible")。
  6. trapundefined,则
    1. 返回 ? IsExtensible(target)。
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target »))。
  8. targetResult 为 ? IsExtensible(target)。
  9. booleanTrapResult 不等于 targetResult,抛出 TypeError 异常。
  10. 返回 booleanTrapResult
Note

Proxy 的 [[IsExtensible]] 强制以下不变式:

  • 结果是 Boolean。
  • 对 Proxy 的调用结果必须与对其 target 的调用结果一致。

10.5.4 [[PreventExtensions]] ( )

The [[PreventExtensions]] internal method of Proxy 特异对象 O takes no arguments and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "preventExtensions")。
  6. trapundefined,则
    1. 返回 ? target.[[PreventExtensions]]()
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target »))。
  8. booleanTrapResulttrue,则
    1. extensibleTarget 为 ? IsExtensible(target)。
    2. extensibleTargettrue,抛出 TypeError 异常。
  9. 返回 booleanTrapResult
Note

Proxy 的 [[PreventExtensions]] 强制以下不变式:

  • 结果是 Boolean。
  • 仅当 target 的 [[IsExtensible]]false 时才可返回 true

10.5.5 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of Proxy 特异对象 O takes argument P (a property key) and returns 返回一个包含 Property Descriptorundefined正常完成,或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "getOwnPropertyDescriptor")。
  6. trapundefined,则
    1. 返回 ? target.[[GetOwnProperty]](P)。
  7. trapResultObj 为 ? Call(trap, handler, « target, P »)。
  8. trapResultObj 不是 Object 且也不是 undefined,抛出 TypeError 异常。
  9. targetDesc 为 ? target.[[GetOwnProperty]](P)。
  10. trapResultObjundefined,则
    1. targetDescundefined,返回 undefined
    2. targetDesc.[[Configurable]]false,抛出 TypeError 异常。
    3. extensibleTarget 为 ? IsExtensible(target)。
    4. extensibleTargetfalse,抛出 TypeError 异常。
    5. 返回 undefined
  11. extensibleTarget 为 ? IsExtensible(target)。
  12. resultDesc 为 ? ToPropertyDescriptor(trapResultObj)。
  13. 执行 CompletePropertyDescriptor(resultDesc)。
  14. validIsCompatiblePropertyDescriptor(extensibleTarget, resultDesc, targetDesc)。
  15. validfalse,抛出 TypeError 异常。
  16. resultDesc.[[Configurable]]false,则
    1. targetDescundefinedtargetDesc.[[Configurable]]true,则
      1. 抛出 TypeError 异常。
    2. resultDesc[[Writable]]resultDesc.[[Writable]]false,则
      1. 断言:targetDesc[[Writable]]
      2. targetDesc.[[Writable]]true,抛出 TypeError 异常。
  17. 返回 resultDesc
Note

Proxy 的 [[GetOwnProperty]] 强制以下不变式:

  • 结果必须是 Objectundefined
  • 若 target 上存在一个不可配置自身属性,不得报告其不存在。
  • 若 target 不可扩展且存在该自身属性,不得报告其不存在。
  • 若 target 不可扩展且不存在该自身属性,不得报告其存在。
  • 不得报告某属性为不可配置,除非它在 target 上为不可配置自身属性。
  • 不得同时报告某属性为不可配置且不可写,除非它在 target 上为不可配置且不可写自身属性。

10.5.6 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of Proxy 特异对象 O takes arguments P (a property key) and Desc (a Property Descriptor) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "defineProperty")。
  6. trapundefined,则
    1. 返回 ? target.[[DefineOwnProperty]](P, Desc)。
  7. descObjFromPropertyDescriptor(Desc)。
  8. booleanTrapResultToBoolean(? Call(trap, handler, « target, P, descObj »))。
  9. booleanTrapResultfalse,返回 false
  10. targetDesc 为 ? target.[[GetOwnProperty]](P)。
  11. extensibleTarget 为 ? IsExtensible(target)。
  12. Desc[[Configurable]]Desc.[[Configurable]]false,则
    1. settingConfigFalsetrue
  13. 否则,
    1. settingConfigFalsefalse
  14. targetDescundefined,则
    1. extensibleTargetfalse,抛出 TypeError 异常。
    2. settingConfigFalsetrue,抛出 TypeError 异常。
  15. 否则,
    1. IsCompatiblePropertyDescriptor(extensibleTarget, Desc, targetDesc) 为 false,抛出 TypeError 异常。
    2. settingConfigFalsetruetargetDesc.[[Configurable]]true,抛出 TypeError 异常。
    3. IsDataDescriptor(targetDesc) 为 truetargetDesc.[[Configurable]]falsetargetDesc.[[Writable]]true,则
      1. Desc[[Writable]]Desc.[[Writable]]false,抛出 TypeError 异常。
  16. 返回 true
Note

Proxy 的 [[DefineOwnProperty]] 强制以下不变式:

  • 结果为 Boolean。
  • 若 target 不可扩展,不得添加新属性。
  • 不得创建不可配置属性,除非 target 上已有对应不可配置自身属性。
  • 不得创建既不可配置又不可写属性,除非 target 上已有对应不可配置且不可写自身属性。
  • 若属性在 target 上已有对应属性,则用给定描述符通过 [[DefineOwnProperty]] 作用于 target 不会抛出异常。

10.5.7 [[HasProperty]] ( P )

The [[HasProperty]] internal method of Proxy 特异对象 O takes argument P (a property key) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "has")。
  6. trapundefined,则
    1. 返回 ? target.[[HasProperty]](P)。
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target, P »))。
  8. booleanTrapResultfalse,则
    1. targetDesc 为 ? target.[[GetOwnProperty]](P)。
    2. targetDesc 不为 undefined,则
      1. targetDesc.[[Configurable]]false,抛出 TypeError 异常。
      2. extensibleTarget 为 ? IsExtensible(target)。
      3. extensibleTargetfalse,抛出 TypeError 异常。
  9. 返回 booleanTrapResult
Note

Proxy 的 [[HasProperty]] 强制以下不变式:

  • 结果为 Boolean。
  • 若 target 上存在不可配置自身属性,不得报告其不存在。
  • 若 target 不可扩展且存在该自身属性,不得报告其不存在。

10.5.8 [[Get]] ( P, Receiver )

The [[Get]] internal method of Proxy 特异对象 O takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "get")。
  6. trapundefined,则
    1. 返回 ? target.[[Get]](P, Receiver)。
  7. trapResult 为 ? Call(trap, handler, « target, P, Receiver »)。
  8. targetDesc 为 ? target.[[GetOwnProperty]](P)。
  9. targetDesc 不为 undefinedtargetDesc.[[Configurable]]false,则
    1. IsDataDescriptor(targetDesc) 为 truetargetDesc.[[Writable]]false,则
      1. SameValue(trapResult, targetDesc.[[Value]]) 为 false,抛出 TypeError 异常。
    2. IsAccessorDescriptor(targetDesc) 为 truetargetDesc.[[Get]]undefined,则
      1. trapResult 不为 undefined,抛出 TypeError 异常。
  10. 返回 trapResult
Note

Proxy 的 [[Get]] 强制以下不变式:

  • 若 target 上对应属性为不可写、不可配置的自身数据属性,则读取结果必须与其值相同。
  • 若 target 上对应属性为不可配置自身访问器属性且其 [[Get]]undefined,则读取结果必须为 undefined

10.5.9 [[Set]] ( P, V, Receiver )

The [[Set]] internal method of Proxy 特异对象 O takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "set")。
  6. trapundefined,则
    1. 返回 ? target.[[Set]](P, V, Receiver)。
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target, P, V, Receiver »))。
  8. booleanTrapResultfalse,返回 false
  9. targetDesc 为 ? target.[[GetOwnProperty]](P)。
  10. targetDesc 不为 undefinedtargetDesc.[[Configurable]]false,则
    1. IsDataDescriptor(targetDesc) 为 truetargetDesc.[[Writable]]false,则
      1. SameValue(V, targetDesc.[[Value]]) 为 false,抛出 TypeError 异常。
    2. IsAccessorDescriptor(targetDesc) 为 true,则
      1. targetDesc.[[Set]]undefined,抛出 TypeError 异常。
  11. 返回 true
Note

Proxy 的 [[Set]] 强制以下不变式:

  • 结果为 Boolean。
  • 若 target 上对应属性为不可写且不可配置的数据属性,不得改为不同的值。
  • 若 target 上对应属性为不可配置自身访问器属性且其 [[Set]]undefined,不得设置该属性值。

10.5.10 [[Delete]] ( P )

The [[Delete]] internal method of Proxy 特异对象 O takes argument P (a property key) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "deleteProperty")。
  6. trapundefined,则
    1. 返回 ? target.[[Delete]](P)。
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target, P »))。
  8. booleanTrapResultfalse,返回 false
  9. targetDesc 为 ? target.[[GetOwnProperty]](P)。
  10. targetDescundefined,返回 true
  11. targetDesc.[[Configurable]]false,抛出 TypeError 异常。
  12. extensibleTarget 为 ? IsExtensible(target)。
  13. extensibleTargetfalse,抛出 TypeError 异常。
  14. 返回 true
Note

Proxy 的 [[Delete]] 强制以下不变式:

  • 结果为 Boolean。
  • 若属性在 target 上是不可配置自身属性,不得报告其已删除。
  • 若属性在 target 上是自身属性且 target 不可扩展,不得报告其已删除。

10.5.11 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of Proxy 特异对象 O takes no arguments and returns 返回一个包含属性键列表的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "ownKeys")。
  6. trapundefined,则
    1. 返回 ? target.[[OwnPropertyKeys]]()
  7. trapResultArray 为 ? Call(trap, handler, « target »)。
  8. trapResult 为 ? CreateListFromArrayLike(trapResultArray, property-key)。
  9. trapResult 含任何重复项,抛出 TypeError 异常。
  10. extensibleTarget 为 ? IsExtensible(target)。
  11. targetKeys 为 ? target.[[OwnPropertyKeys]]()
  12. 断言:targetKeys属性键列表。
  13. 断言:targetKeys 不含重复项。
  14. targetConfigurableKeys 为新空列表。
  15. targetNonconfigurableKeys 为新空列表。
  16. targetKeys 中每个元素 key
    1. desc 为 ? target.[[GetOwnProperty]](key)。
    2. desc 不为 undefineddesc.[[Configurable]]false,则
      1. key 追加至 targetNonconfigurableKeys
    3. 否则,
      1. key 追加至 targetConfigurableKeys
  17. extensibleTargettruetargetNonconfigurableKeys 为空,则
    1. 返回 trapResult
  18. uncheckedResultKeys 为包含 trapResult 各元素的新列表。
  19. targetNonconfigurableKeys 中每个 key
    1. uncheckedResultKeys 不含 key,抛出 TypeError 异常。
    2. uncheckedResultKeys 移除 key
  20. extensibleTargettrue,返回 trapResult
  21. targetConfigurableKeys 中每个 key
    1. uncheckedResultKeys 不含 key,抛出 TypeError 异常。
    2. uncheckedResultKeys 移除 key
  22. uncheckedResultKeys 非空,抛出 TypeError 异常。
  23. 返回 trapResult
Note

Proxy 的 [[OwnPropertyKeys]] 强制以下不变式:

  • 结果是一个列表。
  • 返回列表不含重复项。
  • 列表中每个元素都是属性键
  • 列表必须包含 target 所有不可配置自身属性的键。
  • 若 target 不可扩展,则列表必须精确包含其全部自身属性键且不含其他值。

10.5.12 [[Call]] ( thisArgument, argumentsList )

The [[Call]] internal method of Proxy 特异对象 O takes arguments thisArgument (an ECMAScript language value) and argumentsList (a List of ECMAScript language values) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "apply")。
  6. trapundefined,则
    1. 返回 ? Call(target, thisArgument, argumentsList)。
  7. argArrayCreateArrayFromList(argumentsList)。
  8. 返回 ? Call(trap, handler, « target, thisArgument, argArray »)。
Note

仅当 [[ProxyTarget]] 初始值是一个具有 [[Call]] 内部方法的对象时,Proxy 特异对象才具有 [[Call]]

10.5.13 [[Construct]] ( argumentsList, newTarget )

The [[Construct]] internal method of Proxy 特异对象 O takes arguments argumentsList (a List of ECMAScript language values) and newTarget (a constructor) and returns 返回一个包含 Object 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. 断言:IsConstructor(target) 为 true
  4. handlerO.[[ProxyHandler]]
  5. 断言:handler 是一个 Object。
  6. trap 为 ? GetMethod(handler, "construct")。
  7. trapundefined,则
    1. 返回 ? Construct(target, argumentsList, newTarget)。
  8. argArrayCreateArrayFromList(argumentsList)。
  9. newObj 为 ? Call(trap, handler, « target, argArray, newTarget »)。
  10. newObj 不是 Object,抛出 TypeError 异常。
  11. 返回 newObj
Note 1

仅当 [[ProxyTarget]] 初始值是一个具有 [[Construct]] 内部方法的对象时,Proxy 特异对象才具有 [[Construct]]

Note 2

Proxy 的 [[Construct]] 强制以下不变式:

  • 结果必须是一个 Object。

10.5.14 ValidateNonRevokedProxy ( proxy )

The abstract operation ValidateNonRevokedProxy takes argument proxy (a Proxy exotic object) and returns 返回一个包含 unused正常完成或一个抛出完成. 若 proxy 已被撤销则抛出 TypeError 异常。 It performs the following steps when called:

  1. proxy.[[ProxyTarget]]null,抛出 TypeError 异常。
  2. 断言:proxy.[[ProxyHandler]] 不为 null
  3. 返回 unused

10.5.15 ProxyCreate ( target, handler )

The abstract operation ProxyCreate takes arguments target (an ECMAScript language value) and handler (an ECMAScript language value) and returns 返回一个包含 Proxy 特异对象正常完成或一个抛出完成. 用于指定创建新的 Proxy 对象。 It performs the following steps when called:

  1. target 不是 Object,抛出 TypeError 异常。
  2. handler 不是 Object,抛出 TypeError 异常。
  3. PMakeBasicObject[[ProxyHandler]], [[ProxyTarget]] »)。
  4. 设置 P 的关键内部方法(除 [[Call]][[Construct]])为 10.5 中的定义。
  5. IsCallable(target) 为 true,则
    1. 10.5.12 设置 P.[[Call]]
    2. IsConstructor(target) 为 true,则
      1. 10.5.13 设置 P.[[Construct]]
  6. P.[[ProxyTarget]] 设为 target
  7. P.[[ProxyHandler]] 设为 handler
  8. 返回 P

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 代码而言不可观察。

12 ECMAScript 语言:词法语法 (ECMAScript Language: Lexical Grammar)

ECMAScript ScriptModule 的源码文本首先被转换为输入元素序列,这些输入元素包括记号 (token)、行终止符、注释或空白。源码从左到右扫描,反复取能形成下一个输入元素的最长可能码点序列。

在若干情形下,词法输入元素的识别会对消费这些输入元素的句法语法上下文敏感,因此词法语法需要多个目标符号InputElementHashbangOrRegExp 目标用于 ScriptModule 的开始处。InputElementRegExpOrTemplateTail 目标用于允许出现 RegularExpressionLiteralTemplateMiddleTemplateTail 的句法语境。InputElementRegExp 目标符号用于所有允许 RegularExpressionLiteral 但不允许 TemplateMiddleTemplateTail 的句法语境。InputElementTemplateTail 目标用于所有允许 TemplateMiddleTemplateTail 但不允许 RegularExpressionLiteral 的句法语境。所有其它语境中,使用 InputElementDiv 作为词法目标符号

Note

使用多个词法目标可确保不存在会影响自动分号插入的词法二义性。例如,没有任何句法语境同时允许以除法或除法赋值开头以及以 RegularExpressionLiteral 开头。这一点不受分号插入影响(见 12.10);在如下示例中:

a = b
/hi/g.exec(c).map(d);

当一个 LineTerminator 之后第一个非空白、非注释码点为 U+002F (SOLIDUS),且句法上下文允许除法或除法赋值时,不会在该 LineTerminator 处插入分号。也就是说,上例被解释为与下列代码相同:

a = b / hi / g.exec(c).map(d);

Syntax

InputElementDiv :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator RightBracePunctuator InputElementRegExp :: WhiteSpace LineTerminator Comment CommonToken RightBracePunctuator RegularExpressionLiteral InputElementRegExpOrTemplateTail :: WhiteSpace LineTerminator Comment CommonToken RegularExpressionLiteral TemplateSubstitutionTail InputElementTemplateTail :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator TemplateSubstitutionTail InputElementHashbangOrRegExp :: WhiteSpace LineTerminator Comment CommonToken HashbangComment RegularExpressionLiteral

12.1 Unicode 格式控制字符 (Unicode Format-Control Characters)

Unicode 格式控制字符(即 Unicode 字符数据库中类别 “Cf” 的字符,例如 LEFT-TO-RIGHT MARK 或 RIGHT-TO-LEFT MARK)是用于在缺乏更高层协议(如标记语言)时控制一段文本排版的控制码。

允许在源码文本中使用格式控制字符有助于编辑与显示。所有格式控制字符可出现在注释中,以及字符串字面量、模板字面量和正则表达式字面量中。

U+FEFF (ZERO WIDTH NO-BREAK SPACE) 是一种主要用于文本开头以标记其为 Unicode 并允许检测编码与字节序的格式控制字符。用于该目的的 <ZWNBSP> 字符有时也可能在文本开头之后出现,例如连接文件的结果。在 ECMAScript 源码文本中,除注释、字符串字面量、模板字面量和正则表达式字面量外,<ZWNBSP> 码点被视为空白字符(见 12.2)。

12.2 空白 (White Space)

空白码点用于提升源码可读性并分隔记号(不可再分的词法单元),除此之外没有意义。空白码点可出现在任意两个记号之间以及输入开头或结尾。空白码点可出现在 StringLiteralRegularExpressionLiteralTemplateTemplateSubstitutionTail 内部,此时它们是字面量值组成部分的有效码点;也可出现在 Comment 内,但不能出现在其它类型的记号内部。

ECMAScript 的空白码点列于 Table 33

Table 33: 空白码点 (White Space Code Points)
Code Points 名称 (Name) 缩写 (Abbreviation)
U+0009 CHARACTER TABULATION <TAB>
U+000B LINE TABULATION <VT>
U+000C FORM FEED (FF) <FF>
U+FEFF ZERO WIDTH NO-BREAK SPACE <ZWNBSP>
any code point in general category “Space_Separator” <USP>
Note 1

U+0020 (SPACE) 与 U+00A0 (NO-BREAK SPACE) 码点属于 <USP>。

Note 2

Table 33 所列码点外,ECMAScript WhiteSpace 有意排除所有具有 Unicode “White_Space” 属性但不属于一般类别 “Space_Separator”(“Zs”) 的码点。

Syntax

WhiteSpace :: <TAB> <VT> <FF> <ZWNBSP> <USP>

12.3 行终止符 (Line Terminators)

与空白码点类似,行终止符码点用于提升源码可读性并分隔记号。但与空白码点不同,行终止符会对句法语法行为产生影响。一般而言,行终止符可出现在任意两个记号之间,但也有少数位置为句法语法所禁止。行终止符还影响自动分号插入过程(见 12.10)。行终止符不能出现在除 StringLiteralTemplateTemplateSubstitutionTail 之外的任何记号内部。<LF> 与 <CR> 行终止符除作为 LineContinuation 的一部分外,不能出现在 StringLiteral 记号内。

MultiLineComment 内可以出现行终止符,但 SingleLineComment 内不能。

行终止符包含在正则表达式 \s 类所匹配的空白码点集合中。

ECMAScript 行终止符码点列于 Table 34

Table 34: 行终止符码点 (Line Terminator Code Points)
Code Point Unicode 名称 (Unicode Name) 缩写 (Abbreviation)
U+000A LINE FEED (LF) <LF>
U+000D CARRIAGE RETURN (CR) <CR>
U+2028 LINE SEPARATOR <LS>
U+2029 PARAGRAPH SEPARATOR <PS>

只有 Table 34 中的 Unicode 码点被视为行终止符。其它换行或断行的 Unicode 码点不会被视为行终止符,但若满足 Table 33 所列要求,则被视为空白。序列 <CR><LF> 常用作行终止符;在报告行号时应将其视为单个 SourceCharacter

Syntax

LineTerminator :: <LF> <CR> <LS> <PS> LineTerminatorSequence :: <LF> <CR> [lookahead ≠ <LF>] <LS> <PS> <CR> <LF>

12.4 注释 (Comments)

注释可以是单行或多行。多行注释不能嵌套。

由于单行注释可包含除 LineTerminator 码点外的任意 Unicode 码点,并且根据“一段记号总是尽可能长”的通则,单行注释总是从 // 标记到该行末端的全部码点。然而,行末的 LineTerminator 不视为单行注释的一部分;它被词法语法单独识别并进入供句法语法使用的输入元素流。这一点很重要,因为这意味着单行注释的有无不影响自动分号插入(见 12.10)。

注释的行为类似空白并被丢弃;但若 MultiLineComment 含有行终止符码点,则整个注释在句法解析目的上被视为一个 LineTerminator

Syntax

Comment :: MultiLineComment SingleLineComment MultiLineComment :: /* MultiLineCommentCharsopt */ MultiLineCommentChars :: MultiLineNotAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt PostAsteriskCommentChars :: MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt MultiLineNotAsteriskChar :: SourceCharacter but not * MultiLineNotForwardSlashOrAsteriskChar :: SourceCharacter but not one of / or * SingleLineComment :: // SingleLineCommentCharsopt SingleLineCommentChars :: SingleLineCommentChar SingleLineCommentCharsopt SingleLineCommentChar :: SourceCharacter but not LineTerminator

本节若干产生式在 B.1.1 中给出替代定义。

12.5 Hashbang 注释 (Hashbang Comments)

Hashbang 注释对位置敏感,并且与其它类型注释一样从句法语法的输入元素流中被丢弃。

Syntax

HashbangComment :: #! SingleLineCommentCharsopt

12.6 记号 (Tokens)

Syntax

CommonToken :: IdentifierName PrivateIdentifier Punctuator NumericLiteral StringLiteral Template Note

DivPunctuatorRegularExpressionLiteralRightBracePunctuatorTemplateSubstitutionTail 产生式派生的额外记号未包含在 CommonToken 中。

12.7 名称与关键字 (Names and Keywords)

IdentifierNameReservedWord 是按 Unicode 标准附件 #31《标识符与模式语法》中“默认标识符语法”解释的记号,并带有少量修改。ReservedWordIdentifierName枚举子集。句法语法将 Identifier 定义为不是 ReservedWordIdentifierName。Unicode 标识符语法基于 Unicode 标准规定的字符属性。符合规范的 ECMAScript 实现必须将 Unicode 标准最新版本中指定类别的码点视为属于这些类别。实现可以识别 Unicode 后续版本定义的标识符码点。

Note 1

本标准特别增加:U+0024 (DOLLAR SIGN) 与 U+005F (LOW LINE) 可在 IdentifierName 任意位置使用。

Syntax

PrivateIdentifier :: # IdentifierName IdentifierName :: IdentifierStart IdentifierName IdentifierPart IdentifierStart :: IdentifierStartChar \ UnicodeEscapeSequence IdentifierPart :: IdentifierPartChar \ UnicodeEscapeSequence IdentifierStartChar :: UnicodeIDStart $ _ IdentifierPartChar :: UnicodeIDContinue $ AsciiLetter :: one of a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z UnicodeIDStart :: any Unicode code point with the Unicode property “ID_Start” UnicodeIDContinue :: any Unicode code point with the Unicode property “ID_Continue”

非终结符 UnicodeEscapeSequence 的定义见 12.9.4

Note 2

非终结符 IdentifierPart 通过 UnicodeIDContinue 派生 _

Note 3

具有 Unicode 属性 “ID_Start” 与 “ID_Continue” 的码点集合分别包含具有 “Other_ID_Start” 与 “Other_ID_Continue” 属性的码点。

12.7.1 标识符名称 (Identifier Names)

IdentifierName 中允许使用 Unicode 转义序列,它们贡献单个等于该 UnicodeEscapeSequence 的 IdentifierCodePoint 的 Unicode 码点。前导的 \ 不贡献码点。UnicodeEscapeSequence 不能用于为本来无效的 IdentifierName 提供码点。换言之,如果将 \ UnicodeEscapeSequence 序列替换为其贡献的 SourceCharacter,结果仍须是一个有效的 IdentifierName,并且与原始 IdentifierName 拥有完全相同的 SourceCharacter 序列。本规范中对 IdentifierName 的所有解释都基于其实际码点,无论是否通过转义序列写出。

两个根据 Unicode 标准规范等价的 IdentifierName,除非在替换每个 UnicodeEscapeSequence 后由完全相同的码点序列表示,否则相等。

12.7.1.1 静态语义:早期错误 (Static Semantics: Early Errors)

IdentifierStart :: \ UnicodeEscapeSequence IdentifierPart :: \ UnicodeEscapeSequence

12.7.1.2 静态语义:IdentifierCodePoints

The syntax-directed operation 静态语义:IdentifierCodePoints takes no arguments and returns 码点列表 (a List of code points). It is defined piecewise over the following productions:

IdentifierName :: IdentifierStart
  1. cpIdentifierStart 的 IdentifierCodePoint。
  2. 返回 « cp »。
IdentifierName :: IdentifierName IdentifierPart
  1. cps 为所派生 IdentifierName 的 IdentifierCodePoints。
  2. cpIdentifierPart 的 IdentifierCodePoint。
  3. 返回 cps 与 « cp » 的列表连接。

12.7.1.3 静态语义:IdentifierCodePoint

The syntax-directed operation 静态语义:IdentifierCodePoint takes no arguments and returns 一个码点 (a code point). It is defined piecewise over the following productions:

IdentifierStart :: IdentifierStartChar
  1. 返回 IdentifierStartChar 匹配的码点。
IdentifierPart :: IdentifierPartChar
  1. 返回 IdentifierPartChar 匹配的码点。
UnicodeEscapeSequence :: u Hex4Digits
  1. 返回数值为 Hex4Digits 的 MV 的码点。
UnicodeEscapeSequence :: u{ CodePoint }
  1. 返回数值为 CodePoint 的 MV 的码点。

12.7.2 关键字与保留字 (Keywords and Reserved Words)

关键字 (keyword) 是匹配 IdentifierName 且具有句法用途的记号;即出现在某个句法产生式中以打字机字体(固定宽度)字面形式的词。ECMAScript 的关键字包括 ifwhileasyncawait 等。

保留字 (reserved word) 是不能用作标识符的 IdentifierName。许多关键字是保留字,但有些不是;还有一些只在特定上下文中被保留。ifwhile 是保留字。await 仅在 async 函数与模块内部被保留。async 不是保留字;它可自由用作变量名或语句标签。

本规范结合语法产生式与早期错误规则来指明哪些名称是有效标识符,哪些是保留字。下列 ReservedWord 列表中除 awaityield 外的所有记号无条件被保留。awaityield 的例外通过带参数的句法产生式在 13.1 中指定。最后,多条早期错误规则限制有效标识符集合,见 13.1.114.3.1.114.7.5.115.7.1。概括而言,标识符名称有五类:

  • 始终允许且不是关键字的,如 MathwindowtoString_

  • 永不允许的,即下表 ReservedWord(除 awaityield);

  • 上下文允许的,即 awaityield

  • 在严格模式中上下文不允许的:letstaticimplementsinterfacepackageprivateprotectedpublic

  • 始终允许但在某些句法产生式(Identifier 不允许处)又作为关键字出现的:asasyncfromgetmetaofsettarget

条件关键字 (conditional keyword)上下文关键字 (contextual keyword) 常用于指代后三类,它们在某些上下文可作标识符,在另一些上下文作关键字。

Syntax

ReservedWord :: one of await break case catch class const continue debugger default delete do else enum export extends false finally for function if import in instanceof new null return super switch this throw true try typeof var void while with yield Note 1

依据 5.1.5,语法中的关键字匹配特定 SourceCharacter 序列的字面串。关键字中的码点不能通过 \ UnicodeEscapeSequence 表达。

IdentifierName 可包含 \ UnicodeEscapeSequence,但不能通过拼写 els\u{65} 来声明名为 “else” 的变量。13.1.1早期错误规则会排除 StringValue 与保留字相同的标识符。

Note 2

enum 当前尚未作为关键字使用。它是一个未来保留字,为未来语言扩展保留。

同样地,implementsinterfacepackageprivateprotectedpublic 在严格模式中是未来保留字。

Note 3

argumentseval 不是关键字,但在严格模式中有一些限制。参见 13.1.18.6.415.2.115.5.115.6.115.8.1

12.8 标点符号 (Punctuators)

Syntax

Punctuator :: OptionalChainingPunctuator OtherPunctuator OptionalChainingPunctuator :: ?. [lookahead ∉ DecimalDigit] OtherPunctuator :: one of { ( ) [ ] . ... ; , < > <= >= == != === !== + - * % ** ++ -- << >> >>> & | ^ ! ~ && || ?? ? : = += -= *= %= **= <<= >>= >>>= &= |= ^= &&= ||= ??= => DivPunctuator :: / /= RightBracePunctuator :: }

12.9 字面量 (Literals)

12.9.1 Null 字面量 (Null Literals)

Syntax

NullLiteral :: null

12.9.2 布尔字面量 (Boolean Literals)

Syntax

BooleanLiteral :: true false

12.9.3 数值字面量 (Numeric Literals)

Syntax

NumericLiteralSeparator :: _ NumericLiteral :: DecimalLiteral DecimalBigIntegerLiteral NonDecimalIntegerLiteral[+Sep] NonDecimalIntegerLiteral[+Sep] BigIntLiteralSuffix LegacyOctalIntegerLiteral DecimalBigIntegerLiteral :: 0 BigIntLiteralSuffix NonZeroDigit DecimalDigits[+Sep]opt BigIntLiteralSuffix NonZeroDigit NumericLiteralSeparator DecimalDigits[+Sep] BigIntLiteralSuffix NonDecimalIntegerLiteral[Sep] :: BinaryIntegerLiteral[?Sep] OctalIntegerLiteral[?Sep] HexIntegerLiteral[?Sep] BigIntLiteralSuffix :: n DecimalLiteral :: DecimalIntegerLiteral . DecimalDigits[+Sep]opt ExponentPart[+Sep]opt . DecimalDigits[+Sep] ExponentPart[+Sep]opt DecimalIntegerLiteral ExponentPart[+Sep]opt DecimalIntegerLiteral :: 0 NonZeroDigit NonZeroDigit NumericLiteralSeparatoropt DecimalDigits[+Sep] NonOctalDecimalIntegerLiteral DecimalDigits[Sep] :: DecimalDigit DecimalDigits[?Sep] DecimalDigit [+Sep] DecimalDigits[+Sep] NumericLiteralSeparator DecimalDigit DecimalDigit :: one of 0 1 2 3 4 5 6 7 8 9 NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9 ExponentPart[Sep] :: ExponentIndicator SignedInteger[?Sep] ExponentIndicator :: one of e E SignedInteger[Sep] :: DecimalDigits[?Sep] + DecimalDigits[?Sep] - DecimalDigits[?Sep] BinaryIntegerLiteral[Sep] :: 0b BinaryDigits[?Sep] 0B BinaryDigits[?Sep] BinaryDigits[Sep] :: BinaryDigit BinaryDigits[?Sep] BinaryDigit [+Sep] BinaryDigits[+Sep] NumericLiteralSeparator BinaryDigit BinaryDigit :: one of 0 1 OctalIntegerLiteral[Sep] :: 0o OctalDigits[?Sep] 0O OctalDigits[?Sep] OctalDigits[Sep] :: OctalDigit OctalDigits[?Sep] OctalDigit [+Sep] OctalDigits[+Sep] NumericLiteralSeparator OctalDigit LegacyOctalIntegerLiteral :: 0 OctalDigit LegacyOctalIntegerLiteral OctalDigit NonOctalDecimalIntegerLiteral :: 0 NonOctalDigit LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit NonOctalDecimalIntegerLiteral DecimalDigit LegacyOctalLikeDecimalIntegerLiteral :: 0 OctalDigit LegacyOctalLikeDecimalIntegerLiteral OctalDigit OctalDigit :: one of 0 1 2 3 4 5 6 7 NonOctalDigit :: one of 8 9 HexIntegerLiteral[Sep] :: 0x HexDigits[?Sep] 0X HexDigits[?Sep] HexDigits[Sep] :: HexDigit HexDigits[?Sep] HexDigit [+Sep] HexDigits[+Sep] NumericLiteralSeparator HexDigit HexDigit :: one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

NumericLiteral 之后紧接的下一个 SourceCharacter 不能是 IdentifierStartDecimalDigit

Note

例如:3in 是错误,而不是两个输入元素 3in

12.9.3.1 静态语义:早期错误 (Static Semantics: Early Errors)

NumericLiteral :: LegacyOctalIntegerLiteral DecimalIntegerLiteral :: NonOctalDecimalIntegerLiteral
  • 若 IsStrict(this production) 为 true 则为语法错误。
Note
在非严格代码中,该语法为 Legacy。

12.9.3.2 静态语义:MV (Static Semantics: MV)

数值字面量表示 Number 类型BigInt 类型的值。

12.9.3.3 静态语义:NumericValue

The syntax-directed operation 静态语义:NumericValue takes no arguments and returns Number 或 BigInt. It is defined piecewise over the following productions:

NumericLiteral :: DecimalLiteral
  1. 返回 RoundMVResult(DecimalLiteral 的 MV)。
NumericLiteral :: NonDecimalIntegerLiteral
  1. 返回 𝔽(NonDecimalIntegerLiteral 的 MV)。
NumericLiteral :: LegacyOctalIntegerLiteral
  1. 返回 𝔽(LegacyOctalIntegerLiteral 的 MV)。
NumericLiteral :: NonDecimalIntegerLiteral BigIntLiteralSuffix
  1. 返回 NonDecimalIntegerLiteral 的 MV 对应的 BigInt 值
DecimalBigIntegerLiteral :: 0 BigIntLiteralSuffix
  1. 返回 0
DecimalBigIntegerLiteral :: NonZeroDigit BigIntLiteralSuffix
  1. 返回 NonZeroDigit 的 MV 对应的 BigInt 值
DecimalBigIntegerLiteral :: NonZeroDigit DecimalDigits BigIntLiteralSuffix NonZeroDigit NumericLiteralSeparator DecimalDigits BigIntLiteralSuffix
  1. nDecimalDigits 中(排除所有 NumericLiteralSeparator)码点数。
  2. mv 为 (NonZeroDigit 的 MV × 10n) + DecimalDigits 的 MV。
  3. 返回 (mv)。

12.9.4 字符串字面量 (String Literals)

Note 1

字符串字面量是 0 个或更多 Unicode 码点,被单引号或双引号包围。Unicode 码点也可用转义序列表达。除闭合引号码点、U+005C (REVERSE SOLIDUS)、U+000D (CARRIAGE RETURN)、U+000A (LINE FEED) 外,所有码点都可直接出现在字符串字面量中。任何码点都可以转义形式出现。字符串字面量求值为 ECMAScript String 值。生成这些 String 值时 Unicode 码点按 11.1.1 中定义进行 UTF-16 编码。基本多文种平面 (BMP) 内的码点编码为单个代码单元,其它码点编码为两个代码单元。

Syntax

StringLiteral :: " DoubleStringCharactersopt " ' SingleStringCharactersopt ' DoubleStringCharacters :: DoubleStringCharacter DoubleStringCharactersopt SingleStringCharacters :: SingleStringCharacter SingleStringCharactersopt DoubleStringCharacter :: SourceCharacter but not one of " or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation SingleStringCharacter :: SourceCharacter but not one of ' or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation LineContinuation :: \ LineTerminatorSequence EscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] LegacyOctalEscapeSequence NonOctalDecimalEscapeSequence HexEscapeSequence UnicodeEscapeSequence CharacterEscapeSequence :: SingleEscapeCharacter NonEscapeCharacter SingleEscapeCharacter :: one of ' " \ b f n r t v NonEscapeCharacter :: SourceCharacter but not one of EscapeCharacter or LineTerminator EscapeCharacter :: SingleEscapeCharacter DecimalDigit x u LegacyOctalEscapeSequence :: 0 [lookahead ∈ { 8, 9 }] NonZeroOctalDigit [lookahead ∉ OctalDigit] ZeroToThree OctalDigit [lookahead ∉ OctalDigit] FourToSeven OctalDigit ZeroToThree OctalDigit OctalDigit NonZeroOctalDigit :: OctalDigit but not 0 ZeroToThree :: one of 0 1 2 3 FourToSeven :: one of 4 5 6 7 NonOctalDecimalEscapeSequence :: one of 8 9 HexEscapeSequence :: x HexDigit HexDigit UnicodeEscapeSequence :: u Hex4Digits u{ CodePoint } Hex4Digits :: HexDigit HexDigit HexDigit HexDigit

非终结符 HexDigit 定义见 12.9.3SourceCharacter 定义见 11.1

Note 2

<LF> 与 <CR> 不能出现在字符串字面量中,除非作为 LineContinuation 的一部分以生成空码点序列。要在字符串字面量值中包含它们,应使用 \n\u000A 等转义序列。

12.9.4.1 静态语义:早期错误 (Static Semantics: Early Errors)

EscapeSequence :: LegacyOctalEscapeSequence NonOctalDecimalEscapeSequence
  • 若 IsStrict(this production) 为 true 则为语法错误。
Note 1
在非严格代码中,该语法为 Legacy。
Note 2

字符串字面量可能位于使封闭代码进入 严格模式 的 Use Strict 指令之前,实现必须谨慎对这些字面量执行上述规则。例如,下列源码包含语法错误:

function invalid() { "\7"; "use strict"; }

12.9.4.2 静态语义:SV

The syntax-directed operation 静态语义:SV takes no arguments and returns 一个 String.

字符串字面量表示 String 类型值。SV 通过对字面量各部分的递归应用生成 String 值。在此过程中,字符串字面量中的某些 Unicode 码点按下文或 12.9.3 描述被视为具有数学值

Table 35: 字符串单字符转义序列 (String Single Character Escape Sequences)
转义序列 (Escape Sequence) 代码单元值 (Code Unit Value) Unicode 字符名 (Unicode Character Name) 符号 (Symbol)
\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 \

12.9.4.3 静态语义:MV

12.9.5 正则表达式字面量 (Regular Expression Literals)

Note 1

正则表达式字面量是一个输入元素,每次求值它都会转换为一个 RegExp 对象(见 22.2)。程序中两个正则字面量即便内容相同,求值得到的两个正则对象也永远不会 ===。RegExp 对象也可在运行时通过 new RegExp 或以函数形式调用构造器创建(见 22.2.4)。

下列产生式描述正则表达式字面量的语法,供输入元素扫描器定位字面量结束。由 RegularExpressionBodyRegularExpressionFlags 组成的源码随后再用更严格的 ECMAScript 正则语法(22.2.1)解析。

实现可扩展 22.2.1 定义的 ECMAScript 正则语法,但不得扩展以下定义的 RegularExpressionBodyRegularExpressionFlags 及其依赖的产生式。

Syntax

RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags RegularExpressionBody :: RegularExpressionFirstChar RegularExpressionChars RegularExpressionChars :: [empty] RegularExpressionChars RegularExpressionChar RegularExpressionFirstChar :: RegularExpressionNonTerminator but not one of * or \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionChar :: RegularExpressionNonTerminator but not one of \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionBackslashSequence :: \ RegularExpressionNonTerminator RegularExpressionNonTerminator :: SourceCharacter but not LineTerminator RegularExpressionClass :: [ RegularExpressionClassChars ] RegularExpressionClassChars :: [empty] RegularExpressionClassChars RegularExpressionClassChar RegularExpressionClassChar :: RegularExpressionNonTerminator but not one of ] or \ RegularExpressionBackslashSequence RegularExpressionFlags :: [empty] RegularExpressionFlags IdentifierPartChar Note 2

正则字面量不能为空;序列 // 表示单行注释而不是空正则。若需空正则,使用 /(?:)/

12.9.5.1 静态语义:BodyText

The syntax-directed operation 静态语义:BodyText takes no arguments and returns source text. It is defined piecewise over the following productions:

RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags
  1. 返回识别为 RegularExpressionBody 的源码文本。

12.9.5.2 静态语义:FlagText

The syntax-directed operation 静态语义:FlagText takes no arguments and returns source text. It is defined piecewise over the following productions:

RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags
  1. 返回识别为 RegularExpressionFlags 的源码文本。

12.9.6 模板字面量词法组件 (Template Literal Lexical Components)

Syntax

Template :: NoSubstitutionTemplate TemplateHead NoSubstitutionTemplate :: ` TemplateCharactersopt ` TemplateHead :: ` TemplateCharactersopt ${ TemplateSubstitutionTail :: TemplateMiddle TemplateTail TemplateMiddle :: } TemplateCharactersopt ${ TemplateTail :: } TemplateCharactersopt ` TemplateCharacters :: TemplateCharacter TemplateCharactersopt TemplateCharacter :: $ [lookahead ≠ {] \ TemplateEscapeSequence \ NotEscapeSequence LineContinuation LineTerminatorSequence SourceCharacter but not one of ` or \ or $ or LineTerminator TemplateEscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] HexEscapeSequence UnicodeEscapeSequence NotEscapeSequence :: 0 DecimalDigit DecimalDigit but not 0 x [lookahead ∉ HexDigit] x HexDigit [lookahead ∉ HexDigit] u [lookahead ∉ HexDigit] [lookahead ≠ {] u HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit HexDigit [lookahead ∉ HexDigit] u { [lookahead ∉ HexDigit] u { NotCodePoint [lookahead ∉ HexDigit] u { CodePoint [lookahead ∉ HexDigit] [lookahead ≠ }] NotCodePoint :: HexDigits[~Sep] but only if the MV of HexDigits > 0x10FFFF CodePoint :: HexDigits[~Sep] but only if the MV of HexDigits ≤ 0x10FFFF Note

TemplateSubstitutionTailInputElementTemplateTail 可选词法目标使用。

12.9.6.1 静态语义:TV

The syntax-directed operation 静态语义:TV takes no arguments and returns String 或 undefined. 模板字面量组件由 TV 解释为 String 类型值。TV 用来构造模板对象的索引组件(俗称 template values)。在 TV 中,转义序列被替换为其表示码点的 UTF-16 代码单元。

12.9.6.2 静态语义:TRV

The syntax-directed operation 静态语义:TRV takes no arguments and returns String. 模板字面量组件由 TRV 解释为 String 类型值。TRV 用来构造模板对象的原始组件(raw values)。TRV 与 TV 类似,区别在于 TRV 中转义序列按字面出现形式解释。

Note

TV 不包含 LineContinuation 的代码单元,而 TRV 包含。<CR><LF> 与 <CR> LineTerminatorSequence 在 TV 与 TRV 中均规范化为 <LF>。要包含 <CR> 或 <CR><LF>,需要显式 TemplateEscapeSequence

12.10 自动分号插入 (Automatic Semicolon Insertion)

大多数 ECMAScript 语句与声明必须以分号结束。此类分号可在源码中显式出现。为方便起见,在某些情形下可以省略;在这些情形中,认为分号被自动插入到源码记号流中。

12.10.1 自动分号插入的规则 (Rules of Automatic Semicolon Insertion)

下列规则中,“token” 指根据 12 所述当前词法目标符号识别出的实际词法记号。

分号插入有三条基本规则:

  1. 当从左到右解析源码时遇到一个不被任何语法产生式允许的记号(称为 违规记号 (offending token))时,如果满足以下任一条件,则在其前自动插入分号:

    • 违规记号与前一个记号之间至少有一个 LineTerminator
    • 违规记号是 }
    • 前一个记号是 ),且插入的分号会被解析为 do-while 语句(14.7.2)的结束分号。
  2. 当从左到右解析时,如果到达输入记号流末尾且解析器无法将其解析为目标非终结符的单一实例,则在末尾自动插入分号。
  3. 当从左到右解析时遇到的记号在某个产生式中被允许,但该产生式是受限产生式 (restricted production) 且该记号将成为紧随 “[no LineTerminator here]” 注解之后的终结符或非终结符的首记号(故称为受限记号),且受限记号与前一记号之间至少有一个 LineTerminator,则在该受限记号前自动插入分号。

然而,上述规则受一个额外覆盖条件:若自动插入的分号会被解析为空语句,或将成为 for 语句(见 14.7.4)头部的两个分号之一,则不会自动插入。

Note

以下是语法中唯一的受限产生式:

UpdateExpression[Yield, Await] : LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] ++ LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] -- ContinueStatement[Yield, Await] : continue ; continue [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ; BreakStatement[Yield, Await] : break ; break [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ; ReturnStatement[Yield, Await] : return ; return [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; ThrowStatement[Yield, Await] : throw [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; YieldExpression[In, Await] : yield yield [no LineTerminator here] AssignmentExpression[?In, +Yield, ?Await] yield [no LineTerminator here] * AssignmentExpression[?In, +Yield, ?Await] ArrowFunction[In, Yield, Await] : ArrowParameters[?Yield, ?Await] [no LineTerminator here] => ConciseBody[?In] AsyncFunctionDeclaration[Yield, Await, Default] : async [no LineTerminator here] function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } [+Default] async [no LineTerminator here] function ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionExpression : async [no LineTerminator here] function BindingIdentifier[~Yield, +Await]opt ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncMethod[Yield, Await] : async [no LineTerminator here] ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncGeneratorDeclaration[Yield, Await, Default] : async [no LineTerminator here] function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } [+Default] async [no LineTerminator here] function * ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorExpression : async [no LineTerminator here] function * BindingIdentifier[+Yield, +Await]opt ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorMethod[Yield, Await] : async [no LineTerminator here] * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncArrowFunction[In, Yield, Await] : async [no LineTerminator here] AsyncArrowBindingIdentifier[?Yield] [no LineTerminator here] => AsyncConciseBody[?In] CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody[?In] AsyncArrowHead : async [no LineTerminator here] ArrowFormalParameters[~Yield, +Await]

这些受限产生式的实际效果:

  • 当遇到可被解析为后缀 ++-- 运算符的记号,且其与前一记号之间至少有一个 LineTerminator,则在该运算符前自动插入分号。
  • 当遇到 continuebreakreturnthrowyield,且其后一个记号前存在 LineTerminator,则在该关键字后自动插入分号。
  • 当箭头函数参数后紧跟的 => 前出现 LineTerminator 时,自动插入分号并导致该 => 处语法错误。
  • async 后在期望的 functionIdentifierName( 之前出现 LineTerminator,自动插入分号且后续不再与该 async 归为同一表达式或类元素。
  • async 后在期望的 * 之前出现 LineTerminator,自动插入分号并导致该标点语法错误。

对程序员的实践建议:

  • 后缀 ++ / -- 应与其操作数位于同一行。
  • returnthrow 语句中的 Expressionyield 表达式中的 AssignmentExpression 应与关键字位于同一行。
  • breakcontinue 语句中的 LabelIdentifier 应与各自关键字在同一行。
  • 箭头函数参数部分结尾与 => 应位于同一行。
  • 异步函数或方法前的 async 应与紧随其后的记号在同一行。

12.10.2 自动分号插入示例 (Examples of Automatic Semicolon Insertion)

本节为非规范性内容。

源码

{ 1 2 } 3

即便考虑自动分号插入规则,也不是有效 ECMAScript 语句。相比之下,源码

{ 1
2 } 3

也不是有效语句,但会被自动分号插入转换为:

{ 1
;2 ;} 3;

其为有效语句。

源码

for (a; b
)

不是有效语句,且不会被修改,因为分号对 for 头部必要;自动分号插入不会插入 for 头部的两个分号之一。

源码

return
a + b

被转换为:

return;
a + b;
Note 1

a + b 不作为 return 语句返回值,因为 LineTerminator 将其与 return 分隔。

源码

a = b
++c

转换为:

a = b;
++c;
Note 2

++ 不作为应用于 b 的后缀运算符,因为 b++ 之间存在 LineTerminator

源码

if (a > b)
else c = d

不是有效语句,且在 else 前不会自动插入分号,即便此处没有适用的语法产生式,因为插入分号会形成空语句。

源码

a = b + c
(d + e).print()

不会 被转换,因为第二行以括号表达式开始可被解释为函数调用的实参列表:

a = b + c(d + e).print()

若赋值语句必须以左括号开始,建议在前一语句末尾显式写分号,而不是依赖自动分号插入。

12.10.3 自动分号插入的有趣情形 (Interesting Cases of Automatic Semicolon Insertion)

本节为非规范性内容。

ECMAScript 程序可以通过依赖自动分号插入以极少分号的风格编写。如前述,分号不会在每个换行处插入,并且插入可能依赖跨行的多个记号。

随着新语法特性的加入,可能增加新的产生式,使之前依赖自动分号插入的行在解析时改变其产生式。

本节中,若某处是否插入分号取决于其前源码,则视为“有趣”情形。剩余内容描述本版本 ECMAScript 中若干此类情形。

12.10.3.1 语句列表中的自动分号插入有趣情形 (Interesting Cases ... in Statement Lists)

StatementList 中,许多 StatementListItem 以可省略的分号结尾。根据上述规则,在一行表达式结尾处,若下一行以以下任一开头则需要分号:

  • 左括号 (()。缺少分号会将两行合并为 CallExpression
  • 左方括号 ([)。缺少分号会解析为属性访问而非 ArrayLiteralArrayAssignmentPattern
  • 模板字面量 (`)。缺少分号会合并为带前一个表达式为 MemberExpression 的标签模板(13.3.11)。
  • 一元 +-。缺少分号会被解释为相应二元运算的一部分。
  • 正则表达式字面量。缺少分号时,若正则含标志,可能被解析为 / MultiplicativeOperator

12.10.3.2 与 “[no LineTerminator here]” 相关的自动分号插入情形 (Cases ... “[no LineTerminator here]”)

本节为非规范性内容。

ECMAScript 包含含 “[no LineTerminator here]” 的语法产生式。这些产生式有时用于在语法中表达可选操作数。在这些位置引入 LineTerminator 会通过采用不含可选操作数的产生式改变源码的语法结构。

本节其余内容描述本版本中使用 “[no LineTerminator here]” 的若干产生式。

12.10.3.2.1 含可选操作数与 “[no LineTerminator here]” 的产生式列表

13 ECMAScript 语言:表达式 (ECMAScript Language: Expressions)

13.1 标识符 (Identifiers)

语法 (Syntax)

IdentifierReference[Yield, Await] : Identifier [~Yield] yield [~Await] await BindingIdentifier[Yield, Await] : Identifier yield await LabelIdentifier[Yield, Await] : Identifier [~Yield] yield [~Await] await Identifier : IdentifierName but not ReservedWord Note

yieldawait 在语法中被允许作为 BindingIdentifier,稍后通过静态语义禁止,是为了阻止在如下情形发生自动分号插入:

let
await 0;

13.1.1 静态语义:早期错误 (Static Semantics: Early Errors)

BindingIdentifier : Identifier
  • 若 IsStrict(this production) 为 trueIdentifier 的 StringValue 为 "arguments""eval",则为语法错误。
IdentifierReference : yield BindingIdentifier : yield LabelIdentifier : yield
  • 若 IsStrict(this production) 为 true 则为语法错误。
IdentifierReference : await BindingIdentifier : await LabelIdentifier : await BindingIdentifier[Yield, Await] : yield
  • 若此产生式具有 [Yield] 参数则为语法错误。
BindingIdentifier[Yield, Await] : await
  • 若此产生式具有 [Await] 参数则为语法错误。
IdentifierReference[Yield, Await] : Identifier BindingIdentifier[Yield, Await] : Identifier LabelIdentifier[Yield, Await] : Identifier
  • 若此产生式具有 [Yield] 参数且 Identifier 的 StringValue 为 "yield",则为语法错误。
  • 若此产生式具有 [Await] 参数且 Identifier 的 StringValue 为 "await",则为语法错误。
Identifier : IdentifierName but not ReservedWord
  • 若 IsStrict(this phrase) 为 trueIdentifierName 的 StringValue 为 "implements""interface""let""package""private""protected""public""static""yield" 之一,则为语法错误。
  • 若句法语法目标符号ModuleIdentifierName 的 StringValue 为 "await",则为语法错误。
  • IdentifierName 的 StringValue 等于某 ReservedWord 的 StringValue 且该 ReservedWord 不是 yieldawait,则为语法错误。
Note

IdentifierName 的 StringValue 会规范化其中的任意 Unicode 转义序列,因此不能通过转义来写出与某 ReservedWord 码点序列相同的 Identifier

13.1.2 静态语义:StringValue

The syntax-directed operation 静态语义:StringValue takes no arguments and returns 一个 String. It is defined piecewise over the following productions:

IdentifierName :: IdentifierStart IdentifierName IdentifierPart
  1. idTextUnescapedIdentifierName 的 IdentifierCodePoints。
  2. 返回 CodePointsToString(idTextUnescaped)。
IdentifierReference : yield BindingIdentifier : yield LabelIdentifier : yield
  1. 返回 "yield"
IdentifierReference : await BindingIdentifier : await LabelIdentifier : await
  1. 返回 "await"
Identifier : IdentifierName but not ReservedWord
  1. 返回 IdentifierName 的 StringValue。
PrivateIdentifier :: # IdentifierName
  1. 返回 0x0023 (NUMBER SIGN) 与 IdentifierName 的 StringValue 的字符串连接。
ModuleExportName : StringLiteral
  1. 返回 StringLiteral 的 SV。

13.1.3 运行时语义:求值 (Runtime Semantics: Evaluation)

IdentifierReference : Identifier
  1. 返回 ? ResolveBinding(StringValue of Identifier)。
IdentifierReference : yield
  1. 返回 ? ResolveBinding("yield")。
IdentifierReference : await
  1. 返回 ? ResolveBinding("await")。
Note 1

对一个 IdentifierReference 求值的结果总是 Reference 类型的值。

Note 2

在非严格代码中,关键字 yield 可以作为标识符使用。对该 IdentifierReference 求值会解析 yield 的绑定,好像它是一个普通 Identifier。早期错误限制保证此求值只会出现在非严格代码。

13.2 基础表达式 (Primary Expression)

语法 (Syntax)

PrimaryExpression[Yield, Await] : this IdentifierReference[?Yield, ?Await] Literal ArrayLiteral[?Yield, ?Await] ObjectLiteral[?Yield, ?Await] FunctionExpression ClassExpression[?Yield, ?Await] GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral[?Yield, ?Await, ~Tagged] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[Yield, Await] : ( Expression[+In, ?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ) ( ) ( ... BindingIdentifier[?Yield, ?Await] ) ( ... BindingPattern[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingIdentifier[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingPattern[?Yield, ?Await] )

补充语法 (Supplemental Syntax)

当处理产生式实例:
PrimaryExpression[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
时,使用如下语法细化对 CoverParenthesizedExpressionAndArrowParameterList 的解释:

ParenthesizedExpression[Yield, Await] : ( Expression[+In, ?Yield, ?Await] )

13.2.1 this 关键字 (The this Keyword)

13.2.1.1 运行时语义:求值 (Runtime Semantics: Evaluation)

PrimaryExpression : this
  1. 返回 ? ResolveThisBinding()。

13.2.2 标识符引用 (Identifier Reference)

关于 IdentifierReference13.1

13.2.3 字面量 (Literals)

语法 (Syntax)

Literal : NullLiteral BooleanLiteral NumericLiteral StringLiteral

13.2.3.1 运行时语义:求值 (Runtime Semantics: Evaluation)

Literal : NullLiteral
  1. 返回 null
Literal : BooleanLiteral
  1. BooleanLiteral 为记号 false,返回 false
  2. BooleanLiteral 为记号 true,返回 true
Literal : NumericLiteral
  1. 返回 12.9.3 中定义的 NumericLiteral 的 NumericValue。
Literal : StringLiteral
  1. 返回 12.9.4.2 中定义的 StringLiteral 的 SV。

13.2.4 数组初始化器 (Array Initializer)

Note

ArrayLiteral 是描述数组初始化的表达式:一个由零个或多个表达式(各代表一个数组元素)构成的列表,置于方括号内。元素不必是字面量;数组初始化器每次求值都会重新求各元素表达式。

数组元素可在列表的开头、中间或结尾省略。若元素列表中的一个逗号未被 AssignmentExpression 前导(例如在开头或跟在另一个逗号后),则缺失的数组元素会计入 Array 的 length 并增加后续元素索引。被省略的数组元素未定义。若在数组末尾省略元素,该元素不计入 Array 的 length。

语法 (Syntax)

ArrayLiteral[Yield, Await] : [ Elisionopt ] [ ElementList[?Yield, ?Await] ] [ ElementList[?Yield, ?Await] , Elisionopt ] ElementList[Yield, Await] : Elisionopt AssignmentExpression[+In, ?Yield, ?Await] Elisionopt SpreadElement[?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt AssignmentExpression[+In, ?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt SpreadElement[?Yield, ?Await] Elision : , Elision , SpreadElement[Yield, Await] : ... AssignmentExpression[+In, ?Yield, ?Await]

13.2.4.1 运行时语义:ArrayAccumulation : 返回一个含整数的正常完成或一个突然完成

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

Elision : ,
  1. lennextIndex + 1。
  2. 执行 ? Set(array, "length", 𝔽(len), true)。
  3. 注:若 len 超过 232 - 1,上一步会抛出。
  4. 返回 len
Elision : Elision ,
  1. 返回 ? ArrayAccumulation of Elision with arguments array and (nextIndex + 1)。
ElementList : Elisionopt AssignmentExpression
  1. 若存在 Elision,则
    1. nextIndex 设为 ? ArrayAccumulation of Elision,参数 arraynextIndex
  2. initResult 为 ? Evaluation of AssignmentExpression
  3. initValue 为 ? GetValue(initResult)。
  4. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), initValue)。
  5. 返回 nextIndex + 1。
ElementList : Elisionopt SpreadElement
  1. 若存在 Elision,则
    1. nextIndex 设为 ? ArrayAccumulation of Elision,参数 arraynextIndex
  2. 返回 ? ArrayAccumulation of SpreadElement,参数 arraynextIndex
ElementList : ElementList , Elisionopt AssignmentExpression
  1. nextIndex 设为 ? ArrayAccumulation of ElementList,参数 arraynextIndex
  2. 若存在 Elision,则
    1. nextIndex 设为 ? ArrayAccumulation of Elision,参数 arraynextIndex
  3. initResult 为 ? Evaluation of AssignmentExpression
  4. initValue 为 ? GetValue(initResult)。
  5. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), initValue)。
  6. 返回 nextIndex + 1。
ElementList : ElementList , Elisionopt SpreadElement
  1. nextIndex 设为 ? ArrayAccumulation of ElementList,参数 arraynextIndex
  2. 若存在 Elision,则
    1. nextIndex 设为 ? ArrayAccumulation of Elision,参数 arraynextIndex
  3. 返回 ? ArrayAccumulation of SpreadElement,参数 arraynextIndex
SpreadElement : ... AssignmentExpression
  1. spreadRef 为 ? Evaluation of AssignmentExpression
  2. spreadObj 为 ? GetValue(spreadRef)。
  3. iteratorRecord 为 ? GetIterator(spreadObj, sync)。
  4. 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. nextdone,返回 nextIndex
    3. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), next)。
    4. nextIndex 设为 nextIndex + 1。
Note

使用 CreateDataPropertyOrThrow 以确保即使内置 Array 原型对象被修改(导致用 [[Set]] 无法创建新自有属性),数组自有属性仍能被定义。

13.2.4.2 运行时语义:求值 (Runtime Semantics: Evaluation)

ArrayLiteral : [ Elisionopt ]
  1. array 为 ! ArrayCreate(0)。
  2. 若存在 Elision,则
    1. 执行 ? ArrayAccumulation of Elision,参数 array 与 0。
  3. 返回 array
ArrayLiteral : [ ElementList ]
  1. array 为 ! ArrayCreate(0)。
  2. 执行 ? ArrayAccumulation of ElementList,参数 array 与 0。
  3. 返回 array
ArrayLiteral : [ ElementList , Elisionopt ]
  1. array 为 ! ArrayCreate(0)。
  2. nextIndex 为 ? ArrayAccumulation of ElementList,参数 array 与 0。
  3. 若存在 Elision,则
    1. 执行 ? ArrayAccumulation of Elision,参数 arraynextIndex
  4. 返回 array

13.2.5 对象初始化器 (Object Initializer)

Note 1

对象初始化器是描述对象初始化的表达式,其形式类似字面量。它是零个或多个属性键及其关联值的列表,置于花括号中。值不必是字面量;对象初始化器每次求值都会重新求各值。

语法 (Syntax)

ObjectLiteral[Yield, Await] : { } { PropertyDefinitionList[?Yield, ?Await] } { PropertyDefinitionList[?Yield, ?Await] , } PropertyDefinitionList[Yield, Await] : PropertyDefinition[?Yield, ?Await] PropertyDefinitionList[?Yield, ?Await] , PropertyDefinition[?Yield, ?Await] PropertyDefinition[Yield, Await] : IdentifierReference[?Yield, ?Await] CoverInitializedName[?Yield, ?Await] PropertyName[?Yield, ?Await] : AssignmentExpression[+In, ?Yield, ?Await] MethodDefinition[?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] PropertyName[Yield, Await] : LiteralPropertyName ComputedPropertyName[?Yield, ?Await] LiteralPropertyName : IdentifierName StringLiteral NumericLiteral ComputedPropertyName[Yield, Await] : [ AssignmentExpression[+In, ?Yield, ?Await] ] CoverInitializedName[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await] Initializer[In, Yield, Await] : = AssignmentExpression[?In, ?Yield, ?Await] Note 2 Note 3

在某些上下文中,ObjectLiteral 作为更受限次级语法的覆盖语法使用。CoverInitializedName 产生式的存在是为了完整覆盖这些次级语法。但在期望实际 ObjectLiteral 的正常上下文中使用该产生式会导致早期语法错误。

13.2.5.1 静态语义:早期错误 (Static Semantics: Early Errors)

PropertyDefinition : MethodDefinition

除了描述实际对象初始化器,ObjectLiteral 产生式也作为 ObjectAssignmentPattern覆盖语法,并可能作为 CoverParenthesizedExpressionAndArrowParameterList 一部分被识别。当 ObjectLiteral 出现在需要 ObjectAssignmentPattern 的上下文中时,下列早期错误规则适用;初始解析 CoverParenthesizedExpressionAndArrowParameterListCoverCallExpressionAndAsyncArrowHead 时也不适用。

PropertyDefinition : CoverInitializedName
  • 若有源码匹配该产生式则为语法错误。
Note 1

该产生式存在是为了让 ObjectLiteral 作为 ObjectAssignmentPattern覆盖语法;它不可能出现在实际对象初始化器中。

ObjectLiteral : { PropertyDefinitionList } { PropertyDefinitionList , } Note 2

PropertyNameList 返回的列表不包含通过 ComputedPropertyName 定义的属性名

13.2.5.2 静态语义:IsComputedPropertyKey

The syntax-directed operation 静态语义:IsComputedPropertyKey takes no arguments and returns Boolean. It is defined piecewise over the following productions:

PropertyName : LiteralPropertyName
  1. 返回 false
PropertyName : ComputedPropertyName
  1. 返回 true

13.2.5.3 静态语义:PropertyNameList

The syntax-directed operation 静态语义:PropertyNameList takes no arguments and returns 字符串列表 (a List of Strings). It is defined piecewise over the following productions:

PropertyDefinitionList : PropertyDefinition
  1. propNamePropertyDefinition 的 PropName。
  2. propNameempty,返回空新列表。
  3. 返回 « propName »。
PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. listPropertyDefinitionList 的 PropertyNameList。
  2. propNamePropertyDefinition 的 PropName。
  3. propNameempty,返回 list
  4. 返回 list 与 « propName » 的列表连接。

13.2.5.4 运行时语义:求值 (Runtime Semantics: Evaluation)

ObjectLiteral : { }
  1. 返回 OrdinaryObjectCreate(%Object.prototype%)。
ObjectLiteral : { PropertyDefinitionList } { PropertyDefinitionList , }
  1. objOrdinaryObjectCreate(%Object.prototype%)。
  2. 执行 ? PropertyDefinitionEvaluation of PropertyDefinitionList,参数 obj
  3. 返回 obj
LiteralPropertyName : IdentifierName
  1. 返回 IdentifierName 的 StringValue。
LiteralPropertyName : StringLiteral
  1. 返回 StringLiteral 的 SV。
LiteralPropertyName : NumericLiteral
  1. nbrNumericLiteral 的 NumericValue。
  2. 返回 ! ToString(nbr)。
ComputedPropertyName : [ AssignmentExpression ]
  1. exprValue 为 ? Evaluation of AssignmentExpression
  2. propName 为 ? GetValue(exprValue)。
  3. 返回 ? ToPropertyKey(propName)。

13.2.5.5 运行时语义:PropertyDefinitionEvaluation : 返回含 unused 的正常完成或一个突然完成

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. 执行 ? PropertyDefinitionEvaluation of PropertyDefinitionList,参数 object
  2. 执行 ? PropertyDefinitionEvaluation of PropertyDefinition,参数 object
  3. 返回 unused
PropertyDefinition : ... AssignmentExpression
  1. exprValue 为 ? Evaluation of AssignmentExpression
  2. fromValue 为 ? GetValue(exprValue)。
  3. excludedNames 为新空列表。
  4. 执行 ? CopyDataProperties(object, fromValue, excludedNames)。
  5. 返回 unused
PropertyDefinition : IdentifierReference
  1. propNameIdentifierReference 的 StringValue。
  2. exprValue 为 ? Evaluation of IdentifierReference
  3. propValue 为 ? GetValue(exprValue)。
  4. 断言:object 是普通、可扩展且无不可配置属性的对象。
  5. 执行 ! CreateDataPropertyOrThrow(object, propName, propValue)。
  6. 返回 unused
PropertyDefinition : PropertyName : AssignmentExpression
  1. propKey 为 ? Evaluation of PropertyName
  2. 若此 PropertyDefinition 位于为 ParseJSON 求值的 Script 中(见 ParseJSON6 步骤),则
    1. isProtoSetterfalse
  3. 否则若 propKey"__proto__" 且 IsComputedPropertyKey(PropertyName) 为 false,则
    1. isProtoSettertrue
  4. 否则,
    1. isProtoSetterfalse
  5. 若 IsAnonymousFunctionDefinition(AssignmentExpression) 为 trueisProtoSetterfalse,则
    1. propValue 为 ? NamedEvaluation of AssignmentExpression,参数 propKey
  6. 否则,
    1. exprValueRef 为 ? Evaluation of AssignmentExpression
    2. propValue 为 ? GetValue(exprValueRef)。
  7. isProtoSettertrue,则
    1. propValue 是 ObjectpropValuenull,则
      1. 执行 ! object.[[SetPrototypeOf]](propValue)。
    2. 返回 unused
  8. 断言:object 是普通、可扩展且无不可配置属性的对象。
  9. 执行 ! CreateDataPropertyOrThrow(object, propKey, propValue)。
  10. 返回 unused
PropertyDefinition : MethodDefinition
  1. 执行 ? MethodDefinitionEvaluation of MethodDefinition,参数 objecttrue
  2. 返回 unused

13.2.6 定义函数的表达式 (Function Defining Expressions)

15.2 关于 PrimaryExpression : FunctionExpression

15.5 关于 PrimaryExpression : GeneratorExpression

15.7 关于 PrimaryExpression : ClassExpression

15.8 关于 PrimaryExpression : AsyncFunctionExpression

15.6 关于 PrimaryExpression : AsyncGeneratorExpression

13.2.7 正则表达式字面量 (Regular Expression Literals)

语法 (Syntax)

12.9.5

13.2.7.1 静态语义:早期错误 (Static Semantics: Early Errors)

PrimaryExpression : RegularExpressionLiteral

13.2.7.2 静态语义:IsValidRegularExpressionLiteral ( literal )

The abstract operation 静态语义:IsValidRegularExpressionLiteral takes argument literal (一个 RegularExpressionLiteral Parse Node) and returns Boolean. 判断参数是否为有效的正则表达式字面量。 It performs the following steps when called:

  1. flagsliteral 的 FlagText。
  2. flags 含有除 dgimsuvy 之外任意码点,或某码点出现多次,返回 false
  3. flagsu,设 utrue;否则 false
  4. flagsv,设 vtrue;否则 false
  5. patternTextliteral 的 BodyText。
  6. ufalsevfalse,则
    1. stringValue 为 CodePointsToString(patternText)。
    2. patternText 设为解释 stringValue 的每个 16 位元素为 Unicode BMP 码点后的码点序列(不执行 UTF-16 解码组合)。
  7. parseResult 为 ParsePattern(patternText, u, v)。
  8. parseResult 是 Parse Node,返回 true;否则返回 false

13.2.7.3 运行时语义:求值 (Runtime Semantics: Evaluation)

PrimaryExpression : RegularExpressionLiteral
  1. pattern 为 CodePointsToString(BodyText of RegularExpressionLiteral)。
  2. flags 为 CodePointsToString(FlagText of RegularExpressionLiteral)。
  3. 返回 ! RegExpCreate(pattern, flags)。

13.2.8 模板字面量 (Template Literals)

语法 (Syntax)

TemplateLiteral[Yield, Await, Tagged] : NoSubstitutionTemplate SubstitutionTemplate[?Yield, ?Await, ?Tagged] SubstitutionTemplate[Yield, Await, Tagged] : TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged] TemplateSpans[Yield, Await, Tagged] : TemplateTail TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateTail TemplateMiddleList[Yield, Await, Tagged] : TemplateMiddle Expression[+In, ?Yield, ?Await] TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await]

13.2.8.1 静态语义:早期错误 (Static Semantics: Early Errors)

TemplateLiteral[Yield, Await, Tagged] : NoSubstitutionTemplate TemplateLiteral[Yield, Await, Tagged] : SubstitutionTemplate[?Yield, ?Await, ?Tagged]
  • 若以 false 为参数的 TemplateLiteral 的 TemplateStrings 中元素数 ≥ 232,则为语法错误。
SubstitutionTemplate[Yield, Await, Tagged] : TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged] TemplateSpans[Yield, Await, Tagged] : TemplateTail TemplateMiddleList[Yield, Await, Tagged] : TemplateMiddle Expression[+In, ?Yield, ?Await] TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await]

13.2.8.2 静态语义:TemplateStrings : 一个由 String 或 undefined 组成的列表

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

TemplateLiteral : NoSubstitutionTemplate
  1. 返回 « TemplateString(NoSubstitutionTemplate, raw) »。
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. head 为 « TemplateString(TemplateHead, raw) »。
  2. tailTemplateSpans 的 TemplateStrings,参数 raw
  3. 返回 headtail 的列表连接。
TemplateSpans : TemplateTail
  1. 返回 « TemplateString(TemplateTail, raw) »。
TemplateSpans : TemplateMiddleList TemplateTail
  1. middleTemplateMiddleList 的 TemplateStrings,参数 raw
  2. tail 为 « TemplateString(TemplateTail, raw) »。
  3. 返回 middletail 的列表连接。
TemplateMiddleList : TemplateMiddle Expression
  1. 返回 « TemplateString(TemplateMiddle, raw) »。
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. frontTemplateMiddleList 的 TemplateStrings,参数 raw
  2. last 为 « TemplateString(TemplateMiddle, raw) »。
  3. 返回 frontlast 的列表连接。

13.2.8.3 静态语义:TemplateString (Static Semantics: TemplateString) ( templateToken: 一个 NoSubstitutionTemplateTemplateHeadTemplateMiddleTemplateTail Parse Node, raw: Boolean, ): 一个 String 或 undefined

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

  1. rawtrue,则
    1. stringtemplateToken 的 TRV。
  2. 否则,
    1. stringtemplateToken 的 TV。
  3. 返回 string
Note

rawfalsetemplateTokenNotEscapeSequence,该操作返回 undefined;其它情况返回 String。

13.2.8.4 GetTemplateObject ( templateLiteral )

The abstract operation GetTemplateObject takes argument templateLiteral (一个 Parse Node) and returns 一个 Array. It performs the following steps when called:

  1. realm当前 Realm Record
  2. templateRegistryrealm.[[TemplateMap]]
  3. templateRegistry 中每个元素 e
    1. e.[[Site]]templateLiteral 是同一 Parse Node,则
      1. 返回 e.[[Array]]
  4. rawStringstemplateLiteral 的 TemplateStrings,参数 true
  5. 断言:rawStrings 是 String 列表。
  6. cookedStringstemplateLiteral 的 TemplateStrings,参数 false
  7. countcookedStrings 元素数量。
  8. 断言:count ≤ 232 - 1。
  9. template 为 ! ArrayCreate(count)。
  10. rawObj 为 ! ArrayCreate(count)。
  11. index 为 0。
  12. index < count 重复:
    1. prop 为 ! ToString(𝔽(index))。
    2. cookedValuecookedStrings[index]。
    3. 执行 ! DefinePropertyOrThrow(template, prop, PropertyDescriptor { [[Value]]: cookedValue, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false })。
    4. rawValuerawStrings[index] 的 String 值。
    5. 执行 ! DefinePropertyOrThrow(rawObj, prop, PropertyDescriptor { [[Value]]: rawValue, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false })。
    6. index 设为 index + 1。
  13. 执行 ! SetIntegrityLevel(rawObj, frozen)。
  14. 执行 ! DefinePropertyOrThrow(template, "raw", PropertyDescriptor { [[Value]]: rawObj, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })。
  15. 执行 ! SetIntegrityLevel(template, frozen)。
  16. 将记录 { [[Site]]: templateLiteral, [[Array]]: template } 附加到 realm.[[TemplateMap]]
  17. 返回 template
Note 1

创建模板对象不会导致突然完成。

Note 2

同一 realm 中程序代码里的每个 TemplateLiteral 关联一个用于求值标签模板(13.2.8.6)的唯一模板对象。模板对象被冻结;同一标签模板每次求值复用同一个模板对象。是首次求值惰性创建还是提前创建是实现细节,对 ECMAScript 代码不可观察。

Note 3

规范未来版本可能为模板对象定义额外不可枚举属性。

13.2.8.5 运行时语义:SubstitutionEvaluation

The syntax-directed operation 运行时语义:SubstitutionEvaluation takes no arguments and returns 返回含 ECMAScript 语言值列表的正常完成或一个突然完成. It is defined piecewise over the following productions:

TemplateSpans : TemplateTail
  1. 返回新的空列表。
TemplateSpans : TemplateMiddleList TemplateTail
  1. 返回 ? SubstitutionEvaluation of TemplateMiddleList
TemplateMiddleList : TemplateMiddle Expression
  1. subRef 为 ? Evaluation of Expression
  2. sub 为 ? GetValue(subRef)。
  3. 返回 « sub »。
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. preceding 为 ? SubstitutionEvaluation of TemplateMiddleList
  2. nextRef 为 ? Evaluation of Expression
  3. next 为 ? GetValue(nextRef)。
  4. 返回 preceding 与 « next » 的列表连接。

13.2.8.6 运行时语义:求值 (Runtime Semantics: Evaluation)

TemplateLiteral : NoSubstitutionTemplate
  1. 返回 12.9.6 中定义的 NoSubstitutionTemplate 的 TV。
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. head12.9.6 中定义的 TemplateHead 的 TV。
  2. subRef 为 ? Evaluation of Expression
  3. sub 为 ? GetValue(subRef)。
  4. middle 为 ? ToString(sub)。
  5. tail 为 ? Evaluation of TemplateSpans
  6. 返回 headmiddletail 的字符串连接。
Note 1

Expression 值的字符串转换语义类似 String.prototype.concat 而非 + 运算符。

TemplateSpans : TemplateTail
  1. 返回 12.9.6 中定义的 TemplateTail 的 TV。
TemplateSpans : TemplateMiddleList TemplateTail
  1. head 为 ? Evaluation of TemplateMiddleList
  2. tail12.9.6 中定义的 TemplateTail 的 TV。
  3. 返回 headtail 的字符串连接。
TemplateMiddleList : TemplateMiddle Expression
  1. head12.9.6 中定义的 TemplateMiddle 的 TV。
  2. subRef 为 ? Evaluation of Expression
  3. sub 为 ? GetValue(subRef)。
  4. middle 为 ? ToString(sub)。
  5. 返回 headmiddle 的字符串连接。
Note 2

Expression 值的字符串转换语义类似 String.prototype.concat 而非 + 运算符。

TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. rest 为 ? Evaluation of TemplateMiddleList
  2. middle12.9.6 中定义的 TemplateMiddle 的 TV。
  3. subRef 为 ? Evaluation of Expression
  4. sub 为 ? GetValue(subRef)。
  5. last 为 ? ToString(sub)。
  6. 返回 restmiddlelast 的字符串连接。
Note 3

Expression 值的字符串转换语义类似 String.prototype.concat 而非 + 运算符。

13.2.9 分组运算符 (The Grouping Operator)

13.2.9.1 静态语义:早期错误 (Static Semantics: Early Errors)

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList

13.2.9.2 运行时语义:求值 (Runtime Semantics: Evaluation)

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprCoverParenthesizedExpressionAndArrowParameterList覆盖ParenthesizedExpression
  2. 返回 ? Evaluation of expr
ParenthesizedExpression : ( Expression )
  1. 返回 ? Evaluation of Expression。其结果可能是 Reference 类型。
Note

该算法不对 Expression 的 Evaluation 结果执行 GetValue。其主要动机是允许对括号表达式应用 deletetypeof 等运算符。

13.3 左值表达式 (Left-Hand-Side Expressions)

语法 (Syntax)

MemberExpression[Yield, Await] : PrimaryExpression[?Yield, ?Await] MemberExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] MemberExpression[?Yield, ?Await] . IdentifierName MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] SuperProperty[?Yield, ?Await] MetaProperty new MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] MemberExpression[?Yield, ?Await] . PrivateIdentifier SuperProperty[Yield, Await] : super [ Expression[+In, ?Yield, ?Await] ] super . IdentifierName MetaProperty : NewTarget ImportMeta NewTarget : new . target ImportMeta : import . meta NewExpression[Yield, Await] : MemberExpression[?Yield, ?Await] new NewExpression[?Yield, ?Await] CallExpression[Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] SuperCall[?Yield, ?Await] ImportCall[?Yield, ?Await] CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await] CallExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] CallExpression[?Yield, ?Await] . IdentifierName CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] CallExpression[?Yield, ?Await] . PrivateIdentifier SuperCall[Yield, Await] : super Arguments[?Yield, ?Await] ImportCall[Yield, Await] : import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) Arguments[Yield, Await] : ( ) ( ArgumentList[?Yield, ?Await] ) ( ArgumentList[?Yield, ?Await] , ) ArgumentList[Yield, Await] : AssignmentExpression[+In, ?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , ... AssignmentExpression[+In, ?Yield, ?Await] OptionalExpression[Yield, Await] : MemberExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalChain[Yield, Await] : ?. Arguments[?Yield, ?Await] ?. [ Expression[+In, ?Yield, ?Await] ] ?. IdentifierName ?. TemplateLiteral[?Yield, ?Await, +Tagged] ?. PrivateIdentifier OptionalChain[?Yield, ?Await] Arguments[?Yield, ?Await] OptionalChain[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] OptionalChain[?Yield, ?Await] . IdentifierName OptionalChain[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] OptionalChain[?Yield, ?Await] . PrivateIdentifier LeftHandSideExpression[Yield, Await] : NewExpression[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalExpression[?Yield, ?Await]

补充语法 (Supplemental Syntax)

当处理产生式实例:
CallExpression : CoverCallExpressionAndAsyncArrowHead
时,使用下列语法细化对 CoverCallExpressionAndAsyncArrowHead 的解释:

CallMemberExpression[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

13.3.1 静态语义 (Static Semantics)

13.3.1.1 静态语义:早期错误 (Static Semantics: Early Errors)

OptionalChain : ?. TemplateLiteral OptionalChain TemplateLiteral
  • 若有源码匹配该产生式则为语法错误。
Note

该产生式存在是为了阻止自动分号插入规则(12.10)应用于以下代码:

a?.b
`c`

使其被解释为两个合法语句。其目的在于与没有可选链的类似代码保持一致:

a.b
`c`

后者是一个合法语句,且自动分号插入不适用。

ImportMeta : import . meta

13.3.2 属性访问器 (Property Accessors)

Note

属性按名称访问,可以使用点号表示法:

也可以使用方括号表示法:

点号表示法可以通过以下句法转换来解释:

其行为与

MemberExpression [ <identifier-name-string> ]

相同;类似地

其行为与

CallExpression [ <identifier-name-string> ]

相同,其中 <identifier-name-string> 为 IdentifierName 的 StringValue。

13.3.2.1 运行时语义:求值 (Runtime Semantics: Evaluation)

MemberExpression : MemberExpression [ Expression ]
  1. baseReference 为 ? Evaluation of MemberExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. strict 为 IsStrict(this MemberExpression)。
  4. 返回 ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)。
MemberExpression : MemberExpression . IdentifierName
  1. baseReference 为 ? Evaluation of MemberExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. strict 为 IsStrict(this MemberExpression)。
  4. 返回 EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)。
MemberExpression : MemberExpression . PrivateIdentifier
  1. baseReference 为 ? Evaluation of MemberExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. fieldNameStringPrivateIdentifier 的 StringValue。
  4. 返回 MakePrivateReference(baseValue, fieldNameString)。
CallExpression : CallExpression [ Expression ]
  1. baseReference 为 ? Evaluation of CallExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. strict 为 IsStrict(this CallExpression)。
  4. 返回 ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)。
CallExpression : CallExpression . IdentifierName
  1. baseReference 为 ? Evaluation of CallExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. strict 为 IsStrict(this CallExpression)。
  4. 返回 EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)。
CallExpression : CallExpression . PrivateIdentifier
  1. baseReference 为 ? Evaluation of CallExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. fieldNameStringPrivateIdentifier 的 StringValue。
  4. 返回 MakePrivateReference(baseValue, fieldNameString)。

13.3.3 EvaluatePropertyAccessWithExpressionKey ( baseValue, expression, strict )

The abstract operation EvaluatePropertyAccessWithExpressionKey takes arguments baseValue (一个 ECMAScript 语言值), expression (一个 Expression Parse Node), and strict (一个 Boolean) and returns 返回一个含 Reference Record正常完成或一个突然完成. It performs the following steps when called:

  1. propertyNameReference 为 ? Evaluation of expression
  2. propertyNameValue 为 ? GetValue(propertyNameReference)。
  3. 注:在大多数情况下,会在此步骤后立即对 propertyNameValue 执行 ToPropertyKey。但在 a[b] = c 的情形下,会延迟到 c 求值之后。
  4. 返回 Reference Record { [[Base]]: baseValue, [[ReferencedName]]: propertyNameValue, [[Strict]]: strict, [[ThisValue]]: empty }。

13.3.4 EvaluatePropertyAccessWithIdentifierKey ( baseValue, identifierName, strict )

The abstract operation EvaluatePropertyAccessWithIdentifierKey takes arguments baseValue (一个 ECMAScript 语言值), identifierName (一个 IdentifierName Parse Node), and strict (一个 Boolean) and returns 一个 Reference Record. It performs the following steps when called:

  1. propertyNameStringidentifierName 的 StringValue。
  2. 返回 Reference Record { [[Base]]: baseValue, [[ReferencedName]]: propertyNameString, [[Strict]]: strict, [[ThisValue]]: empty }。

13.3.5 new 运算符 (The new Operator)

13.3.5.1 运行时语义:求值 (Runtime Semantics: Evaluation)

NewExpression : new NewExpression
  1. 返回 ? EvaluateNew(NewExpression, empty)。
MemberExpression : new MemberExpression Arguments
  1. 返回 ? EvaluateNew(MemberExpression, Arguments)。

13.3.5.1.1 EvaluateNew ( constructExpr, arguments )

The abstract operation EvaluateNew takes arguments constructExpr (一个 NewExpression Parse Node 或 MemberExpression Parse Node) and arguments (empty 或一个 Arguments Parse Node) and returns 返回一个含 ECMAScript 语言值正常完成或一个突然完成. It performs the following steps when called:

  1. ref 为 ? Evaluation of constructExpr
  2. constructor 为 ? GetValue(ref)。
  3. argumentsempty,则
    1. argList 为新空列表。
  4. 否则,
    1. argList 为 ? ArgumentListEvaluation of arguments
  5. IsConstructor(constructor) 为 false,抛出 TypeError 异常。
  6. 返回 ? Construct(constructor, argList)。

13.3.6 函数调用 (Function Calls)

13.3.6.1 运行时语义:求值 (Runtime Semantics: Evaluation)

CallExpression : CoverCallExpressionAndAsyncArrowHead
  1. exprCoverCallExpressionAndAsyncArrowHead 覆盖CallMemberExpression
  2. memberExprexprMemberExpression
  3. argumentsexprArguments
  4. ref 为 ? Evaluation of memberExpr
  5. func 为 ? GetValue(ref)。
  6. refReference RecordIsPropertyReference(ref) 为 false,且 ref.[[ReferencedName]]"eval",则
    1. SameValue(func, %eval%) 为 true,则
      1. argList 为 ? ArgumentListEvaluation of arguments
      2. argList 无元素,返回 undefined
      3. evalArgargList 的第一个元素。
      4. 若 IsStrict(this CallExpression) 为 true,令 strictCallertrue;否则为 false
      5. 返回 ? PerformEval(evalArg, strictCaller, true)。
  7. thisCall 为 this CallExpression
  8. tailCall 为 IsInTailPosition(thisCall)。
  9. 返回 ? EvaluateCall(func, ref, arguments, tailCall)。

执行步骤 6.a.vCallExpression 求值是一次直接 eval (direct eval)

CallExpression : CallExpression Arguments
  1. ref 为 ? Evaluation of CallExpression
  2. func 为 ? GetValue(ref)。
  3. thisCall 为 this CallExpression
  4. tailCall 为 IsInTailPosition(thisCall)。
  5. 返回 ? EvaluateCall(func, ref, Arguments, tailCall)。

13.3.6.2 EvaluateCall ( func, ref, arguments, tailPosition )

The abstract operation EvaluateCall takes arguments func (一个 ECMAScript 语言值), ref (一个 ECMAScript 语言值Reference Record), arguments (一个 Parse Node), and tailPosition (一个 Boolean) and returns 返回一个含 ECMAScript 语言值正常完成或一个突然完成. It performs the following steps when called:

  1. refReference Record,则
    1. IsPropertyReference(ref) 为 true,则
      1. thisValueGetThisValue(ref)。
    2. 否则,
      1. refEnvref.[[Base]]
      2. 断言:refEnv 是一个 Environment Record
      3. thisValuerefEnv.WithBaseObject()。
  2. 否则,
    1. thisValueundefined
  3. argList 为 ? ArgumentListEvaluation of arguments
  4. func 不是 Object,抛出 TypeError 异常。
  5. IsCallable(func) 为 false,抛出 TypeError 异常。
  6. tailPositiontrue,执行 PrepareForTailCall()。
  7. 返回 ? Call(func, thisValue, argList)。

13.3.7 super 关键字 (The super Keyword)

13.3.7.1 运行时语义:求值 (Runtime Semantics: Evaluation)

SuperProperty : super [ Expression ]
  1. envGetThisEnvironment()。
  2. actualThis 为 ? env.GetThisBinding()。
  3. propertyNameReference 为 ? Evaluation of Expression
  4. propertyNameValue 为 ? GetValue(propertyNameReference)。
  5. strict 为 IsStrict(this SuperProperty)。
  6. 注:在大多数情况下,会在此步骤后立即对 propertyNameValue 执行 ToPropertyKey。但在 super[b] = c 的情形下,会延迟到 c 求值后。
  7. 返回 MakeSuperPropertyReference(actualThis, propertyNameValue, strict)。
SuperProperty : super . IdentifierName
  1. envGetThisEnvironment()。
  2. actualThis 为 ? env.GetThisBinding()。
  3. propertyKeyIdentifierName 的 StringValue。
  4. strict 为 IsStrict(this SuperProperty)。
  5. 返回 MakeSuperPropertyReference(actualThis, propertyKey, strict)。
SuperCall : super Arguments
  1. newTargetGetNewTarget()。
  2. 断言:newTarget 是一个构造函数
  3. funcGetSuperConstructor()。
  4. argList 为 ? ArgumentListEvaluation of Arguments
  5. IsConstructor(func) 为 false,抛出 TypeError 异常。
  6. result 为 ? Construct(func, argList, newTarget)。
  7. thisERGetThisEnvironment()。
  8. 断言:thisER 是一个 Function Environment Record
  9. 执行 ? BindThisValue(thisER, result)。
  10. FthisER.[[FunctionObject]]
  11. 断言:F 是一个 ECMAScript 函数对象
  12. 执行 ? InitializeInstanceElements(result, F)。
  13. 返回 result

13.3.7.2 GetSuperConstructor ( )

The abstract operation GetSuperConstructor takes no arguments and returns 一个 ECMAScript 语言值. It performs the following steps when called:

  1. envRecGetThisEnvironment()。
  2. 断言:envRec 是一个 Function Environment Record
  3. activeFunctionenvRec.[[FunctionObject]]
  4. 断言:activeFunction 是一个 ECMAScript 函数对象
  5. superConstructor 为 ! activeFunction.[[GetPrototypeOf]]()。
  6. 返回 superConstructor

13.3.7.3 MakeSuperPropertyReference ( actualThis, propertyKey, strict )

The abstract operation MakeSuperPropertyReference takes arguments actualThis (一个 ECMAScript 语言值), propertyKey (一个 ECMAScript 语言值), and strict (一个 Boolean) and returns 一个 Super Reference Record. It performs the following steps when called:

  1. envGetThisEnvironment()。
  2. 断言:env.HasSuperBinding() 为 true
  3. 断言:env 是一个 Function Environment Record
  4. baseValueGetSuperBase(env)。
  5. 返回 Reference Record { [[Base]]: baseValue, [[ReferencedName]]: propertyKey, [[Strict]]: strict, [[ThisValue]]: actualThis }。

13.3.8 参数列表 (Argument Lists)

Note

对参数列表的求值会产生一个值的 List

13.3.8.1 运行时语义:ArgumentListEvaluation

The syntax-directed operation 运行时语义:ArgumentListEvaluation takes no arguments and returns 返回一个含 ECMAScript 语言值列表的正常完成或一个突然完成. It is defined piecewise over the following productions:

Arguments : ( )
  1. 返回一个新的空列表。
ArgumentList : AssignmentExpression
  1. ref 为 ? Evaluation of AssignmentExpression
  2. arg 为 ? GetValue(ref)。
  3. 返回 « arg »。
ArgumentList : ... AssignmentExpression
  1. list 为新空列表。
  2. spreadRef 为 ? Evaluation of AssignmentExpression
  3. spreadObj 为 ? GetValue(spreadRef)。
  4. iteratorRecord 为 ? GetIterator(spreadObj, sync)。
  5. 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. nextdone,返回 list
    3. next 追加到 list
ArgumentList : ArgumentList , AssignmentExpression
  1. precedingArgs 为 ? ArgumentListEvaluation of ArgumentList
  2. ref 为 ? Evaluation of AssignmentExpression
  3. arg 为 ? GetValue(ref)。
  4. 返回 precedingArgs 与 « arg » 的列表连接。
ArgumentList : ArgumentList , ... AssignmentExpression
  1. precedingArgs 为 ? ArgumentListEvaluation of ArgumentList
  2. spreadRef 为 ? Evaluation of AssignmentExpression
  3. iteratorRecord 为 ? GetIterator(? GetValue(spreadRef), sync)。
  4. 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. nextdone,返回 precedingArgs
    3. next 追加到 precedingArgs
TemplateLiteral : NoSubstitutionTemplate
  1. templateLiteral 为 this TemplateLiteral
  2. siteObjGetTemplateObject(templateLiteral)。
  3. 返回 « siteObj »。
TemplateLiteral : SubstitutionTemplate
  1. templateLiteral 为 this TemplateLiteral
  2. siteObjGetTemplateObject(templateLiteral)。
  3. remaining 为 ? ArgumentListEvaluation of SubstitutionTemplate
  4. 返回 « siteObj » 与 remaining 的列表连接。
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. firstSubRef 为 ? Evaluation of Expression
  2. firstSub 为 ? GetValue(firstSubRef)。
  3. restSub 为 ? SubstitutionEvaluation of TemplateSpans
  4. 断言:restSub 是一个可为空的列表。
  5. 返回 « firstSub » 与 restSub 的列表连接。

13.3.9 可选链 (Optional Chains)

Note
可选链是一个或多个属性访问与函数调用组成的链,其首个访问以 ?. 记号开始。

13.3.9.1 运行时语义:求值 (Runtime Semantics: Evaluation)

OptionalExpression : MemberExpression OptionalChain
  1. baseReference 为 ? Evaluation of MemberExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. baseValueundefinednull,则
    1. 返回 undefined
  4. 返回 ? ChainEvaluation of OptionalChain,参数 baseValuebaseReference
OptionalExpression : CallExpression OptionalChain
  1. baseReference 为 ? Evaluation of CallExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. baseValueundefinednull,则
    1. 返回 undefined
  4. 返回 ? ChainEvaluation of OptionalChain,参数 baseValuebaseReference
OptionalExpression : OptionalExpression OptionalChain
  1. baseReference 为 ? Evaluation of OptionalExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. baseValueundefinednull,则
    1. 返回 undefined
  4. 返回 ? ChainEvaluation of OptionalChain,参数 baseValuebaseReference

13.3.9.2 运行时语义:ChainEvaluation : 返回一个含 ECMAScript 语言值或 Reference Record 的正常完成,或一个突然完成

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

OptionalChain : ?. Arguments
  1. thisChain 为 this OptionalChain
  2. tailCall 为 IsInTailPosition(thisChain)。
  3. 返回 ? EvaluateCall(baseValue, baseReference, Arguments, tailCall)。
OptionalChain : ?. [ Expression ]
  1. strict 为 IsStrict(this OptionalChain)。
  2. 返回 ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)。
OptionalChain : ?. IdentifierName
  1. strict 为 IsStrict(this OptionalChain)。
  2. 返回 EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)。
OptionalChain : ?. PrivateIdentifier
  1. fieldNameStringPrivateIdentifier 的 StringValue。
  2. 返回 MakePrivateReference(baseValue, fieldNameString)。
OptionalChain : OptionalChain Arguments
  1. optionalChainOptionalChain
  2. newReference 为 ? ChainEvaluation of optionalChain,参数 baseValuebaseReference
  3. newValue 为 ? GetValue(newReference)。
  4. thisChain 为 this OptionalChain
  5. tailCall 为 IsInTailPosition(thisChain)。
  6. 返回 ? EvaluateCall(newValue, newReference, Arguments, tailCall)。
OptionalChain : OptionalChain [ Expression ]
  1. optionalChainOptionalChain
  2. newReference 为 ? ChainEvaluation of optionalChain,参数 baseValuebaseReference
  3. newValue 为 ? GetValue(newReference)。
  4. strict 为 IsStrict(this OptionalChain)。
  5. 返回 ? EvaluatePropertyAccessWithExpressionKey(newValue, Expression, strict)。
OptionalChain : OptionalChain . IdentifierName
  1. optionalChainOptionalChain
  2. newReference 为 ? ChainEvaluation of optionalChain,参数 baseValuebaseReference
  3. newValue 为 ? GetValue(newReference)。
  4. strict 为 IsStrict(this OptionalChain)。
  5. 返回 EvaluatePropertyAccessWithIdentifierKey(newValue, IdentifierName, strict)。
OptionalChain : OptionalChain . PrivateIdentifier
  1. optionalChainOptionalChain
  2. newReference 为 ? ChainEvaluation of optionalChain,参数 baseValuebaseReference
  3. newValue 为 ? GetValue(newReference)。
  4. fieldNameStringPrivateIdentifier 的 StringValue。
  5. 返回 MakePrivateReference(newValue, fieldNameString)。

13.3.10 Import 调用 (Import Calls)

13.3.10.1 运行时语义:求值 (Runtime Semantics: Evaluation)

ImportCall : import ( AssignmentExpression ,opt )
  1. 返回 ? EvaluateImportCall(AssignmentExpression)。
ImportCall : import ( AssignmentExpression , AssignmentExpression ,opt )
  1. 返回 ? EvaluateImportCall(第一个 AssignmentExpression, 第二个 AssignmentExpression)。

13.3.10.2 EvaluateImportCall ( specifierExpression: 一个 Parse Node, 可选 optionsExpression: 一个 Parse Node, ): 返回一个含 Promise 的正常完成或一个突然完成

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

  1. referrerGetActiveScriptOrModule()。
  2. referrernull,将 referrer 设为当前 Realm Record
  3. specifierRef 为 ? Evaluation of specifierExpression
  4. specifier 为 ? GetValue(specifierRef)。
  5. 若存在 optionsExpression,则
    1. optionsRef 为 ? Evaluation of optionsExpression
    2. options 为 ? GetValue(optionsRef)。
  6. 否则,
    1. optionsundefined
  7. promiseCapability 为 ! NewPromiseCapability(%Promise%)。
  8. specifierStringCompletion(ToString(specifier))。
  9. IfAbruptRejectPromise(specifierString, promiseCapability)。
  10. attributes 为新空列表。
  11. options 不为 undefined,则
    1. options 不是 Object,则
      1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « 新建的 TypeError 对象 »)。
      2. 返回 promiseCapability.[[Promise]]
    2. attributesObjCompletion(Get(options, "with"))。
    3. IfAbruptRejectPromise(attributesObj, promiseCapability)。
    4. attributesObj 不为 undefined,则
      1. attributesObj 不是 Object,则
        1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « 新建的 TypeError 对象 »)。
        2. 返回 promiseCapability.[[Promise]]
      2. entriesCompletion(EnumerableOwnProperties(attributesObj, key+value))。
      3. IfAbruptRejectPromise(entries, promiseCapability)。
      4. entries 中每个元素 entry
        1. key 为 ! Get(entry, "0")。
        2. value 为 ! Get(entry, "1")。
        3. key 是 String,则
          1. value 不是 String,则
            1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « 新建的 TypeError 对象 »)。
            2. 返回 promiseCapability.[[Promise]]
          2. ImportAttribute Record { [[Key]]: key, [[Value]]: value } 追加到 attributes
    5. AllImportAttributesSupported(attributes) 为 false,则
      1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « 新建的 TypeError 对象 »)。
      2. 返回 promiseCapability.[[Promise]]
    6. [[Key]] 字段字典序(将字段值视为 UTF-16 代码单元序列)对 attributes 排序。注:排序唯一可观察之处是宿主被禁止基于枚举顺序改变行为。
  12. moduleRequest 为新 ModuleRequest Record { [[Specifier]]: specifierString, [[Attributes]]: attributes }。
  13. 执行 HostLoadImportedModule(referrer, moduleRequest, empty, promiseCapability)。
  14. 返回 promiseCapability.[[Promise]]

13.3.10.3 ContinueDynamicImport ( promiseCapability, moduleCompletion )

The abstract operation ContinueDynamicImport takes arguments promiseCapability (一个 PromiseCapability Record) and moduleCompletion (一个含 Module Record正常完成或一个 throw completion) and returns unused. 它完成最初由 import() 调用开始的动态导入过程,适当地 resolve 或 reject 该调用返回的 promise。 It performs the following steps when called:

  1. moduleCompletion 是突然完成,则
    1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « moduleCompletion.[[Value]] »)。
    2. 返回 unused
  2. modulemoduleCompletion.[[Value]]
  3. loadPromisemodule.LoadRequestedModules()。
  4. rejectedClosure 为带参数 (reason)、捕获 promiseCapability 的新抽象闭包,调用时执行:
    1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « reason »)。
    2. 返回 NormalCompletion(undefined)。
  5. onRejectedCreateBuiltinFunction(rejectedClosure, 1, "", « »)。
  6. linkAndEvaluateClosure 为无参数、捕获 modulepromiseCapabilityonRejected 的新抽象闭包,调用时执行:
    1. linkCompletion(module.Link())。
    2. link 是突然完成,则
      1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « link.[[Value]] »)。
      2. 返回 NormalCompletion(undefined)。
    3. evaluatePromisemodule.Evaluate()。
    4. fulfilledClosure 为无参数、捕获 modulepromiseCapability 的新抽象闭包,调用时执行:
      1. namespaceGetModuleNamespace(module)。
      2. 执行 ! Call(promiseCapability.[[Resolve]], undefined, « namespace »)。
      3. 返回 NormalCompletion(undefined)。
    5. onFulfilledCreateBuiltinFunction(fulfilledClosure, 0, "", « »)。
    6. 执行 PerformPromiseThen(evaluatePromise, onFulfilled, onRejected)。
    7. 返回 unused
  7. linkAndEvaluateCreateBuiltinFunction(linkAndEvaluateClosure, 0, "", « »)。
  8. 执行 PerformPromiseThen(loadPromise, linkAndEvaluate, onRejected)。
  9. 返回 unused

13.3.11 带标签模板 (Tagged Templates)

Note

带标签模板是一个函数调用,其调用参数来源于 TemplateLiteral13.2.8)。实际参数包含一个模板对象(13.2.8.4)以及对 TemplateLiteral 内嵌表达式求值得到的值。

13.3.11.1 运行时语义:求值 (Runtime Semantics: Evaluation)

MemberExpression : MemberExpression TemplateLiteral
  1. tagRef 为 ? Evaluation of MemberExpression
  2. tagFunc 为 ? GetValue(tagRef)。
  3. thisCall 为 this MemberExpression
  4. tailCall 为 IsInTailPosition(thisCall)。
  5. 返回 ? EvaluateCall(tagFunc, tagRef, TemplateLiteral, tailCall)。
CallExpression : CallExpression TemplateLiteral
  1. tagRef 为 ? Evaluation of CallExpression
  2. tagFunc 为 ? GetValue(tagRef)。
  3. thisCall 为 this CallExpression
  4. tailCall 为 IsInTailPosition(thisCall)。
  5. 返回 ? EvaluateCall(tagFunc, tagRef, TemplateLiteral, tailCall)。

13.3.12 元属性 (Meta Properties)

13.3.12.1 运行时语义:求值 (Runtime Semantics: Evaluation)

NewTarget : new . target
  1. 返回 GetNewTarget()。
ImportMeta : import . meta
  1. moduleGetActiveScriptOrModule()。
  2. 断言:module 是一个 Source Text Module Record
  3. importMetamodule.[[ImportMeta]]
  4. importMetaempty,则
    1. importMeta 设为 OrdinaryObjectCreate(null)。
    2. importMetaValuesHostGetImportMetaProperties(module)。
    3. importMetaValues 中每个 Record { [[Key]], [[Value]] } p
      1. 执行 ! CreateDataPropertyOrThrow(importMeta, p.[[Key]], p.[[Value]])。
    4. 执行 HostFinalizeImportMeta(importMeta, module)。
    5. module.[[ImportMeta]] 设为 importMeta
    6. 返回 importMeta
  5. 否则,
    1. 断言:importMeta 是一个 Object。
    2. 返回 importMeta

13.3.12.1.1 HostGetImportMetaProperties ( moduleRecord )

The host-defined abstract operation HostGetImportMetaProperties takes argument moduleRecord (一个 Module Record) and returns 一个具有 [[Key]]属性键)与 [[Value]]ECMAScript 语言值)字段的 Record 列表. 允许宿主import.meta 返回的对象提供属性键与值。

HostGetImportMetaProperties 的默认实现是返回一个新的空列表。

13.3.12.1.2 HostFinalizeImportMeta ( importMeta, moduleRecord )

The host-defined abstract operation HostFinalizeImportMeta takes arguments importMeta (一个 Object) and moduleRecord (一个 Module Record) and returns unused. 允许宿主执行额外操作以准备将 import.meta 返回的对象暴露给 ECMAScript 代码。

大多数宿主仅需定义 HostGetImportMetaProperties,并保持 HostFinalizeImportMeta 的默认行为。但 HostFinalizeImportMeta 为需要在对象暴露前直接操作该对象的宿主提供“逃生口”。

HostFinalizeImportMeta 的默认实现是返回 unused

13.4 更新表达式 (Update Expressions)

语法 (Syntax)

UpdateExpression[Yield, Await] : LeftHandSideExpression[?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] ++ LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] -- ++ UnaryExpression[?Yield, ?Await] -- UnaryExpression[?Yield, ?Await]

13.4.1 静态语义:早期错误 (Static Semantics: Early Errors)

UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- UpdateExpression : ++ UnaryExpression -- UnaryExpression
  • UnaryExpression 的 AssignmentTargetType 为 invalid,则属于早期语法错误。

13.4.2 后缀自增运算符 (Postfix Increment Operator)

13.4.2.1 运行时语义:求值 (Runtime Semantics: Evaluation)

UpdateExpression : LeftHandSideExpression ++
  1. lhs 为 ? Evaluation of LeftHandSideExpression
  2. LeftHandSideExpression 的 AssignmentTargetType 为 web-compat,抛出 ReferenceError 异常。
  3. oldValue 为 ? ToNumeric(? GetValue(lhs))。
  4. oldValue 是 Number,则
    1. newValueNumber::add(oldValue, 1𝔽)。
  5. 否则,
    1. 断言:oldValue 为 BigInt。
    2. newValueBigInt::add(oldValue, 1)。
  6. 执行 ? PutValue(lhs, newValue)。
  7. 返回 oldValue

13.4.3 后缀自减运算符 (Postfix Decrement Operator)

13.4.3.1 运行时语义:求值 (Runtime Semantics: Evaluation)

UpdateExpression : LeftHandSideExpression --
  1. lhs 为 ? Evaluation of LeftHandSideExpression
  2. LeftHandSideExpression 的 AssignmentTargetType 为 web-compat,抛出 ReferenceError 异常。
  3. oldValue 为 ? ToNumeric(? GetValue(lhs))。
  4. oldValue 是 Number,则
    1. newValueNumber::subtract(oldValue, 1𝔽)。
  5. 否则,
    1. 断言:oldValue 为 BigInt。
    2. newValueBigInt::subtract(oldValue, 1)。
  6. 执行 ? PutValue(lhs, newValue)。
  7. 返回 oldValue

13.4.4 前缀自增运算符 (Prefix Increment Operator)

13.4.4.1 运行时语义:求值 (Runtime Semantics: Evaluation)

UpdateExpression : ++ UnaryExpression
  1. expr 为 ? Evaluation of UnaryExpression
  2. UnaryExpression 的 AssignmentTargetType 为 web-compat,抛出 ReferenceError 异常。
  3. oldValue 为 ? ToNumeric(? GetValue(expr))。
  4. oldValue 是 Number,则
    1. newValueNumber::add(oldValue, 1𝔽)。
  5. 否则,
    1. 断言:oldValue 为 BigInt。
    2. newValueBigInt::add(oldValue, 1)。
  6. 执行 ? PutValue(expr, newValue)。
  7. 返回 newValue

13.4.5 前缀自减运算符 (Prefix Decrement Operator)

13.4.5.1 运行时语义:求值 (Runtime Semantics: Evaluation)

UpdateExpression : -- UnaryExpression
  1. expr 为 ? Evaluation of UnaryExpression
  2. UnaryExpression 的 AssignmentTargetType 为 web-compat,抛出 ReferenceError 异常。
  3. oldValue 为 ? ToNumeric(? GetValue(expr))。
  4. oldValue 是 Number,则
    1. newValueNumber::subtract(oldValue, 1𝔽)。
  5. 否则,
    1. 断言:oldValue 为 BigInt。
    2. newValueBigInt::subtract(oldValue, 1)。
  6. 执行 ? PutValue(expr, newValue)。
  7. 返回 newValue

13.5 一元运算符 (Unary Operators)

语法 (Syntax)

UnaryExpression[Yield, Await] : UpdateExpression[?Yield, ?Await] delete UnaryExpression[?Yield, ?Await] void UnaryExpression[?Yield, ?Await] typeof UnaryExpression[?Yield, ?Await] + UnaryExpression[?Yield, ?Await] - UnaryExpression[?Yield, ?Await] ~ UnaryExpression[?Yield, ?Await] ! UnaryExpression[?Yield, ?Await] [+Await] AwaitExpression[?Yield]

13.5.1 delete 运算符 (The delete Operator)

13.5.1.1 静态语义:早期错误 (Static Semantics: Early Errors)

UnaryExpression : delete UnaryExpression Note

最后一条规则意味着诸如 delete (((foo))) 的表达式会因为递归应用首条规则而产生早期错误。

13.5.1.2 运行时语义:求值 (Runtime Semantics: Evaluation)

UnaryExpression : delete UnaryExpression
  1. ref 为 ? Evaluation of UnaryExpression
  2. ref 不是 Reference Record,返回 true
  3. IsUnresolvableReference(ref) 为 true,则
    1. 断言:ref.[[Strict]]false
    2. 返回 true
  4. IsPropertyReference(ref) 为 true,则
    1. 断言:IsPrivateReference(ref) 为 false
    2. IsSuperReference(ref) 为 true,抛出 ReferenceError 异常。
    3. baseObj 为 ? ToObject(ref.[[Base]])。
    4. ref.[[ReferencedName]] 不是属性键,则
      1. ref.[[ReferencedName]] 为 ? ToPropertyKey(ref.[[ReferencedName]])。
    5. deleteStatus 为 ? baseObj.[[Delete]](ref.[[ReferencedName]])。
    6. deleteStatusfalseref.[[Strict]]true,抛出 TypeError 异常。
    7. 返回 deleteStatus
  5. 否则,
    1. baseref.[[Base]]
    2. 断言:baseEnvironment Record
    3. 返回 ? base.DeleteBinding(ref.[[ReferencedName]])。
Note 1

在严格模式代码中出现的 delete 运算符,如果其 UnaryExpression 是对变量、函数参数或函数名的直接引用,则抛出 SyntaxError;另外,若删除的属性具有 { [[Configurable]]: false }(或以其他方式不可删除),则抛出 TypeError

Note 2

步骤 4.c 可能创建的对象在该抽象操作普通对象 [[Delete]] 内部方法之外不可访问,实现可选择避免实际创建该对象。

13.5.2 void 运算符 (The void Operator)

13.5.2.1 运行时语义:求值 (Runtime Semantics: Evaluation)

UnaryExpression : void UnaryExpression
  1. expr 为 ? Evaluation of UnaryExpression
  2. 执行 ? GetValue(expr)。
  3. 返回 undefined
Note

必须调用 GetValue(即使其结果未使用),因为它可能具有可观察的副作用。

13.5.3 typeof 运算符 (The typeof Operator)

13.5.3.1 运行时语义:求值 (Runtime Semantics: Evaluation)

UnaryExpression : typeof UnaryExpression
  1. val 为 ? Evaluation of UnaryExpression
  2. valReference Record,则
    1. IsUnresolvableReference(val) 为 true,返回 "undefined"
  3. val 为 ? GetValue(val)。
  4. valundefined,返回 "undefined"
  5. valnull,返回 "object"
  6. val 为 String,返回 "string"
  7. val 为 Symbol,返回 "symbol"
  8. val 为 Boolean,返回 "boolean"
  9. val 为 Number,返回 "number"
  10. val 为 BigInt,返回 "bigint"
  11. 断言:val 为 Object。
  12. Normative Optional
    宿主是 web 浏览器或否则支持 [[IsHTMLDDA]] 内部槽,则
    1. val 拥有 [[IsHTMLDDA]] 内部槽,返回 "undefined"
  13. val 拥有 [[Call]] 内部方法,返回 "function"
  14. 返回 "object"

13.5.4 一元 + 运算符 (Unary + Operator)

Note

一元 + 运算符将其操作数转换为 Number 类型

13.5.4.1 运行时语义:求值 (Runtime Semantics: Evaluation)

UnaryExpression : + UnaryExpression
  1. expr 为 ? Evaluation of UnaryExpression
  2. 返回 ? ToNumber(? GetValue(expr))。

13.5.5 一元 - 运算符 (Unary - Operator)

Note

一元 - 运算符将其操作数先转换为数值再取相反数。对 +0𝔽 取负得到 -0𝔽;对 -0𝔽 取负得到 +0𝔽

13.5.5.1 运行时语义:求值 (Runtime Semantics: Evaluation)

UnaryExpression : - UnaryExpression
  1. expr 为 ? Evaluation of UnaryExpression
  2. oldValue 为 ? ToNumeric(? GetValue(expr))。
  3. oldValue 是 Number,则
    1. 返回 Number::unaryMinus(oldValue)。
  4. 否则,
    1. 断言:oldValue 为 BigInt。
    2. 返回 BigInt::unaryMinus(oldValue)。

13.5.6 按位取反运算符 (Bitwise NOT Operator ~)

13.5.6.1 运行时语义:求值 (Runtime Semantics: Evaluation)

UnaryExpression : ~ UnaryExpression
  1. expr 为 ? Evaluation of UnaryExpression
  2. oldValue 为 ? ToNumeric(? GetValue(expr))。
  3. oldValue 是 Number,则
    1. 返回 Number::bitwiseNOT(oldValue)。
  4. 否则,
    1. 断言:oldValue 为 BigInt。
    2. 返回 BigInt::bitwiseNOT(oldValue)。

13.5.7 逻辑非运算符 (Logical NOT Operator !)

13.5.7.1 运行时语义:求值 (Runtime Semantics: Evaluation)

UnaryExpression : ! UnaryExpression
  1. expr 为 ? Evaluation of UnaryExpression
  2. oldValueToBoolean(? GetValue(expr))。
  3. oldValuetrue,返回 false
  4. 返回 true

13.6 幂运算符 (Exponentiation Operator)

语法 (Syntax)

ExponentiationExpression[Yield, Await] : UnaryExpression[?Yield, ?Await] UpdateExpression[?Yield, ?Await] ** ExponentiationExpression[?Yield, ?Await]

13.6.1 运行时语义:求值 (Runtime Semantics: Evaluation)

ExponentiationExpression : UpdateExpression ** ExponentiationExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(UpdateExpression, **, ExponentiationExpression)。

13.7 乘法类运算符 (Multiplicative Operators)

语法 (Syntax)

MultiplicativeExpression[Yield, Await] : ExponentiationExpression[?Yield, ?Await] MultiplicativeExpression[?Yield, ?Await] MultiplicativeOperator ExponentiationExpression[?Yield, ?Await] MultiplicativeOperator : one of * / % Note
  • * 运算符执行乘法,产生其操作数的乘积。
  • / 运算符执行除法,产生其操作数的商。
  • % 运算符产生隐含除法后的余数。

13.7.1 运行时语义:求值 (Runtime Semantics: Evaluation)

MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression
  1. opTextMultiplicativeOperator 匹配的源文本。
  2. 返回 ? EvaluateStringOrNumericBinaryExpression(MultiplicativeExpression, opText, ExponentiationExpression)。

13.8 加法类运算符 (Additive Operators)

语法 (Syntax)

AdditiveExpression[Yield, Await] : MultiplicativeExpression[?Yield, ?Await] AdditiveExpression[?Yield, ?Await] + MultiplicativeExpression[?Yield, ?Await] AdditiveExpression[?Yield, ?Await] - MultiplicativeExpression[?Yield, ?Await]

13.8.1 加法运算符 (The Addition Operator +)

Note

加法运算符执行字符串连接或数值加法。

13.8.1.1 运行时语义:求值 (Runtime Semantics: Evaluation)

AdditiveExpression : AdditiveExpression + MultiplicativeExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(AdditiveExpression, +, MultiplicativeExpression)。

13.8.2 减法运算符 (The Subtraction Operator -)

Note

- 运算符执行减法,产生操作数之差。

13.8.2.1 运行时语义:求值 (Runtime Semantics: Evaluation)

AdditiveExpression : AdditiveExpression - MultiplicativeExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(AdditiveExpression, -, MultiplicativeExpression)。

13.9 位移运算符 (Bitwise Shift Operators)

语法 (Syntax)

ShiftExpression[Yield, Await] : AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] << AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] >> AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] >>> AdditiveExpression[?Yield, ?Await]

13.9.1 左移运算符 (The Left Shift Operator <<)

Note

对左操作数按右操作数指定的位数执行按位左移。

13.9.1.1 运行时语义:求值 (Runtime Semantics: Evaluation)

ShiftExpression : ShiftExpression << AdditiveExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(ShiftExpression, <<, AdditiveExpression)。

13.9.2 带符号右移运算符 (The Signed Right Shift Operator >>)

Note

对左操作数按右操作数指定的位数执行带符号(符号位填充)按位右移。

13.9.2.1 运行时语义:求值 (Runtime Semantics: Evaluation)

ShiftExpression : ShiftExpression >> AdditiveExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(ShiftExpression, >>, AdditiveExpression)。

13.9.3 无符号右移运算符 (The Unsigned Right Shift Operator >>>)

Note

对左操作数按右操作数指定的位数执行零填充按位右移。

13.9.3.1 运行时语义:求值 (Runtime Semantics: Evaluation)

ShiftExpression : ShiftExpression >>> AdditiveExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(ShiftExpression, >>>, AdditiveExpression)。

13.10 关系运算符 (Relational Operators)

Note 1

关系运算符求值结果总是 Boolean,表示操作数之间关系是否成立。

语法 (Syntax)

RelationalExpression[In, Yield, Await] : ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] < ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] > ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] <= ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] >= ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] instanceof ShiftExpression[?Yield, ?Await] [+In] RelationalExpression[+In, ?Yield, ?Await] in ShiftExpression[?Yield, ?Await] [+In] PrivateIdentifier in ShiftExpression[?Yield, ?Await] Note 2

[In] 语法参数用于避免把关系表达式中的 in 运算符与 for 语句中的 in 混淆。

13.10.1 运行时语义:求值 (Runtime Semantics: Evaluation)

RelationalExpression : RelationalExpression < ShiftExpression
  1. lRef 为 ? Evaluation of RelationalExpression
  2. lVal 为 ? GetValue(lRef)。
  3. rRef 为 ? Evaluation of ShiftExpression
  4. rVal 为 ? GetValue(rRef)。
  5. r 为 ? IsLessThan(lVal, rVal, true)。
  6. rundefined,返回 false;否则返回 r
RelationalExpression : RelationalExpression > ShiftExpression
  1. lRef 为 ? Evaluation of RelationalExpression
  2. lVal 为 ? GetValue(lRef)。
  3. rRef 为 ? Evaluation of ShiftExpression
  4. rVal 为 ? GetValue(rRef)。
  5. r 为 ? IsLessThan(rVal, lVal, false)。
  6. rundefined,返回 false;否则返回 r
RelationalExpression : RelationalExpression <= ShiftExpression
  1. lRef 为 ? Evaluation of RelationalExpression
  2. lVal 为 ? GetValue(lRef)。
  3. rRef 为 ? Evaluation of ShiftExpression
  4. rVal 为 ? GetValue(rRef)。
  5. r 为 ? IsLessThan(rVal, lVal, false)。
  6. rtrueundefined,返回 false;否则返回 true
RelationalExpression : RelationalExpression >= ShiftExpression
  1. lRef 为 ? Evaluation of RelationalExpression
  2. lVal 为 ? GetValue(lRef)。
  3. rRef 为 ? Evaluation of ShiftExpression
  4. rVal 为 ? GetValue(rRef)。
  5. r 为 ? IsLessThan(lVal, rVal, true)。
  6. rtrueundefined,返回 false;否则返回 true
RelationalExpression : RelationalExpression instanceof ShiftExpression
  1. lRef 为 ? Evaluation of RelationalExpression
  2. lVal 为 ? GetValue(lRef)。
  3. rRef 为 ? Evaluation of ShiftExpression
  4. rVal 为 ? GetValue(rRef)。
  5. 返回 ? InstanceofOperator(lVal, rVal)。
RelationalExpression : RelationalExpression in ShiftExpression
  1. lRef 为 ? Evaluation of RelationalExpression
  2. lVal 为 ? GetValue(lRef)。
  3. rRef 为 ? Evaluation of ShiftExpression
  4. rVal 为 ? GetValue(rRef)。
  5. rVal 不是 Object,抛出 TypeError 异常。
  6. 返回 ? HasProperty(rVal, ? ToPropertyKey(lVal))。
RelationalExpression : PrivateIdentifier in ShiftExpression
  1. privateIdentifierPrivateIdentifier 的 StringValue。
  2. rRef 为 ? Evaluation of ShiftExpression
  3. rVal 为 ? GetValue(rRef)。
  4. rVal 不是 Object,抛出 TypeError 异常。
  5. privateEnv 为正在运行的执行上下文的 PrivateEnvironment。
  6. 断言:privateEnvnull
  7. privateNameResolvePrivateIdentifier(privateEnv, privateIdentifier)。
  8. PrivateElementFind(rVal, privateName) 非 empty,返回 true
  9. 返回 false

13.10.2 InstanceofOperator ( V, target )

The abstract operation InstanceofOperator takes arguments V (an ECMAScript language value) and target (an ECMAScript language value) and returns 返回一个含 Boolean 的正常完成或一个 throw completion. 实现判定 V 是否为 target 实例的通用算法:若 target 定义 %Symbol.hasInstance% 方法则调用之,否则检查 target"prototype" 属性值是否出现在 V 的原型链上。 It performs the following steps when called:

  1. target 不是 Object,抛出 TypeError 异常。
  2. instOfHandler 为 ? GetMethod(target, %Symbol.hasInstance%)。
  3. instOfHandler 不为 undefined,则
    1. 返回 ToBoolean(? Call(instOfHandler, target, « V »))。
  4. IsCallable(target) 为 false,抛出 TypeError 异常。
  5. 返回 ? OrdinaryHasInstance(target, V)。
Note

步骤 45 兼容早期未使用 %Symbol.hasInstance% 定义 instanceof 语义的版本。若对象未定义或继承该方法,则使用默认语义。

13.11 相等运算符 (Equality Operators)

Note

相等运算符求值结果总是 Boolean,表示两操作数之间命名关系是否成立。

语法 (Syntax)

EqualityExpression[In, Yield, Await] : RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] == RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] != RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] === RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] !== RelationalExpression[?In, ?Yield, ?Await]

13.11.1 运行时语义:求值 (Runtime Semantics: Evaluation)

EqualityExpression : EqualityExpression == RelationalExpression
  1. lRef 为 ? Evaluation of EqualityExpression
  2. lVal 为 ? GetValue(lRef)。
  3. rRef 为 ? Evaluation of RelationalExpression
  4. rVal 为 ? GetValue(rRef)。
  5. 返回 ? IsLooselyEqual(rVal, lVal)。
EqualityExpression : EqualityExpression != RelationalExpression
  1. lRef 为 ? Evaluation of EqualityExpression
  2. lVal 为 ? GetValue(lRef)。
  3. rRef 为 ? Evaluation of RelationalExpression
  4. rVal 为 ? GetValue(rRef)。
  5. r 为 ? IsLooselyEqual(rVal, lVal)。
  6. rtrue,返回 false;否则返回 true
EqualityExpression : EqualityExpression === RelationalExpression
  1. lRef 为 ? Evaluation of EqualityExpression
  2. lVal 为 ? GetValue(lRef)。
  3. rRef 为 ? Evaluation of RelationalExpression
  4. rVal 为 ? GetValue(rRef)。
  5. 返回 IsStrictlyEqual(rVal, lVal)。
EqualityExpression : EqualityExpression !== RelationalExpression
  1. lRef 为 ? Evaluation of EqualityExpression
  2. lVal 为 ? GetValue(lRef)。
  3. rRef 为 ? Evaluation of RelationalExpression
  4. rVal 为 ? GetValue(rRef)。
  5. rIsStrictlyEqual(rVal, lVal)。
  6. rtrue,返回 false;否则返回 true
Note 1

基于上述定义:

  • 可通过 `${a}` == `${b}` 强制字符串比较。
  • 可通过 +a == +b 强制数值比较。
  • 可通过 !a == !b 强制布尔比较。
Note 2

相等运算符保持以下不变式:

  • A != B 等价于 !(A == B)
  • A == B 等价于 B == A,除求值顺序外。
Note 3

相等运算符并非总是传递。例如可能存在两个不同的 String 对象,各表示相同的字符串值;它们分别与该字符串字面值 ==true,但二者彼此 ==false。示例:

  • new String("a") == "a""a" == new String("a") 均为 true
  • new String("a") == new String("a")false
Note 4

字符串比较对代码单元序列执行简单相等测试,不使用 Unicode 规范中更复杂的语义性字符/字符串等价与排序定义。故按 Unicode 标准正则等价的字符串值可能测试为不等;此算法假设两者已规范化。

13.12 二元按位运算符 (Binary Bitwise Operators)

语法 (Syntax)

BitwiseANDExpression[In, Yield, Await] : EqualityExpression[?In, ?Yield, ?Await] BitwiseANDExpression[?In, ?Yield, ?Await] & EqualityExpression[?In, ?Yield, ?Await] BitwiseXORExpression[In, Yield, Await] : BitwiseANDExpression[?In, ?Yield, ?Await] BitwiseXORExpression[?In, ?Yield, ?Await] ^ BitwiseANDExpression[?In, ?Yield, ?Await] BitwiseORExpression[In, Yield, Await] : BitwiseXORExpression[?In, ?Yield, ?Await] BitwiseORExpression[?In, ?Yield, ?Await] | BitwiseXORExpression[?In, ?Yield, ?Await]

13.12.1 运行时语义:求值 (Runtime Semantics: Evaluation)

BitwiseANDExpression : BitwiseANDExpression & EqualityExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(BitwiseANDExpression, &, EqualityExpression)。
BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(BitwiseXORExpression, ^, BitwiseANDExpression)。
BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(BitwiseORExpression, |, BitwiseXORExpression)。

13.13 二元逻辑运算符 (Binary Logical Operators)

语法 (Syntax)

LogicalANDExpression[In, Yield, Await] : BitwiseORExpression[?In, ?Yield, ?Await] LogicalANDExpression[?In, ?Yield, ?Await] && BitwiseORExpression[?In, ?Yield, ?Await] LogicalORExpression[In, Yield, Await] : LogicalANDExpression[?In, ?Yield, ?Await] LogicalORExpression[?In, ?Yield, ?Await] || LogicalANDExpression[?In, ?Yield, ?Await] CoalesceExpression[In, Yield, Await] : CoalesceExpressionHead[?In, ?Yield, ?Await] ?? BitwiseORExpression[?In, ?Yield, ?Await] CoalesceExpressionHead[In, Yield, Await] : CoalesceExpression[?In, ?Yield, ?Await] BitwiseORExpression[?In, ?Yield, ?Await] ShortCircuitExpression[In, Yield, Await] : LogicalORExpression[?In, ?Yield, ?Await] CoalesceExpression[?In, ?Yield, ?Await] Note

&&|| 运算符产生的值不一定是 Boolean,而总是两个操作数表达式之一的值。

13.13.1 运行时语义:求值 (Runtime Semantics: Evaluation)

LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
  1. lRef 为 ? Evaluation of LogicalANDExpression
  2. lVal 为 ? GetValue(lRef)。
  3. ToBoolean(lVal) 为 false,返回 lVal
  4. rRef 为 ? Evaluation of BitwiseORExpression
  5. 返回 ? GetValue(rRef)。
LogicalORExpression : LogicalORExpression || LogicalANDExpression
  1. lRef 为 ? Evaluation of LogicalORExpression
  2. lVal 为 ? GetValue(lRef)。
  3. ToBoolean(lVal) 为 true,返回 lVal
  4. rRef 为 ? Evaluation of LogicalANDExpression
  5. 返回 ? GetValue(rRef)。
CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression
  1. lRef 为 ? Evaluation of CoalesceExpressionHead
  2. lVal 为 ? GetValue(lRef)。
  3. lValundefinednull,则
    1. rRef 为 ? Evaluation of BitwiseORExpression
    2. 返回 ? GetValue(rRef)。
  4. 否则,
    1. 返回 lVal

13.14 条件运算符 ( ? : ) (Conditional Operator ( ? : ))

语法 (Syntax)

ConditionalExpression[In, Yield, Await] : ShortCircuitExpression[?In, ?Yield, ?Await] ShortCircuitExpression[?In, ?Yield, ?Await] ? AssignmentExpression[+In, ?Yield, ?Await] : AssignmentExpression[?In, ?Yield, ?Await] Note

ECMAScript 中 ConditionalExpression 的语法与 C 和 Java 略有不同;后两者允许第二个子表达式是 Expression,但限制第三个表达式是 ConditionalExpression。ECMAScript 这样设计的动机是允许条件两支任一侧控制一个赋值表达式,并移除“逗号表达式作为中间表达式”这一令人困惑且基本无用的情形。

13.14.1 运行时语义:求值 (Runtime Semantics: Evaluation)

ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
  1. lRef 为 ? Evaluation of ShortCircuitExpression
  2. lValToBoolean(? GetValue(lRef))。
  3. lValtrue,则
    1. trueRef 为 ? Evaluation of 第一个 AssignmentExpression
    2. 返回 ? GetValue(trueRef)。
  4. 否则,
    1. falseRef 为 ? Evaluation of 第二个 AssignmentExpression
    2. 返回 ? GetValue(falseRef)。

13.15 赋值运算符 (Assignment Operators)

语法 (Syntax)

AssignmentExpression[In, Yield, Await] : ConditionalExpression[?In, ?Yield, ?Await] [+Yield] YieldExpression[?In, ?Await] ArrowFunction[?In, ?Yield, ?Await] AsyncArrowFunction[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] = AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] AssignmentOperator AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] &&= AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] ||= AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] ??= AssignmentExpression[?In, ?Yield, ?Await] AssignmentOperator : one of *= /= %= += -= <<= >>= >>>= &= ^= |= **=

13.15.1 静态语义:早期错误 (Static Semantics: Early Errors)

AssignmentExpression : LeftHandSideExpression = AssignmentExpression AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression

13.15.2 运行时语义:求值 (Runtime Semantics: Evaluation)

AssignmentExpression : LeftHandSideExpression = AssignmentExpression
  1. LeftHandSideExpression 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. lRef 为 ? Evaluation of LeftHandSideExpression
    2. LeftHandSideExpression 的 AssignmentTargetType 为 web-compat,抛出 ReferenceError 异常。
    3. 若 IsAnonymousFunctionDefinition(AssignmentExpression) 为 true 且 IsIdentifierRef of LeftHandSideExpressiontrue,则
      1. lhsLeftHandSideExpression 的 StringValue。
      2. rVal 为 ? NamedEvaluation of AssignmentExpression,参数 lhs
    4. 否则,
      1. rRef 为 ? Evaluation of AssignmentExpression
      2. rVal 为 ? GetValue(rRef)。
    5. 执行 ? PutValue(lRef, rVal)。
    6. 返回 rVal
  2. assignmentPatternLeftHandSideExpression 覆盖AssignmentPattern
  3. rRef 为 ? Evaluation of AssignmentExpression
  4. rVal 为 ? GetValue(rRef)。
  5. 执行 ? DestructuringAssignmentEvaluation of assignmentPattern,参数 rVal
  6. 返回 rVal
AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression
  1. lRef 为 ? Evaluation of LeftHandSideExpression
  2. LeftHandSideExpression 的 AssignmentTargetType 为 web-compat,抛出 ReferenceError 异常。
  3. lVal 为 ? GetValue(lRef)。
  4. rRef 为 ? Evaluation of AssignmentExpression
  5. rVal 为 ? GetValue(rRef)。
  6. assignmentOpTextAssignmentOperator 所匹配的源文本。
  7. opText 为下表中与 assignmentOpText 关联的 Unicode 码点序列:
    assignmentOpText opText
    **= **
    *= *
    /= /
    %= %
    += +
    -= -
    <<= <<
    >>= >>
    >>>= >>>
    &= &
    ^= ^
    |= |
  8. r 为 ? ApplyStringOrNumericBinaryOperator(lVal, opText, rVal)。
  9. 执行 ? PutValue(lRef, r)。
  10. 返回 r
AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
  1. lRef 为 ? Evaluation of LeftHandSideExpression
  2. lVal 为 ? GetValue(lRef)。
  3. ToBoolean(lVal) 为 false,返回 lVal
  4. 若 IsAnonymousFunctionDefinition(AssignmentExpression) 为 true 且 IsIdentifierRef of LeftHandSideExpressiontrue,则
    1. lhsLeftHandSideExpression 的 StringValue。
    2. rVal 为 ? NamedEvaluation of AssignmentExpression,参数 lhs
  5. 否则,
    1. rRef 为 ? Evaluation of AssignmentExpression
    2. rVal 为 ? GetValue(rRef)。
  6. 执行 ? PutValue(lRef, rVal)。
  7. 返回 rVal
AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
  1. lRef 为 ? Evaluation of LeftHandSideExpression
  2. lVal 为 ? GetValue(lRef)。
  3. ToBoolean(lVal) 为 true,返回 lVal
  4. 若 IsAnonymousFunctionDefinition(AssignmentExpression) 为 true 且 IsIdentifierRef of LeftHandSideExpressiontrue,则
    1. lhsLeftHandSideExpression 的 StringValue。
    2. rVal 为 ? NamedEvaluation of AssignmentExpression,参数 lhs
  5. 否则,
    1. rRef 为 ? Evaluation of AssignmentExpression
    2. rVal 为 ? GetValue(rRef)。
  6. 执行 ? PutValue(lRef, rVal)。
  7. 返回 rVal
AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
  1. lRef 为 ? Evaluation of LeftHandSideExpression
  2. lVal 为 ? GetValue(lRef)。
  3. lVal 既不是 undefined 也不是 null,返回 lVal
  4. 若 IsAnonymousFunctionDefinition(AssignmentExpression) 为 true 且 IsIdentifierRef of LeftHandSideExpressiontrue,则
    1. lhsLeftHandSideExpression 的 StringValue。
    2. rVal 为 ? NamedEvaluation of AssignmentExpression,参数 lhs
  5. 否则,
    1. rRef 为 ? Evaluation of AssignmentExpression
    2. rVal 为 ? GetValue(rRef)。
  6. 执行 ? PutValue(lRef, rVal)。
  7. 返回 rVal
Note

当该表达式出现在严格模式代码中时,若步骤 1.e3222 中的 lRef 是不可解析引用,则抛出 ReferenceError。另外,若步骤 9666 中的 lRef 引用一个 { [[Writable]]: false } 的数据属性[[Set]]undefined访问器属性,或对象中不存在且该对象的 IsExtensible 结果为 false 的属性,则抛出 TypeError

13.15.3 ApplyStringOrNumericBinaryOperator ( lVal, opText, rVal )

The abstract operation ApplyStringOrNumericBinaryOperator takes arguments lVal (一个 ECMAScript 语言值), opText (**, *, /, %, +, -, <<, >>, >>>, &, ^, 或 |), and rVal (一个 ECMAScript 语言值) and returns 返回一个含 String、BigInt 或 Number 的正常完成,或一个 throw completion. It performs the following steps when called:

  1. opText+,则
    1. lPrim 为 ? ToPrimitive(lVal)。
    2. rPrim 为 ? ToPrimitive(rVal)。
    3. lPrim 为 String 或 rPrim 为 String,则
      1. lStr 为 ? ToString(lPrim)。
      2. rStr 为 ? ToString(rPrim)。
      3. 返回 lStrrStr 的字符串连接。
    4. lVallPrim
    5. rValrPrim
  2. 注:此时必为数值运算。
  3. lNum 为 ? ToNumeric(lVal)。
  4. rNum 为 ? ToNumeric(rVal)。
  5. SameType(lNum, rNum) 为 false,抛出 TypeError 异常。
  6. lNum 为 BigInt,则
    1. opText**,返回 ? BigInt::exponentiate(lNum, rNum)。
    2. opText/,返回 ? BigInt::divide(lNum, rNum)。
    3. opText%,返回 ? BigInt::remainder(lNum, rNum)。
    4. opText>>>,返回 ? BigInt::unsignedRightShift(lNum, rNum)。
    5. operation 为下表中与 opText 关联的抽象操作
      opText operation
      * BigInt::multiply
      + BigInt::add
      - BigInt::subtract
      << BigInt::leftShift
      >> BigInt::signedRightShift
      & BigInt::bitwiseAND
      ^ BigInt::bitwiseXOR
      | BigInt::bitwiseOR
  7. 否则,
    1. 断言:lNum 为 Number。
    2. operation 为下表中与 opText 关联的抽象操作
      opText operation
      ** Number::exponentiate
      * Number::multiply
      / Number::divide
      % Number::remainder
      + Number::add
      - Number::subtract
      << Number::leftShift
      >> Number::signedRightShift
      >>> Number::unsignedRightShift
      & Number::bitwiseAND
      ^ Number::bitwiseXOR
      | Number::bitwiseOR
  8. 返回 operation(lNum, rNum)。
Note 1

步骤 1.a1.b 中对 ToPrimitive 的调用不提供 hint。除 Date 外的所有标准对象在缺省 hint 时按 number 处理;Date 按 string 处理;特异对象可按其他方式处理。

Note 2

步骤 1.cIsLessThan 算法的步骤 3 不同:它使用逻辑“或”而不是逻辑“与”。

13.15.4 EvaluateStringOrNumericBinaryExpression ( leftOperand, opText, rightOperand )

The abstract operation EvaluateStringOrNumericBinaryExpression takes arguments leftOperand (一个 Parse Node), opText (一个 Unicode 码点序列), and rightOperand (一个 Parse Node) and returns 返回一个含 String、BigInt 或 Number 的正常完成,或一个突然完成. It performs the following steps when called:

  1. lRef 为 ? Evaluation of leftOperand
  2. lVal 为 ? GetValue(lRef)。
  3. rRef 为 ? Evaluation of rightOperand
  4. rVal 为 ? GetValue(rRef)。
  5. 返回 ? ApplyStringOrNumericBinaryOperator(lVal, opText, rVal)。

13.15.5 解构赋值 (Destructuring Assignment)

补充语法 (Supplemental Syntax)

在处理产生式实例:
AssignmentExpression : LeftHandSideExpression = AssignmentExpression
时,对 LeftHandSideExpression 的解释通过下列语法细化:

AssignmentPattern[Yield, Await] : ObjectAssignmentPattern[?Yield, ?Await] ArrayAssignmentPattern[?Yield, ?Await] ObjectAssignmentPattern[Yield, Await] : { } { AssignmentRestProperty[?Yield, ?Await] } { AssignmentPropertyList[?Yield, ?Await] } { AssignmentPropertyList[?Yield, ?Await] , AssignmentRestProperty[?Yield, ?Await]opt } ArrayAssignmentPattern[Yield, Await] : [ Elisionopt AssignmentRestElement[?Yield, ?Await]opt ] [ AssignmentElementList[?Yield, ?Await] ] [ AssignmentElementList[?Yield, ?Await] , Elisionopt AssignmentRestElement[?Yield, ?Await]opt ] AssignmentRestProperty[Yield, Await] : ... DestructuringAssignmentTarget[?Yield, ?Await] AssignmentPropertyList[Yield, Await] : AssignmentProperty[?Yield, ?Await] AssignmentPropertyList[?Yield, ?Await] , AssignmentProperty[?Yield, ?Await] AssignmentElementList[Yield, Await] : AssignmentElisionElement[?Yield, ?Await] AssignmentElementList[?Yield, ?Await] , AssignmentElisionElement[?Yield, ?Await] AssignmentElisionElement[Yield, Await] : Elisionopt AssignmentElement[?Yield, ?Await] AssignmentProperty[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt PropertyName[?Yield, ?Await] : AssignmentElement[?Yield, ?Await] AssignmentElement[Yield, Await] : DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt AssignmentRestElement[Yield, Await] : ... DestructuringAssignmentTarget[?Yield, ?Await] DestructuringAssignmentTarget[Yield, Await] : LeftHandSideExpression[?Yield, ?Await]

13.15.5.1 静态语义:早期错误 (Static Semantics: Early Errors)

AssignmentProperty : IdentifierReference Initializeropt AssignmentRestProperty : ... DestructuringAssignmentTarget DestructuringAssignmentTarget : LeftHandSideExpression

13.15.5.2 运行时语义:DestructuringAssignmentEvaluation

The syntax-directed operation 运行时语义:DestructuringAssignmentEvaluation takes argument value (一个 ECMAScript 语言值) and returns 返回一个含 unused正常完成或一个突然完成. It is defined piecewise over the following productions:

ObjectAssignmentPattern : { }
  1. 执行 ? RequireObjectCoercible(value)。
  2. 返回 unused
ObjectAssignmentPattern : { AssignmentPropertyList } { AssignmentPropertyList , }
  1. 执行 ? RequireObjectCoercible(value)。
  2. 执行 ? PropertyDestructuringAssignmentEvaluation of AssignmentPropertyList,参数 value
  3. 返回 unused
ObjectAssignmentPattern : { AssignmentRestProperty }
  1. 执行 ? RequireObjectCoercible(value)。
  2. excludedNames 为新空列表。
  3. 返回 ? RestDestructuringAssignmentEvaluation of AssignmentRestProperty,参数 valueexcludedNames
ObjectAssignmentPattern : { AssignmentPropertyList , AssignmentRestProperty }
  1. 执行 ? RequireObjectCoercible(value)。
  2. excludedNames 为 ? PropertyDestructuringAssignmentEvaluation of AssignmentPropertyList,参数 value
  3. 返回 ? RestDestructuringAssignmentEvaluation of AssignmentRestProperty,参数 valueexcludedNames
ArrayAssignmentPattern : [ ]
  1. iteratorRecord 为 ? GetIterator(value, sync)。
  2. 返回 ? IteratorClose(iteratorRecord, NormalCompletion(unused))。
ArrayAssignmentPattern : [ Elision ]
  1. iteratorRecord 为 ? GetIterator(value, sync)。
  2. resultCompletion(IteratorDestructuringAssignmentEvaluation of Elision,参数 iteratorRecord)。
  3. iteratorRecord.[[Done]]false,返回 ? IteratorClose(iteratorRecord, result)。
  4. 返回 result
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
  1. iteratorRecord 为 ? GetIterator(value, sync)。
  2. 若存在 Elision,则
    1. statusCompletion(IteratorDestructuringAssignmentEvaluation of Elision,参数 iteratorRecord)。
    2. status 是突然完成,则
      1. 断言:iteratorRecord.[[Done]]true
      2. 返回 ? status
  3. resultCompletion(IteratorDestructuringAssignmentEvaluation of AssignmentRestElement,参数 iteratorRecord)。
  4. iteratorRecord.[[Done]]false,返回 ? IteratorClose(iteratorRecord, result)。
  5. 返回 result
ArrayAssignmentPattern : [ AssignmentElementList ]
  1. iteratorRecord 为 ? GetIterator(value, sync)。
  2. resultCompletion(IteratorDestructuringAssignmentEvaluation of AssignmentElementList,参数 iteratorRecord)。
  3. iteratorRecord.[[Done]]false,返回 ? IteratorClose(iteratorRecord, result)。
  4. 返回 result
ArrayAssignmentPattern : [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
  1. iteratorRecord 为 ? GetIterator(value, sync)。
  2. statusCompletion(IteratorDestructuringAssignmentEvaluation of AssignmentElementList,参数 iteratorRecord)。
  3. status 是突然完成,则
    1. iteratorRecord.[[Done]]false,返回 ? IteratorClose(iteratorRecord, status)。
    2. 返回 ? status
  4. 若存在 Elision,则
    1. statusCompletion(IteratorDestructuringAssignmentEvaluation of Elision,参数 iteratorRecord)。
    2. status 是突然完成,则
      1. 断言:iteratorRecord.[[Done]]true
      2. 返回 ? status
  5. 若存在 AssignmentRestElement,则
    1. statusCompletion(IteratorDestructuringAssignmentEvaluation of AssignmentRestElement,参数 iteratorRecord)。
  6. iteratorRecord.[[Done]]false,返回 ? IteratorClose(iteratorRecord, status)。
  7. 返回 ? status

13.15.5.3 运行时语义:PropertyDestructuringAssignmentEvaluation

The syntax-directed operation 运行时语义:PropertyDestructuringAssignmentEvaluation takes argument value (一个 ECMAScript 语言值) and returns 返回一个含属性键列表的正常完成或一个突然完成. 收集所有被解构的属性键列表。 It is defined piecewise over the following productions:

AssignmentPropertyList : AssignmentPropertyList , AssignmentProperty
  1. propertyNames 为 ? PropertyDestructuringAssignmentEvaluation of AssignmentPropertyList,参数 value
  2. nextNames 为 ? PropertyDestructuringAssignmentEvaluation of AssignmentProperty,参数 value
  3. 返回 propertyNamesnextNames 的列表连接。
AssignmentProperty : IdentifierReference Initializeropt
  1. PIdentifierReference 的 StringValue。
  2. lRef 为 ? ResolveBinding(P)。
  3. v 为 ? GetV(value, P)。
  4. 若存在 Initializervundefined,则
    1. 若 IsAnonymousFunctionDefinition(Initializer) 为 true,则
      1. v 为 ? NamedEvaluation of Initializer,参数 P
    2. 否则,
      1. defaultValue 为 ? Evaluation of Initializer
      2. v 为 ? GetValue(defaultValue)。
  5. 执行 ? PutValue(lRef, v)。
  6. 返回 « P »。
AssignmentProperty : PropertyName : AssignmentElement
  1. name 为 ? Evaluation of PropertyName
  2. 执行 ? KeyedDestructuringAssignmentEvaluation of AssignmentElement,参数 valuename
  3. 返回 « name »。

13.15.5.4 运行时语义:RestDestructuringAssignmentEvaluation

The syntax-directed operation 运行时语义:RestDestructuringAssignmentEvaluation takes arguments value (一个 ECMAScript 语言值) and excludedNames (一个属性键列表) and returns 返回一个含 unused正常完成或一个突然完成. It is defined piecewise over the following productions:

AssignmentRestProperty : ... DestructuringAssignmentTarget
  1. lRef 为 ? Evaluation of DestructuringAssignmentTarget
  2. restObjOrdinaryObjectCreate(%Object.prototype%)。
  3. 执行 ? CopyDataProperties(restObj, value, excludedNames)。
  4. 返回 ? PutValue(lRef, restObj)。

13.15.5.5 运行时语义:IteratorDestructuringAssignmentEvaluation

The syntax-directed operation 运行时语义:IteratorDestructuringAssignmentEvaluation takes argument iteratorRecord (一个 Iterator Record) and returns 返回一个含 unused正常完成或一个突然完成. It is defined piecewise over the following productions:

AssignmentElementList : AssignmentElisionElement
  1. 返回 ? IteratorDestructuringAssignmentEvaluation of AssignmentElisionElement,参数 iteratorRecord
AssignmentElementList : AssignmentElementList , AssignmentElisionElement
  1. 执行 ? IteratorDestructuringAssignmentEvaluation of AssignmentElementList,参数 iteratorRecord
  2. 返回 ? IteratorDestructuringAssignmentEvaluation of AssignmentElisionElement,参数 iteratorRecord
AssignmentElisionElement : AssignmentElement
  1. 返回 ? IteratorDestructuringAssignmentEvaluation of AssignmentElement,参数 iteratorRecord
AssignmentElisionElement : Elision AssignmentElement
  1. 执行 ? IteratorDestructuringAssignmentEvaluation of Elision,参数 iteratorRecord
  2. 返回 ? IteratorDestructuringAssignmentEvaluation of AssignmentElement,参数 iteratorRecord
Elision : ,
  1. iteratorRecord.[[Done]]false,则
    1. 执行 ? IteratorStep(iteratorRecord)。
  2. 返回 unused
Elision : Elision ,
  1. 执行 ? IteratorDestructuringAssignmentEvaluation of Elision,参数 iteratorRecord
  2. iteratorRecord.[[Done]]false,则
    1. 执行 ? IteratorStep(iteratorRecord)。
  3. 返回 unused
AssignmentElement : DestructuringAssignmentTarget Initializeropt
  1. DestructuringAssignmentTarget 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. lRef 为 ? Evaluation of DestructuringAssignmentTarget
  2. valueundefined
  3. iteratorRecord.[[Done]]false,则
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. nextdone,则
      1. valuenext
  4. 若存在 Initializervalueundefined,则
    1. 若 IsAnonymousFunctionDefinition(Initializer) 为 true 且 IsIdentifierRef of DestructuringAssignmentTargettrue,则
      1. targetDestructuringAssignmentTarget 的 StringValue。
      2. v 为 ? NamedEvaluation of Initializer,参数 target
    2. 否则,
      1. defaultValue 为 ? Evaluation of Initializer
      2. v 为 ? GetValue(defaultValue)。
  5. 否则,
    1. vvalue
  6. DestructuringAssignmentTargetObjectLiteralArrayLiteral,则
    1. nestedAssignmentPatternDestructuringAssignmentTarget 覆盖AssignmentPattern
    2. 返回 ? DestructuringAssignmentEvaluation of nestedAssignmentPattern,参数 v
  7. 返回 ? PutValue(lRef, v)。
Note

通过在访问迭代器或求 Initializer 之前先求值非解构模式的 DestructuringAssignmentTarget,保持自左向右的求值顺序。

AssignmentRestElement : ... DestructuringAssignmentTarget
  1. DestructuringAssignmentTarget 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. lRef 为 ? Evaluation of DestructuringAssignmentTarget
  2. A 为 ! ArrayCreate(0)。
  3. n 为 0。
  4. iteratorRecord.[[Done]]false 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. nextdone,则
      1. 执行 ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), next)。
      2. nn + 1。
  5. DestructuringAssignmentTarget 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. 返回 ? PutValue(lRef, A)。
  6. nestedAssignmentPatternDestructuringAssignmentTarget 覆盖AssignmentPattern
  7. 返回 ? DestructuringAssignmentEvaluation of nestedAssignmentPattern,参数 A

13.15.5.6 运行时语义:KeyedDestructuringAssignmentEvaluation

The syntax-directed operation 运行时语义:KeyedDestructuringAssignmentEvaluation takes arguments value (一个 ECMAScript 语言值) and propertyName (一个属性键) and returns 返回一个含 unused正常完成或一个突然完成. It is defined piecewise over the following productions:

AssignmentElement : DestructuringAssignmentTarget Initializeropt
  1. DestructuringAssignmentTarget 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. lRef 为 ? Evaluation of DestructuringAssignmentTarget
  2. v 为 ? GetV(value, propertyName)。
  3. 若存在 Initializervundefined,则
    1. 若 IsAnonymousFunctionDefinition(Initializer) 为 true 且 IsIdentifierRef of DestructuringAssignmentTargettrue,则
      1. targetDestructuringAssignmentTarget 的 StringValue。
      2. rhsValue 为 ? NamedEvaluation of Initializer,参数 target
    2. 否则,
      1. defaultValue 为 ? Evaluation of Initializer
      2. rhsValue 为 ? GetValue(defaultValue)。
  4. 否则,
    1. rhsValuev
  5. DestructuringAssignmentTargetObjectLiteralArrayLiteral,则
    1. assignmentPatternDestructuringAssignmentTarget 覆盖AssignmentPattern
    2. 返回 ? DestructuringAssignmentEvaluation of assignmentPattern,参数 rhsValue
  6. 返回 ? PutValue(lRef, rhsValue)。

13.16 逗号运算符 ( , )

语法 (Syntax)

Expression[In, Yield, Await] : AssignmentExpression[?In, ?Yield, ?Await] Expression[?In, ?Yield, ?Await] , AssignmentExpression[?In, ?Yield, ?Await]

13.16.1 运行时语义:求值 (Runtime Semantics: Evaluation)

Expression : Expression , AssignmentExpression
  1. lRef 为 ? Evaluation of Expression
  2. 执行 ? GetValue(lRef)。
  3. rRef 为 ? Evaluation of AssignmentExpression
  4. 返回 ? GetValue(rRef)。
Note

必须调用 GetValue(即使其结果未被使用),因为它可能具有可观察的副作用。

14 ECMAScript 语言:语句与声明 (ECMAScript Language: Statements and Declarations)

语法 (Syntax)

Statement[Yield, Await, Return] : BlockStatement[?Yield, ?Await, ?Return] VariableStatement[?Yield, ?Await] EmptyStatement ExpressionStatement[?Yield, ?Await] IfStatement[?Yield, ?Await, ?Return] BreakableStatement[?Yield, ?Await, ?Return] ContinueStatement[?Yield, ?Await] BreakStatement[?Yield, ?Await] [+Return] ReturnStatement[?Yield, ?Await] WithStatement[?Yield, ?Await, ?Return] LabelledStatement[?Yield, ?Await, ?Return] ThrowStatement[?Yield, ?Await] TryStatement[?Yield, ?Await, ?Return] DebuggerStatement Declaration[Yield, Await] : HoistableDeclaration[?Yield, ?Await, ~Default] ClassDeclaration[?Yield, ?Await, ~Default] LexicalDeclaration[+In, ?Yield, ?Await] HoistableDeclaration[Yield, Await, Default] : FunctionDeclaration[?Yield, ?Await, ?Default] GeneratorDeclaration[?Yield, ?Await, ?Default] AsyncFunctionDeclaration[?Yield, ?Await, ?Default] AsyncGeneratorDeclaration[?Yield, ?Await, ?Default] BreakableStatement[Yield, Await, Return] : IterationStatement[?Yield, ?Await, ?Return] SwitchStatement[?Yield, ?Await, ?Return]

14.1 语句语义 (Statement Semantics)

14.1.1 运行时语义:求值 (Runtime Semantics: Evaluation)

HoistableDeclaration : GeneratorDeclaration AsyncFunctionDeclaration AsyncGeneratorDeclaration
  1. 返回 empty.
HoistableDeclaration : FunctionDeclaration
  1. 返回 ? Evaluation of FunctionDeclaration.
BreakableStatement : IterationStatement SwitchStatement
  1. newLabelSet 为新空 List
  2. 返回 ? LabelledEvaluation of 此 BreakableStatement,参数 newLabelSet

14.2 块 (Block)

语法 (Syntax)

BlockStatement[Yield, Await, Return] : Block[?Yield, ?Await, ?Return] Block[Yield, Await, Return] : { StatementList[?Yield, ?Await, ?Return]opt } StatementList[Yield, Await, Return] : StatementListItem[?Yield, ?Await, ?Return] StatementList[?Yield, ?Await, ?Return] StatementListItem[?Yield, ?Await, ?Return] StatementListItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] Declaration[?Yield, ?Await]

14.2.1 静态语义:早期错误 (Static Semantics: Early Errors)

Block : { StatementList }
  • StatementList 的 LexicallyDeclaredNames 含有重复条目则为语法错误;除非宿主是 web 浏览器或支持 块级函数声明 Web 历史兼容语义 且以下两条件同时为真:

    • IsStrict(this production) 为 false
    • 重复条目仅由 FunctionDeclarations 绑定。
  • StatementList 的 LexicallyDeclaredNames 中任一元素也出现在其 VarDeclaredNames 中,则为语法错误。

14.2.2 运行时语义:求值 (Runtime Semantics: Evaluation)

Block : { }
  1. 返回 empty
Block : { StatementList }
  1. oldEnv 为当前执行上下文的 LexicalEnvironment。
  2. blockEnvNewDeclarativeEnvironment(oldEnv)。
  3. 执行 BlockDeclarationInstantiation(StatementList, blockEnv)。
  4. 将当前执行上下文的 LexicalEnvironment 设为 blockEnv
  5. blockValueCompletion(Evaluation of StatementList)。
  6. 将当前执行上下文的 LexicalEnvironment 设回 oldEnv
  7. 返回 ? blockValue
Note 1

无论控制如何离开 Block,LexicalEnvironment 均会恢复到之前状态。

StatementList : StatementList StatementListItem
  1. sl 为 ? Evaluation of StatementList
  2. sCompletion(Evaluation of StatementListItem)。
  3. 返回 ? UpdateEmpty(s, sl)。
Note 2

StatementList 的值是其中最后一个产生值的项。例如下列对 eval 的调用都返回 1:

eval("1;;;;;")
eval("1;{}")
eval("1;var a;")

14.2.3 BlockDeclarationInstantiation ( code, env )

The abstract operation BlockDeclarationInstantiation takes arguments code (一个 Parse Node) and env (一个 Declarative Environment Record) and returns unused. code 是块主体对应的 Parse Node。env 是要在其中创建绑定的 Environment Record

Note

当求值一个 BlockCaseBlock 时会创建新的 Declarative Environment Record,并为块内每个块级变量、常量、函数、类实例化绑定。

调用时执行以下步骤:

  1. declarationscode 的 LexicallyScopedDeclarations。
  2. privateEnv 为当前执行上下文的 PrivateEnvironment。
  3. declarations 中每个元素 d
    1. d 的 BoundNames 每个元素 dn
      1. 若 IsConstantDeclaration of dtrue,则
        1. 执行 ! env.CreateImmutableBinding(dn, true)。
      2. 否则,
        1. Normative Optional
          宿主是 web 浏览器或支持 块级函数声明 Web 历史兼容语义,则
          1. 若 ! env.HasBinding(dn) 为 false,执行 ! env.CreateMutableBinding(dn, false)。
        2. 否则,
          1. 执行 ! env.CreateMutableBinding(dn, false)。
    2. dFunctionDeclarationGeneratorDeclarationAsyncFunctionDeclarationAsyncGeneratorDeclaration,则
      1. fnd 的唯一 BoundName。
      2. fo 为 InstantiateFunctionObject of d,参数 envprivateEnv
      3. Normative Optional
        宿主是 web 浏览器或支持 块级函数声明 Web 历史兼容语义,则
        1. envfn 的绑定是未初始化,执行 ! env.InitializeBinding(fn, fo)。
        2. 否则,
          1. 断言:dFunctionDeclaration
          2. 执行 ! env.SetMutableBinding(fn, fo, false)。
      4. 否则,
        1. 执行 ! env.InitializeBinding(fn, fo)。
  4. 返回 unused

14.3 声明与变量语句 (Declarations and the Variable Statement)

14.3.1 Let 与 Const 声明 (Let and Const Declarations)

Note

letconst 声明的变量作用域为当前执行上下文的 LexicalEnvironment。变量在其包含的 Environment Record 实例化时创建,但在其 LexicalBinding 求值前不可访问。带 InitializerLexicalBinding 其变量在求值时(而非创建时)赋值为 InitializerAssignmentExpression 结果。let 声明中无 InitializerLexicalBinding 在求值时变量被赋值 undefined

语法 (Syntax)

LexicalDeclaration[In, Yield, Await] : LetOrConst BindingList[?In, ?Yield, ?Await] ; LetOrConst : let const BindingList[In, Yield, Await] : LexicalBinding[?In, ?Yield, ?Await] BindingList[?In, ?Yield, ?Await] , LexicalBinding[?In, ?Yield, ?Await] LexicalBinding[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]

14.3.1.1 静态语义:早期错误 (Static Semantics: Early Errors)

LexicalDeclaration : LetOrConst BindingList ;
  • BindingList 的 BoundNames 含 "let",语法错误。
  • BindingList 的 BoundNames 含重复条目,语法错误。
LexicalBinding : BindingIdentifier Initializeropt

14.3.1.2 运行时语义:求值 (Runtime Semantics: Evaluation)

LexicalDeclaration : LetOrConst BindingList ;
  1. 执行 ? Evaluation of BindingList
  2. 返回 empty
BindingList : BindingList , LexicalBinding
  1. 执行 ? Evaluation of BindingList
  2. 返回 ? Evaluation of LexicalBinding
LexicalBinding : BindingIdentifier
  1. lhs 为 ! ResolveBinding(StringValue of BindingIdentifier)。
  2. 执行 ! InitializeReferencedBinding(lhs, undefined)。
  3. 返回 empty
Note

静态语义确保此形式不会出现在 const 声明中。

LexicalBinding : BindingIdentifier Initializer
  1. bindingIdBindingIdentifier 的 StringValue。
  2. lhs 为 ! ResolveBinding(bindingId)。
  3. 若 IsAnonymousFunctionDefinition(Initializer) 为 true,则
    1. value 为 ? NamedEvaluation of Initializer,参数 bindingId
  4. 否则,
    1. rhs 为 ? Evaluation of Initializer
    2. value 为 ? GetValue(rhs)。
  5. 执行 ! InitializeReferencedBinding(lhs, value)。
  6. 返回 empty
LexicalBinding : BindingPattern Initializer
  1. rhs 为 ? Evaluation of Initializer
  2. value 为 ? GetValue(rhs)。
  3. env 为当前执行上下文的 LexicalEnvironment。
  4. 返回 ? BindingInitialization of BindingPattern,参数 valueenv

14.3.2 变量语句 (Variable Statement)

Note

var 声明的变量作用域为当前执行上下文的 VariableEnvironment。此类变量在其环境记录实例化时创建并初始化为 undefined。在同一 VariableEnvironment 作用域中,相同 BindingIdentifier 可以出现在多个 VariableDeclaration 中,但这些声明共同定义一个变量。带 InitializerVariableDeclaration 在执行时赋值,而非创建时。

语法 (Syntax)

VariableStatement[Yield, Await] : var VariableDeclarationList[+In, ?Yield, ?Await] ; VariableDeclarationList[In, Yield, Await] : VariableDeclaration[?In, ?Yield, ?Await] VariableDeclarationList[?In, ?Yield, ?Await] , VariableDeclaration[?In, ?Yield, ?Await] VariableDeclaration[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]

14.3.2.1 运行时语义:求值 (Runtime Semantics: Evaluation)

VariableStatement : var VariableDeclarationList ;
  1. 执行 ? Evaluation of VariableDeclarationList
  2. 返回 empty
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. 执行 ? Evaluation of VariableDeclarationList
  2. 返回 ? Evaluation of VariableDeclaration
VariableDeclaration : BindingIdentifier
  1. 返回 empty
VariableDeclaration : BindingIdentifier Initializer
  1. bindingIdBindingIdentifier 的 StringValue。
  2. lhs 为 ? ResolveBinding(bindingId)。
  3. 若 IsAnonymousFunctionDefinition(Initializer) 为 true,则
    1. value 为 ? NamedEvaluation of Initializer,参数 bindingId
  4. 否则,
    1. rhs 为 ? Evaluation of Initializer
    2. value 为 ? GetValue(rhs)。
  5. 执行 ? PutValue(lhs, value)。
  6. 返回 empty
Note

VariableDeclaration 嵌套于 with 语句,且其 BindingIdentifier 与 with 绑定对象的属性同名,则步骤 5 会把 value 赋给该属性,而不是 VariableEnvironment 中的变量绑定。

VariableDeclaration : BindingPattern Initializer
  1. rhs 为 ? Evaluation of Initializer
  2. rVal 为 ? GetValue(rhs)。
  3. 返回 ? BindingInitialization of BindingPattern,参数 rValundefined

14.3.3 解构绑定模式 (Destructuring Binding Patterns)

语法 (Syntax)

BindingPattern[Yield, Await] : ObjectBindingPattern[?Yield, ?Await] ArrayBindingPattern[?Yield, ?Await] ObjectBindingPattern[Yield, Await] : { } { BindingRestProperty[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] , BindingRestProperty[?Yield, ?Await]opt } ArrayBindingPattern[Yield, Await] : [ Elisionopt BindingRestElement[?Yield, ?Await]opt ] [ BindingElementList[?Yield, ?Await] ] [ BindingElementList[?Yield, ?Await] , Elisionopt BindingRestElement[?Yield, ?Await]opt ] BindingRestProperty[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] BindingPropertyList[Yield, Await] : BindingProperty[?Yield, ?Await] BindingPropertyList[?Yield, ?Await] , BindingProperty[?Yield, ?Await] BindingElementList[Yield, Await] : BindingElisionElement[?Yield, ?Await] BindingElementList[?Yield, ?Await] , BindingElisionElement[?Yield, ?Await] BindingElisionElement[Yield, Await] : Elisionopt BindingElement[?Yield, ?Await] BindingProperty[Yield, Await] : SingleNameBinding[?Yield, ?Await] PropertyName[?Yield, ?Await] : BindingElement[?Yield, ?Await] BindingElement[Yield, Await] : SingleNameBinding[?Yield, ?Await] BindingPattern[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt SingleNameBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt BindingRestElement[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] ... BindingPattern[?Yield, ?Await]

14.3.3.1 运行时语义:PropertyBindingInitialization

The syntax-directed operation 运行时语义:PropertyBindingInitialization takes arguments value (一个 ECMAScript 语言值) and environment (一个 Environment Recordundefined) and returns 返回一个含属性键列表的正常完成或一个突然完成. 收集所有绑定的属性名列表。 It is defined piecewise over the following productions:

BindingPropertyList : BindingPropertyList , BindingProperty
  1. boundNames 为 ? PropertyBindingInitialization of BindingPropertyList,参数 valueenvironment
  2. nextNames 为 ? PropertyBindingInitialization of BindingProperty,参数 valueenvironment
  3. 返回列表连接 boundNamesnextNames
BindingProperty : SingleNameBinding
  1. nameSingleNameBinding 的 BoundNames 唯一元素。
  2. 执行 ? KeyedBindingInitialization of SingleNameBinding,参数 valueenvironmentname
  3. 返回 « name »。
BindingProperty : PropertyName : BindingElement
  1. P 为 ? Evaluation of PropertyName
  2. 执行 ? KeyedBindingInitialization of BindingElement,参数 valueenvironmentP
  3. 返回 « P »。

14.3.3.2 运行时语义:RestBindingInitialization

The syntax-directed operation 运行时语义:RestBindingInitialization takes arguments value (一个 ECMAScript 语言值), environment (一个 Environment Recordundefined), and excludedNames (属性键列表) and returns 返回含 unused正常完成或一个突然完成. It is defined piecewise over the following productions:

BindingRestProperty : ... BindingIdentifier
  1. lhs 为 ? ResolveBinding(StringValue of BindingIdentifier, environment)。
  2. restObjOrdinaryObjectCreate(%Object.prototype%)。
  3. 执行 ? CopyDataProperties(restObj, value, excludedNames)。
  4. environmentundefined,返回 ? PutValue(lhs, restObj)。
  5. 返回 ? InitializeReferencedBinding(lhs, restObj)。

14.3.3.3 运行时语义:KeyedBindingInitialization

The syntax-directed operation 运行时语义:KeyedBindingInitialization takes arguments value (一个 ECMAScript 语言值), environment (一个 Environment Recordundefined), and propertyName (一个属性键) and returns 返回含 unused正常完成或一个突然完成.

Note

environmentundefined 表示需使用 PutValue 赋值。这发生在非严格函数形参列表等场景;此时形参绑定已预初始化,以应对重复名称。

It is defined piecewise over the following productions:

BindingElement : BindingPattern Initializeropt
  1. v 为 ? GetV(value, propertyName)。
  2. 若存在 Initializervundefined,则
    1. defaultValue 为 ? Evaluation of Initializer
    2. v 为 ? GetValue(defaultValue)。
  3. 返回 ? BindingInitialization of BindingPattern,参数 venvironment
SingleNameBinding : BindingIdentifier Initializeropt
  1. bindingIdBindingIdentifier 的 StringValue。
  2. lhs 为 ? ResolveBinding(bindingId, environment)。
  3. v 为 ? GetV(value, propertyName)。
  4. 若存在 Initializervundefined,则
    1. 若 IsAnonymousFunctionDefinition(Initializer) 为 true,则
      1. v 为 ? NamedEvaluation of Initializer,参数 bindingId
    2. 否则,
      1. defaultValue 为 ? Evaluation of Initializer
      2. v 为 ? GetValue(defaultValue)。
  5. environmentundefined,返回 ? PutValue(lhs, v)。
  6. 返回 ? InitializeReferencedBinding(lhs, v)。

14.4 空语句 (Empty Statement)

语法 (Syntax)

EmptyStatement : ;

14.4.1 运行时语义:求值 (Runtime Semantics: Evaluation)

EmptyStatement : ;
  1. 返回 empty

14.5 表达式语句 (Expression Statement)

语法 (Syntax)

ExpressionStatement[Yield, Await] : [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }] Expression[+In, ?Yield, ?Await] ; Note

ExpressionStatement 不能以 U+007B { 开始以避免与 Block 歧义;不能以 functionclass 开头以避免与 FunctionDeclarationGeneratorDeclarationClassDeclaration 歧义;不能以 async function 开头避免与 AsyncFunctionDeclarationAsyncGeneratorDeclaration 歧义;不能以 let [ 开头避免与以数组绑定模式为首绑定的 let LexicalDeclaration 歧义。

14.5.1 运行时语义:求值 (Runtime Semantics: Evaluation)

ExpressionStatement : Expression ;
  1. exprRef 为 ? Evaluation of Expression
  2. 返回 ? GetValue(exprRef)。

14.6 if 语句 (The if Statement)

语法 (Syntax)

IfStatement[Yield, Await, Return] : if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else Statement[?Yield, ?Await, ?Return] if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [lookahead ≠ else] Note
lookahead 限制 [lookahead ≠ else] 以传统方式解决“悬挂的 else”问题:当关联的 if 有歧义时,将 else 归属最近的尚未匹配的 if

14.6.1 静态语义:早期错误 (Static Semantics: Early Errors)

IfStatement : if ( Expression ) Statement else Statement
  • 若 IsLabelledFunction(第一个 Statement) 为 true,语法错误。
  • 若 IsLabelledFunction(第二个 Statement) 为 true,语法错误。
IfStatement : if ( Expression ) Statement
  • 若 IsLabelledFunction(Statement) 为 true,语法错误。
Note

仅当实现了 B.3.1 中的扩展时才需应用此规则。

14.6.2 运行时语义:求值 (Runtime Semantics: Evaluation)

IfStatement : if ( Expression ) Statement else Statement
  1. exprRef 为 ? Evaluation of Expression
  2. exprValueToBoolean(? GetValue(exprRef))。
  3. exprValuetrue,则
    1. stmtCompletionCompletion(Evaluation of 第一个 Statement)。
  4. 否则,
    1. stmtCompletionCompletion(Evaluation of 第二个 Statement)。
  5. 返回 ? UpdateEmpty(stmtCompletion, undefined)。
IfStatement : if ( Expression ) Statement
  1. exprRef 为 ? Evaluation of Expression
  2. exprValueToBoolean(? GetValue(exprRef))。
  3. exprValuefalse,返回 undefined
  4. 否则,
    1. stmtCompletionCompletion(Evaluation of Statement)。
    2. 返回 ? UpdateEmpty(stmtCompletion, undefined)。

14.7 迭代语句 (Iteration Statements)

语法 (Syntax)

IterationStatement[Yield, Await, Return] : DoWhileStatement[?Yield, ?Await, ?Return] WhileStatement[?Yield, ?Await, ?Return] ForStatement[?Yield, ?Await, ?Return] ForInOfStatement[?Yield, ?Await, ?Return]

14.7.1 语义 (Semantics)

14.7.1.1 LoopContinues ( completion, labelSet )

The abstract operation LoopContinues takes arguments completion (一个 Completion Record) and labelSet (字符串列表) and returns 一个 Boolean. It performs the following steps when called:

  1. completion 是 normal 完成,返回 true
  2. completion 不是 continue 完成,返回 false
  3. completion.[[Target]]empty,返回 true
  4. labelSetcompletion.[[Target]],返回 true
    1. 返回 false
Note

IterationStatementStatement 部分可以使用 ContinueStatement 开启新一轮迭代。

14.7.1.2 运行时语义:LoopEvaluation

The syntax-directed operation 运行时语义:LoopEvaluation takes argument labelSet (字符串列表) and returns 返回含 ECMAScript 语言值的正常或突然完成. It is defined piecewise over the following productions:

IterationStatement : DoWhileStatement
  1. 返回 ? DoWhileLoopEvaluation of DoWhileStatement,参数 labelSet
IterationStatement : WhileStatement
  1. 返回 ? WhileLoopEvaluation of WhileStatement,参数 labelSet
IterationStatement : ForStatement
  1. 返回 ? ForLoopEvaluation of ForStatement,参数 labelSet
IterationStatement : ForInOfStatement
  1. 返回 ? ForInOfLoopEvaluation of ForInOfStatement,参数 labelSet

14.7.2 do-while 语句 (The do-while Statement)

语法 (Syntax)

DoWhileStatement[Yield, Await, Return] : do Statement[?Yield, ?Await, ?Return] while ( Expression[+In, ?Yield, ?Await] ) ;

14.7.2.1 静态语义:早期错误 (Static Semantics: Early Errors)

DoWhileStatement : do Statement while ( Expression ) ;
  • 若 IsLabelledFunction(Statement) 为 true,语法错误。
Note

仅当实现了 B.3.1 的扩展时需应用此规则。

14.7.2.2 运行时语义:DoWhileLoopEvaluation

The syntax-directed operation 运行时语义:DoWhileLoopEvaluation takes argument labelSet (字符串列表) and returns 正常或突然完成. It is defined piecewise over the following productions:

DoWhileStatement : do Statement while ( Expression ) ;
  1. Vundefined
  2. 重复,
    1. stmtResultCompletion(Evaluation of Statement)。
    2. LoopContinues(stmtResult, labelSet) 为 false,返回 ? UpdateEmpty(stmtResult, V)。
    3. stmtResult.[[Value]]empty,令 V = 该值。
    4. exprRef 为 ? Evaluation of Expression
    5. exprValue 为 ? GetValue(exprRef)。
    6. ToBoolean(exprValue) 为 false,返回 V

14.7.3 while 语句 (The while Statement)

语法 (Syntax)

WhileStatement[Yield, Await, Return] : while ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]

14.7.3.1 静态语义:早期错误 (Static Semantics: Early Errors)

WhileStatement : while ( Expression ) Statement
  • 若 IsLabelledFunction(Statement) 为 true,语法错误。
Note

仅当实现了 B.3.1 扩展时需应用。

14.7.3.2 运行时语义:WhileLoopEvaluation

The syntax-directed operation 运行时语义:WhileLoopEvaluation takes argument labelSet (字符串列表) and returns 正常或突然完成. It is defined piecewise over the following productions:

WhileStatement : while ( Expression ) Statement
  1. Vundefined
  2. 重复,
    1. exprRef 为 ? Evaluation of Expression
    2. exprValue 为 ? GetValue(exprRef)。
    3. ToBoolean(exprValue) 为 false,返回 V
    4. stmtResultCompletion(Evaluation of Statement)。
    5. LoopContinues(stmtResult, labelSet) 为 false,返回 ? UpdateEmpty(stmtResult, V)。
    6. stmtResult.[[Value]]empty,设 V 为该值。

14.7.4 for 语句 (The for Statement)

语法 (Syntax)

ForStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] Expression[~In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( var VariableDeclarationList[~In, ?Yield, ?Await] ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( LexicalDeclaration[~In, ?Yield, ?Await] Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return]

14.7.4.1 静态语义:早期错误 (Static Semantics: Early Errors)

ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  • 若 IsLabelledFunction(Statement) 为 true,语法错误。
Note

仅当实现 B.3.1 扩展时适用。

ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement

14.7.4.2 运行时语义:ForLoopEvaluation

The syntax-directed operation 运行时语义:ForLoopEvaluation takes argument labelSet (字符串列表) and returns 正常或突然完成. It is defined piecewise over the following productions:

ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
  1. 若首个 Expression 存在,令 exprRef 为其求值;执行 ? GetValue(exprRef)。
  2. 若第二个存在,令 test 为该表达式,否则 empty
  3. 若第三个存在,令 increment 为该表达式,否则 empty
  4. 返回 ? ForBodyEvaluation(test, increment, Statement, « », labelSet)。
ForStatement : for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement
  1. 执行 ? Evaluation of VariableDeclarationList
  2. 若首个 Expression 存在令 test = 它,否则 empty
  3. 若第二个 Expression 存在令 increment = 它,否则 empty
  4. 返回 ? ForBodyEvaluation(test, increment, Statement, « », labelSet)。
ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. oldEnv 为当前执行上下文的 LexicalEnvironment。
  2. loopEnvNewDeclarativeEnvironment(oldEnv)。
  3. isConstLexicalDeclaration 的 IsConstantDeclaration。
  4. boundNamesLexicalDeclaration 的 BoundNames。
  5. boundNames 中每个 dn
    1. isConsttrue,执行 ! loopEnv.CreateImmutableBinding(dn, true)。
    2. 否则执行 ! loopEnv.CreateMutableBinding(dn, false)。
  6. 设置当前执行上下文 LexicalEnvironment 为 loopEnv
  7. forDclCompletion(Evaluation of LexicalDeclaration)。
  8. forDcl 为突然完成:
    1. 恢复 LexicalEnvironment 为 oldEnv
    2. 返回 ? forDcl
  9. isConstfalse,令 perIterationLets = boundNames;否则为空列表。
  10. 若首个 Expression 存在令 test 为其,否则 empty
  11. 若第二个 Expression 存在令 increment 为其,否则 empty
  12. bodyResultCompletion(ForBodyEvaluation(test, increment, Statement, perIterationLets, labelSet))。
  13. 恢复 LexicalEnvironment 为 oldEnv
  14. 返回 ? bodyResult

14.7.4.3 ForBodyEvaluation ( test, increment, stmt, perIterationBindings, labelSet )

The abstract operation ForBodyEvaluation takes arguments test (Expression Parse Node 或 empty), increment (Expression Parse Node 或 empty), stmt (Statement Parse Node), perIterationBindings (字符串列表), and labelSet (字符串列表) and returns 正常或突然完成. It performs the following steps when called:

  1. V = undefined
  2. 执行 ? CreatePerIterationEnvironment(perIterationBindings)。
  3. 重复:
    1. testempty
      1. testRef 为 ? Evaluation of test
      2. testValue 为 ? GetValue(testRef)。
      3. ToBoolean(testValue) 为 false,返回 V
    2. resultCompletion(Evaluation of stmt)。
    3. LoopContinues(result, labelSet) 为 false,返回 ? UpdateEmpty(result, V)。
    4. result.[[Value]]empty,设 V 为该值。
    5. 执行 ? CreatePerIterationEnvironment(perIterationBindings)。
    6. incrementempty
      1. incRef 为 ? Evaluation of increment
      2. 执行 ? GetValue(incRef)。

14.7.4.4 CreatePerIterationEnvironment ( perIterationBindings )

The abstract operation CreatePerIterationEnvironment takes argument perIterationBindings (字符串列表) and returns 返回 unused 的正常或抛出完成. It performs the following steps when called:

  1. perIterationBindings 非空:
    1. lastIterationEnv 为当前执行上下文的 LexicalEnvironment。
    2. outerlastIterationEnv.[[OuterEnv]]
    3. 断言 outernull
    4. thisIterationEnvNewDeclarativeEnvironment(outer)。
    5. perIterationBindings 中每个 bn
      1. 执行 ! thisIterationEnv.CreateMutableBinding(bn, false)。
      2. lastValue 为 ? lastIterationEnv.GetBindingValue(bn, true)。
      3. 执行 ! thisIterationEnv.InitializeBinding(bn, lastValue)。
    6. 将当前 LexicalEnvironment 设为 thisIterationEnv
  2. 返回 unused

14.7.5 for-infor-offor-await-of 语句

语法 (Syntax)

ForInOfStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] LeftHandSideExpression[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( [lookahead ≠ let] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] ForDeclaration[Yield, Await] : LetOrConst ForBinding[?Yield, ?Await] ForBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] Note

本节由附录 B.3.5 扩展。

14.7.5.1 静态语义:早期错误 (Static Semantics: Early Errors)

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  • 若 IsLabelledFunction(Statement) 为 true,语法错误。
Note

仅在实现 B.3.1 扩展时适用。

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement ForInOfStatement : for ( ForDeclaration in Expression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  • ForDeclaration 的 BoundNames 含 "let",语法错误。
  • 若 BoundNames 的任一元素出现在 Statement 的 VarDeclaredNames 中,语法错误。
  • 若 BoundNames 含重复条目,语法错误。

14.7.5.2 静态语义:IsDestructuring

The syntax-directed operation 静态语义:IsDestructuring takes no arguments and returns Boolean. It is defined piecewise over the following productions:

MemberExpression : PrimaryExpression
  1. PrimaryExpressionObjectLiteralArrayLiteral,返回 true
  2. 否则返回 false
MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier NewExpression : new NewExpression LeftHandSideExpression : CallExpression OptionalExpression
  1. 返回 false
ForDeclaration : LetOrConst ForBinding
  1. 返回 IsDestructuring of ForBinding
ForBinding : BindingIdentifier
  1. 返回 false
ForBinding : BindingPattern
  1. 返回 true
Note

本节由附录 B.3.5 扩展。

14.7.5.3 运行时语义:ForDeclarationBindingInitialization

The syntax-directed operation 运行时语义:ForDeclarationBindingInitialization takes arguments value (ECMAScript 语言值) and environment (Environment Recordundefined) and returns 正常或突然完成.

Note

undefined 表示应使用 PutValue 赋值。适用于 var 语句以及某些非严格函数形参(参见 10.2.11)。这些场景下词法绑定被提升并预初始化。

It is defined piecewise over the following productions:

ForDeclaration : LetOrConst ForBinding
  1. 返回 ? BindingInitialization of ForBinding,参数 valueenvironment

14.7.5.4 运行时语义:ForDeclarationBindingInstantiation

The syntax-directed operation 运行时语义:ForDeclarationBindingInstantiation takes argument environment (一个 Declarative Environment Record) and returns unused. It is defined piecewise over the following productions:

ForDeclaration : LetOrConst ForBinding
  1. ForBinding 的 BoundNames 每个 name
    1. 若 IsConstantDeclaration of LetOrConsttrue,执行 ! environment.CreateImmutableBinding(name, true)。
    2. 否则执行 ! environment.CreateMutableBinding(name, false)。
  2. 返回 unused

14.7.5.5 运行时语义:ForInOfLoopEvaluation

The syntax-directed operation 运行时语义:ForInOfLoopEvaluation takes argument labelSet (字符串列表) and returns 正常或突然完成. It is defined piecewise over the following productions:

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement
  1. keyResult 为 ? ForIn/OfHeadEvaluation(« », Expression, enumerate)。
  2. 返回 ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, enumerate, assignment, labelSet)。
ForInOfStatement : for ( var ForBinding in Expression ) Statement
  1. keyResult ← ? ForIn/OfHeadEvaluation(« », Expression, enumerate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, enumerate, var-binding, labelSet)。
ForInOfStatement : for ( ForDeclaration in Expression ) Statement
  1. keyResult ← ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, Expression, enumerate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, enumerate, lexical-binding, labelSet)。
ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement
  1. keyResult ← ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, iterate, assignment, labelSet)。
ForInOfStatement : for ( var ForBinding of AssignmentExpression ) Statement
  1. keyResult ← ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, iterate, var-binding, labelSet)。
ForInOfStatement : for ( ForDeclaration of AssignmentExpression ) Statement
  1. keyResult ← ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexical-binding, labelSet)。
ForInOfStatement : for await ( LeftHandSideExpression of AssignmentExpression ) Statement
  1. keyResult ← ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, iterate, assignment, labelSet, async)。
ForInOfStatement : for await ( var ForBinding of AssignmentExpression ) Statement
  1. keyResult ← ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, iterate, var-binding, labelSet, async)。
ForInOfStatement : for await ( ForDeclaration of AssignmentExpression ) Statement
  1. keyResult ← ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, async-iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexical-binding, labelSet, async)。
Note

本节由附录 B.3.5 扩展。

14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind )

The abstract operation ForIn/OfHeadEvaluation takes arguments uninitializedBoundNames (字符串列表), expr (ExpressionAssignmentExpression Parse Node), and iterationKind (enumerate / iterate / async-iterate) and returns Iterator Record 或突然完成. It performs the following steps when called:

  1. oldEnv 为当前执行上下文 LexicalEnvironment。
  2. uninitializedBoundNames 非空:
    1. 断言无重复。
    2. newEnvNewDeclarativeEnvironment(oldEnv)。
    3. 对每个 name 执行 ! newEnv.CreateMutableBinding(name, false)。
    4. 设置当前 LexicalEnvironment 为 newEnv
  3. exprRefCompletion(Evaluation of expr)。
  4. 恢复 LexicalEnvironment 为 oldEnv
  5. exprValue 为 ? GetValue(? exprRef)。
  6. iterationKindenumerate
    1. exprValueundefinednull
      1. 返回 Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }。
    2. obj = ! ToObject(exprValue)。
    3. iterator = EnumerateObjectProperties(obj)。
    4. nextMethod = ! GetV(iterator, "next")。
    5. 返回 Iterator Record { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false }。
  7. 否则:
    1. 断言 iterationKinditerateasync-iterate
    2. 若为 async-iterateiteratorKind = async 否则 sync
    3. 返回 ? GetIterator(exprValue, iteratorKind)。

14.7.5.7 ForIn/OfBodyEvaluation ( lhs: Parse Node, stmt: Statement Parse Node, iteratorRecord: Iterator Record, iterationKind: enumerateiterate, lhsKind: assignment / var-binding / lexical-binding, labelSet: 字符串列表, 可选 iteratorKind: sync / async, ): 正常或突然完成

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

  1. 若未给出 iteratorKind,设为 sync
  2. oldEnv 为当前 LexicalEnvironment。
  3. V = undefined
  4. destructuring = IsDestructuring of lhs
  5. destructuringtruelhsKindassignment
    1. 断言 lhsLeftHandSideExpression
    2. assignmentPattern 为其覆盖AssignmentPattern
  6. 循环:
    1. nextResult = ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]])。
    2. iteratorKindasync,设 nextResult = ? Await(nextResult)。
    3. nextResult 非 Object 抛 TypeError
    4. done = ? IteratorComplete(nextResult)。
    5. donetrue,返回 V
    6. nextValue = ? IteratorValue(nextResult)。
    7. lhsKindassignmentvar-binding
      1. destructuringtrue
        1. lhsKindassignment
          1. status = Completion(DestructuringAssignmentEvaluation of assignmentPattern,参数 nextValue)。
        2. 否则 (var-binding):
          1. 断言 lhsForBinding
          2. status = Completion(BindingInitialization of lhs, 参数 nextValueundefined)。
      2. 否则:
        1. lhsRef = Completion(Evaluation of lhs)(可重复求值)。
        2. lhsKindassignment 且 AssignmentTargetType 为 web-compatReferenceError
        3. lhsRef 为突然完成则 status = lhsRef;否则 status = Completion(PutValue(lhsRef.[[Value]], nextValue))。
    8. 否则 (lexical-binding):
      1. 断言 lhsForDeclaration
      2. iterationEnv = NewDeclarativeEnvironment(oldEnv)。
      3. 执行 ForDeclarationBindingInstantiation of lhs 参数 iterationEnv
      4. 设当前 LexicalEnvironment = iterationEnv
      5. destructuringtrue
        1. status = Completion(ForDeclarationBindingInitialization of lhs, 参数 nextValueiterationEnv)。
      6. 否则:
        1. 断言 lhs 绑定单一名字。
        2. lhsName 为唯一 BoundName。
        3. lhsRef = ! ResolveBinding(lhsName)。
        4. status = Completion(InitializeReferencedBinding(lhsRef, nextValue))。
    9. status 为突然完成:
      1. 恢复 LexicalEnvironment 为 oldEnv
      2. iteratorKindasync 返回 ? AsyncIteratorClose(iteratorRecord, status)。
      3. iterationKindenumerate 返回 ? status
      4. 否则返回 ? IteratorClose(iteratorRecord, status)。
    10. resultCompletion(Evaluation of stmt)。
    11. 恢复 LexicalEnvironment 为 oldEnv
    12. LoopContinues(result, labelSet) 为 false
      1. iterationKindenumerate 返回 ? UpdateEmpty(result, V)。
      2. 否则:
        1. status = Completion(UpdateEmpty(result, V))。
        2. iteratorKindasync 返回 ? AsyncIteratorClose(iteratorRecord, status)。
        3. 返回 ? IteratorClose(iteratorRecord, status)。
    13. result.[[Value]]empty,设 V = 该值。

14.7.5.8 运行时语义:求值 (Runtime Semantics: Evaluation)

BindingIdentifier : Identifier yield await
  1. bindingIdBindingIdentifier 的 StringValue。
  2. 返回 ? ResolveBinding(bindingId)。

14.7.5.9 EnumerateObjectProperties ( O )

The abstract operation EnumerateObjectProperties takes argument O (一个 Object) and returns 一个迭代器对象. It performs the following steps when called:

  1. 返回一个迭代器对象,其 next 方法按规则遍历 O 的可枚举属性的字符串键。该迭代器对象不可被 ECMAScript 代码直接获取。枚举顺序未指定,但必须符合下述规则。

迭代器的 throwreturn 方法为 null 且不会被调用。next 决定是否返回一个属性键;不返回 Symbol 键。枚举期间可删除目标对象属性,被删且尚未处理的属性被忽略;新增属性不保证出现在当前枚举。每个名称最多返回一次。

枚举包括原型链上可枚举属性;若某原型属性与已处理属性同名则跳过,不比较 [[Enumerable]]。原型对象的可枚举属性名通过再次调用 EnumerateObjectProperties 获得。目标对象的自有属性键通过其 [[OwnPropertyKeys]] 获得,属性属性值通过 [[GetOwnProperty]] 获得。

另外,若 O 及其原型链均非 Proxy / TypedArray / module namespace 或实现自定义 exotic,则该迭代器行为须与 CreateForInIterator(O) 所给迭代器一致,直到出现以下任一情况:

  • 原型链中任意对象的 [[Prototype]] 发生变化;
  • O 或其原型链某对象删除属性;
  • 原型链某对象新增属性;
  • O 或原型链某对象属性的 [[Enumerable]] 值改变。
Note 1

实现无需直接实现 14.7.5.10.2.1 的算法,只要行为一致即可。

下列生成器函数是符合规则的示例:

function* EnumerateObjectProperties(obj) {
  const visited = new Set();
  for (const key of Reflect.ownKeys(obj)) {
    if (typeof key === "symbol") continue;
    const desc = Reflect.getOwnPropertyDescriptor(obj, key);
    if (desc) {
      visited.add(key);
      if (desc.enumerable) yield key;
    }
  }
  const proto = Reflect.getPrototypeOf(obj);
  if (proto === null) return;
  for (const protoKey of EnumerateObjectProperties(proto)) {
    if (!visited.has(protoKey)) yield protoKey;
  }
}
Note 2
例外 exotic 列表基于历史实现差异,其余保持一致。

14.7.5.10 For-In 迭代器对象 (For-In Iterator Objects)

For-In Iterator 表示对特定对象的一次具体迭代,不能被脚本直接访问,仅用于描述 EnumerateObjectProperties 的行为。

14.7.5.10.1 CreateForInIterator ( object )

The abstract operation CreateForInIterator takes argument object (一个 Object) and returns 一个 For-In Iterator. 创建针对 object 自有及继承可枚举字符串属性按特定顺序遍历的 For-In Iterator 对象。 It performs the following steps when called:

  1. iterator = OrdinaryObjectCreate(%ForInIteratorPrototype%, « [[Object]], [[ObjectWasVisited]], [[VisitedKeys]], [[RemainingKeys]] »)。
  2. iterator.[[Object]]object
  3. iterator.[[ObjectWasVisited]]false
  4. iterator.[[VisitedKeys]] ← 空 List
  5. iterator.[[RemainingKeys]] ← 空 List
  6. 返回 iterator

14.7.5.10.2 %ForInIteratorPrototype% 对象

%ForInIteratorPrototype% 对象:

14.7.5.10.2.1 %ForInIteratorPrototype%.next ( )

  1. Othis
  2. 断言 O 是 Object
  3. 断言 OFor-In Iterator 所有内部槽。
  4. object = O.[[Object]]
  5. 重复:
    1. O.[[ObjectWasVisited]]false
      1. keys = ? object.[[OwnPropertyKeys]]()
      2. keys 每个 key
        1. key 是 String,追加到 O.[[RemainingKeys]]
      3. O.[[ObjectWasVisited]] = true
    2. O.[[RemainingKeys]] 非空重复:
      1. r 为首元素。
      2. 移除之。
      3. O.[[VisitedKeys]] 不含 r
        1. desc = ? object.[[GetOwnProperty]](r)。
        2. descundefined
          1. 追加 rO.[[VisitedKeys]]
          2. desc.[[Enumerable]]true,返回 CreateIteratorResultObject(r, false)。
    3. object = ? object.[[GetPrototypeOf]]()
    4. O.[[Object]] = object
    5. O.[[ObjectWasVisited]] = false
    6. objectnull,返回 CreateIteratorResultObject(undefined, true)。

14.7.5.10.3 For-In 迭代器实例属性 (Properties of For-In Iterator Instances)

实例为普通对象,继承自 %ForInIteratorPrototype%,初始拥有下表内部槽:

Table 36: For-In 迭代器实例内部槽 (Internal Slots of For-In Iterator Instances)
内部槽 类型 描述
[[Object]] Object 枚举属性的对象。
[[ObjectWasVisited]] Boolean 若已在 [[Object]] 上调用 [[OwnPropertyKeys]]true,否则 false
[[VisitedKeys]] 字符串列表 迄今已发出的键。
[[RemainingKeys]] 字符串列表 当前对象剩余未发出的键(在遍历原型链之前)。

14.8 continue 语句 (The continue Statement)

语法 (Syntax)

ContinueStatement[Yield, Await] : continue ; continue [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ;

14.8.1 静态语义:早期错误 (Static Semantics: Early Errors)

ContinueStatement : continue ; continue LabelIdentifier ;

14.8.2 运行时语义:求值 (Runtime Semantics: Evaluation)

ContinueStatement : continue ;
  1. 返回 Completion Record { [[Type]]: continue, [[Value]]: empty, [[Target]]: empty }。
ContinueStatement : continue LabelIdentifier ;
  1. labelLabelIdentifier 的 StringValue。
  2. 返回 Completion Record { [[Type]]: continue, [[Value]]: empty, [[Target]]: label }。

14.9 break 语句 (The break Statement)

语法 (Syntax)

BreakStatement[Yield, Await] : break ; break [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ;

14.9.1 静态语义:早期错误 (Static Semantics: Early Errors)

BreakStatement : break ;

14.9.2 运行时语义:求值 (Runtime Semantics: Evaluation)

BreakStatement : break ;
  1. 返回 Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }。
BreakStatement : break LabelIdentifier ;
  1. labelLabelIdentifier 的 StringValue。
  2. 返回 Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: label }。

14.10 return 语句 (The return Statement)

语法 (Syntax)

ReturnStatement[Yield, Await] : return ; return [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; Note

return 语句使函数终止执行并(大多数情况下)向调用者返回值;若省略 Expression,返回 undefined。在某些上下文(如 try/finally)中,返回值可能被之后的 Completion 替换。

14.10.1 运行时语义:求值 (Runtime Semantics: Evaluation)

ReturnStatement : return ;
  1. 返回 ReturnCompletion(undefined)。
ReturnStatement : return Expression ;
  1. exprRef 为 ? Evaluation of Expression
  2. exprValue 为 ? GetValue(exprRef)。
  3. GetGeneratorKind() 为 async,设 exprValue = ? Await(exprValue)。
  4. 返回 ReturnCompletion(exprValue)。
Legacy

14.11 with 语句 (The with Statement)

Note 1

不建议在新代码中使用遗留 with 语句;可考虑在严格和非严格模式都允许的替代方案,如 解构赋值

语法 (Syntax)

WithStatement[Yield, Await, Return] : with ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] Note 2

with 语句把对象环境记录加入当前词法环境,然后使用扩展环境执行语句,结束后恢复原环境。

14.11.1 静态语义:早期错误 (Static Semantics: Early Errors)

WithStatement : with ( Expression ) Statement
  • 若 IsStrict(this production) 为 true,语法错误。
  • 若 IsLabelledFunction(Statement) 为 true,语法错误。
Note

仅在实现 B.3.1 扩展时需应用第二条。

14.11.2 运行时语义:求值 (Runtime Semantics: Evaluation)

WithStatement : with ( Expression ) Statement
  1. val 为 ? Evaluation of Expression
  2. obj 为 ? ToObject(? GetValue(val))。
  3. oldEnv 为当前 LexicalEnvironment。
  4. newEnvNewObjectEnvironment(obj, true, oldEnv)。
  5. 设置当前 LexicalEnvironment 为 newEnv
  6. CCompletion(Evaluation of Statement)。
  7. 恢复 LexicalEnvironment 为 oldEnv
  8. 返回 ? UpdateEmpty(C, undefined)。
Note

无论 Statement 如何结束(正常与否),LexicalEnvironment 都会被恢复。

14.12 switch 语句 (The switch Statement)

语法 (Syntax)

SwitchStatement[Yield, Await, Return] : switch ( Expression[+In, ?Yield, ?Await] ) CaseBlock[?Yield, ?Await, ?Return] CaseBlock[Yield, Await, Return] : { CaseClauses[?Yield, ?Await, ?Return]opt } { CaseClauses[?Yield, ?Await, ?Return]opt DefaultClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return]opt } CaseClauses[Yield, Await, Return] : CaseClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return] CaseClause[?Yield, ?Await, ?Return] CaseClause[Yield, Await, Return] : case Expression[+In, ?Yield, ?Await] : StatementList[?Yield, ?Await, ?Return]opt DefaultClause[Yield, Await, Return] : default : StatementList[?Yield, ?Await, ?Return]opt

14.12.1 静态语义:早期错误 (Static Semantics: Early Errors)

SwitchStatement : switch ( Expression ) CaseBlock
  • CaseBlock 的 LexicallyDeclaredNames 含重复条目则语法错误;除非宿主是 web 浏览器或支持 块级函数声明 Web 历史兼容语义 且:

    • IsStrict(this production) 为 false
    • 重复条目仅由 FunctionDeclarations 绑定。
  • CaseBlock 的 LexicallyDeclaredNames 与其 VarDeclaredNames 有交集,语法错误。

14.12.2 运行时语义:CaseBlockEvaluation

The syntax-directed operation 运行时语义:CaseBlockEvaluation takes argument input (ECMAScript 语言值) and returns 正常或突然完成. It is defined piecewise over the following productions:

CaseBlock : { }
  1. 返回 undefined
CaseBlock : { CaseClauses }
  1. Vundefined
  2. A ← 按源码顺序的 CaseClause 列表。
  3. foundfalse
  4. 对每个 CA
    1. foundfalse,设 found ← ? CaseClauseIsSelected(C, input)。
    2. foundtrue
      1. RCompletion(Evaluation of C)。
      2. R.[[Value]]emptyVR.[[Value]]
      3. R 为突然完成,返回 ? UpdateEmpty(R, V)。
  5. 返回 V
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. Vundefined
  2. 若首个 CaseClauses 存在,A ← 其 CaseClause 列表;否则空列表。
  3. foundfalse
  4. A 中每个 C
    1. foundfalsefound ← ? CaseClauseIsSelected(C, input)。
    2. foundtrue
      1. RCompletion(Evaluation of C)。
      2. R.[[Value]]emptyVR.[[Value]]
      3. R 为突然完成,返回 ? UpdateEmpty(R, V)。
  5. foundInBfalse
  6. 若第二个 CaseClauses 存在,B ← 其列表;否则空列表。
  7. foundfalse
    1. B 中每个 C
      1. foundInBfalsefoundInB ← ? CaseClauseIsSelected(C, input)。
      2. foundInBtrue
        1. RCompletion(Evaluation of C)。
        2. R.[[Value]]emptyVR.[[Value]]
        3. R 为突然完成,返回 ? UpdateEmpty(R, V)。
  8. foundInBtrue,返回 V
  9. defaultRCompletion(Evaluation of DefaultClause)。
  10. defaultR.[[Value]]emptyVdefaultR.[[Value]]
  11. defaultR 为突然完成,返回 ? UpdateEmpty(defaultR, V)。
  12. 注:以下再次遍历 B
  13. B 中每个 C
    1. RCompletion(Evaluation of C)。
    2. R.[[Value]]emptyVR.[[Value]]
    3. R 为突然完成,返回 ? UpdateEmpty(R, V)。
  14. 返回 V

14.12.3 CaseClauseIsSelected ( C, input )

The abstract operation CaseClauseIsSelected takes arguments C (CaseClause Parse Node) and input (ECMAScript 语言值) and returns 正常完成含 Boolean 或突然完成. 判断 C 是否匹配 input。 It performs the following steps when called:

  1. 断言 C 为产生式 CaseClause : case Expression : StatementListopt 实例。
  2. exprRef 为 ? Evaluation of CExpression
  3. clauseSelector 为 ? GetValue(exprRef)。
  4. 返回 IsStrictlyEqual(input, clauseSelector)。
Note

该操作不执行 CStatementListCaseBlock 算法根据其返回值决定从哪个 StatementList 开始。

14.12.4 运行时语义:求值 (Runtime Semantics: Evaluation)

SwitchStatement : switch ( Expression ) CaseBlock
  1. exprRef ← ? Evaluation of Expression
  2. switchValue ← ? GetValue(exprRef)。
  3. oldEnv ← 当前 LexicalEnvironment。
  4. blockEnvNewDeclarativeEnvironment(oldEnv)。
  5. 执行 BlockDeclarationInstantiation(CaseBlock, blockEnv)。
  6. 设置 LexicalEnvironment = blockEnv
  7. RCompletion(CaseBlockEvaluation of CaseBlock, 参数 switchValue)。
  8. 恢复 LexicalEnvironment = oldEnv
  9. 返回 R
Note

无论控制如何离开 SwitchStatement,LexicalEnvironment 皆被恢复。

CaseClause : case Expression :
  1. 返回 empty
CaseClause : case Expression : StatementList
  1. 返回 ? Evaluation of StatementList
DefaultClause : default :
  1. 返回 empty
DefaultClause : default : StatementList
  1. 返回 ? Evaluation of StatementList

14.13 带标签语句 (Labelled Statements)

语法 (Syntax)

LabelledStatement[Yield, Await, Return] : LabelIdentifier[?Yield, ?Await] : LabelledItem[?Yield, ?Await, ?Return] LabelledItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] FunctionDeclaration[?Yield, ?Await, ~Default] Note

Statement 可带标签。标签语句仅配合带标签的 break / continue;语言无 goto。标签递归嵌套形成“当前标签集合”。

14.13.1 静态语义:早期错误 (Static Semantics: Early Errors)

LabelledItem : FunctionDeclaration

14.13.2 静态语义:IsLabelledFunction ( stmt )

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

  1. stmt 不是 LabelledStatement,返回 false
  2. item 为其 LabelledItem
  3. item LabelledItem : FunctionDeclaration ,返回 true
  4. subStmtitemStatement
  5. 返回 IsLabelledFunction(subStmt)。

14.13.3 运行时语义:求值 (Runtime Semantics: Evaluation)

LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 ? LabelledEvaluation of 此 LabelledStatement,参数 « »。

14.13.4 运行时语义:LabelledEvaluation

The syntax-directed operation 运行时语义:LabelledEvaluation takes argument labelSet (字符串列表) and returns 正常完成ECMAScript 语言值empty,或突然完成. It is defined piecewise over the following productions:

BreakableStatement : IterationStatement
  1. stmtResultCompletion(LoopEvaluation of IterationStatement, 参数 labelSet)。
  2. stmtResultbreak 完成
    1. stmtResult.[[Target]]empty
      1. stmtResult.[[Value]]empty,设其为 NormalCompletion(undefined);否则设为其值的 NormalCompletion
  3. 返回 ? stmtResult
BreakableStatement : SwitchStatement
  1. stmtResultCompletion(Evaluation of SwitchStatement)。
  2. 若为 break 且 [[Target]]empty
    1. [[Value]]empty 设为 NormalCompletion(undefined) 否则为该值。
  3. 返回 ? stmtResult
Note 1

BreakableStatement 是能被无标签 BreakStatement 退出的语句。

LabelledStatement : LabelIdentifier : LabelledItem
  1. label ← StringValue of LabelIdentifier
  2. newLabelSet ← 连接 labelSet 与 « label »。
  3. stmtResultCompletion(LabelledEvaluation of LabelledItem, 参数 newLabelSet)。
  4. stmtResult 是 break 且 [[Target]]label,则设为 NormalCompletion(stmtResult.[[Value]])。
  5. 返回 ? stmtResult
LabelledItem : FunctionDeclaration
  1. 返回 ? Evaluation of FunctionDeclaration
Statement : BlockStatement VariableStatement EmptyStatement ExpressionStatement IfStatement ContinueStatement BreakStatement ReturnStatement WithStatement ThrowStatement TryStatement DebuggerStatement
  1. 返回 ? Evaluation of Statement
Note 2

Statement 中仅 BreakableStatementLabelledStatement 在 LabelledEvaluation 有特殊语义。

14.14 throw 语句 (The throw Statement)

语法 (Syntax)

ThrowStatement[Yield, Await] : throw [no LineTerminator here] Expression[+In, ?Yield, ?Await] ;

14.14.1 运行时语义:求值 (Runtime Semantics: Evaluation)

ThrowStatement : throw Expression ;
  1. exprRef ← ? Evaluation of Expression
  2. exprValue ← ? GetValue(exprRef)。
  3. 返回 ThrowCompletion(exprValue)。

14.15 try 语句 (The try Statement)

语法 (Syntax)

TryStatement[Yield, Await, Return] : try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] Catch[Yield, Await, Return] : catch ( CatchParameter[?Yield, ?Await] ) Block[?Yield, ?Await, ?Return] catch Block[?Yield, ?Await, ?Return] Finally[Yield, Await, Return] : finally Block[?Yield, ?Await, ?Return] CatchParameter[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] Note

try 语句封装可能发生异常的代码块;catch 提供处理逻辑;被捕获异常绑定到 CatchParameter

14.15.1 静态语义:早期错误 (Static Semantics: Early Errors)

Catch : catch ( CatchParameter ) Block

14.15.2 运行时语义:CatchClauseEvaluation

The syntax-directed operation 运行时语义:CatchClauseEvaluation takes argument thrownValue (ECMAScript 语言值) and returns 正常完成ECMAScript 语言值empty,或突然完成. It is defined piecewise over the following productions:

Catch : catch ( CatchParameter ) Block
  1. oldEnv ← 当前 LexicalEnvironment。
  2. catchEnvNewDeclarativeEnvironment(oldEnv)。
  3. CatchParameter 的 BoundNames 中每个 argName
    1. 执行 ! catchEnv.CreateMutableBinding(argName, false)。
  4. 设置 LexicalEnvironment = catchEnv
  5. statusCompletion(BindingInitialization of CatchParameter,参数 thrownValuecatchEnv)。
  6. status 为突然完成:
    1. 恢复 LexicalEnvironment = oldEnv
    2. 返回 ? status
  7. BCompletion(Evaluation of Block)。
  8. 恢复 LexicalEnvironment = oldEnv
  9. 返回 ? B
Catch : catch Block
  1. 返回 ? Evaluation of Block
Note

无论 Block 如何离开,LexicalEnvironment 都被恢复。

14.15.3 运行时语义:求值 (Runtime Semantics: Evaluation)

TryStatement : try Block Catch
  1. BCompletion(Evaluation of Block)。
  2. Bthrow 完成CCompletion(CatchClauseEvaluation of Catch, 参数 B.[[Value]]);否则 CB
  3. 返回 ? UpdateEmpty(C, undefined)。
TryStatement : try Block Finally
  1. BCompletion(Evaluation of Block)。
  2. FCompletion(Evaluation of Finally)。
  3. F 为 normal,设 FB
  4. 返回 ? UpdateEmpty(F, undefined)。
TryStatement : try Block Catch Finally
  1. BCompletion(Evaluation of Block)。
  2. B 为 throw,CCompletion(CatchClauseEvaluation of Catch, 参数 B.[[Value]]);否则 CB
  3. FCompletion(Evaluation of Finally)。
  4. F 为 normal,设 FC
  5. 返回 ? UpdateEmpty(F, undefined)。

14.16 debugger 语句 (The debugger Statement)

语法 (Syntax)

DebuggerStatement : debugger ;

14.16.1 运行时语义:求值 (Runtime Semantics: Evaluation)

Note

求值 DebuggerStatement 时实现可在调试器下触发断点;若无调试器则无可观察效果。

DebuggerStatement : debugger ;
  1. 若实现定义的调试设施可用且启用:
    1. 执行实现定义调试动作。
    2. 返回实现定义的新 Completion Record
  2. 否则返回 empty

15 ECMAScript 语言:函数与类 (ECMAScript Language: Functions and Classes)

Note

多种 ECMAScript 语言元素会创建 ECMAScript 函数对象10.2)。此类函数的求值从其 [[Call]] 内部方法的执行开始(10.2.1)。

15.1 参数列表 (Parameter Lists)

语法 (Syntax)

UniqueFormalParameters[Yield, Await] : FormalParameters[?Yield, ?Await] FormalParameters[Yield, Await] : [empty] FunctionRestParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameterList[?Yield, ?Await] , FunctionRestParameter[?Yield, ?Await] FormalParameterList[Yield, Await] : FormalParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameter[?Yield, ?Await] FunctionRestParameter[Yield, Await] : BindingRestElement[?Yield, ?Await] FormalParameter[Yield, Await] : BindingElement[?Yield, ?Await]

15.1.1 静态语义:早期错误 (Static Semantics: Early Errors)

UniqueFormalParameters : FormalParameters
  • 如果 FormalParameters 的 BoundNames 包含任意重复元素,则为语法错误。
FormalParameters : FormalParameterList
  • 如果 FormalParameterList 的 IsSimpleParameterList 为 false 且其 BoundNames 含有任意重复元素,则为语法错误。
Note

同一个 BindingIdentifier 在同一个 FormalParameterList 中出现多次只在函数具有简单参数列表并且不是在严格模式代码中定义时才被允许。

15.1.2 静态语义:ContainsExpression

The syntax-directed operation 静态语义:ContainsExpression takes no arguments and returns 一个 Boolean. It is defined piecewise over the following productions:

ObjectBindingPattern : { } { BindingRestProperty }
  1. 返回 false
ObjectBindingPattern : { BindingPropertyList , BindingRestProperty }
  1. 返回 ContainsExpression of BindingPropertyList
ArrayBindingPattern : [ Elisionopt ]
  1. 返回 false
ArrayBindingPattern : [ Elisionopt BindingRestElement ]
  1. 返回 ContainsExpression of BindingRestElement
ArrayBindingPattern : [ BindingElementList , Elisionopt ]
  1. 返回 ContainsExpression of BindingElementList
ArrayBindingPattern : [ BindingElementList , Elisionopt BindingRestElement ]
  1. has 为 ContainsExpression of BindingElementList
  2. 如果 hastrue,返回 true
  3. 返回 ContainsExpression of BindingRestElement
BindingPropertyList : BindingPropertyList , BindingProperty
  1. has 为 ContainsExpression of BindingPropertyList
  2. 如果 hastrue,返回 true
  3. 返回 ContainsExpression of BindingProperty
BindingElementList : BindingElementList , BindingElisionElement
  1. has 为 ContainsExpression of BindingElementList
  2. 如果 hastrue,返回 true
  3. 返回 ContainsExpression of BindingElisionElement
BindingElisionElement : Elisionopt BindingElement
  1. 返回 ContainsExpression of BindingElement
BindingProperty : PropertyName : BindingElement
  1. has 为 IsComputedPropertyKey of PropertyName
  2. 如果 hastrue,返回 true
  3. 返回 ContainsExpression of BindingElement
BindingElement : BindingPattern Initializer
  1. 返回 true
SingleNameBinding : BindingIdentifier
  1. 返回 false
SingleNameBinding : BindingIdentifier Initializer
  1. 返回 true
BindingRestElement : ... BindingIdentifier
  1. 返回 false
BindingRestElement : ... BindingPattern
  1. 返回 ContainsExpression of BindingPattern
FormalParameters : [empty]
  1. 返回 false
FormalParameters : FormalParameterList , FunctionRestParameter
  1. 如果 ContainsExpression of FormalParameterListtrue,返回 true
  2. 返回 ContainsExpression of FunctionRestParameter
FormalParameterList : FormalParameterList , FormalParameter
  1. 如果 ContainsExpression of FormalParameterListtrue,返回 true
  2. 返回 ContainsExpression of FormalParameter
ArrowParameters : BindingIdentifier
  1. 返回 false
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formals 为由 CoverParenthesizedExpressionAndArrowParameterList 覆盖ArrowFormalParameters
  2. 返回 ContainsExpression of formals
AsyncArrowBindingIdentifier : BindingIdentifier
  1. 返回 false

15.1.3 静态语义:IsSimpleParameterList

The syntax-directed operation 静态语义:IsSimpleParameterList takes no arguments and returns 一个 Boolean. It is defined piecewise over the following productions:

BindingElement : BindingPattern
  1. 返回 false
BindingElement : BindingPattern Initializer
  1. 返回 false
SingleNameBinding : BindingIdentifier
  1. 返回 true
SingleNameBinding : BindingIdentifier Initializer
  1. 返回 false
FormalParameters : [empty]
  1. 返回 true
FormalParameters : FunctionRestParameter
  1. 返回 false
FormalParameters : FormalParameterList , FunctionRestParameter
  1. 返回 false
FormalParameterList : FormalParameterList , FormalParameter
  1. 如果 IsSimpleParameterList of FormalParameterListfalse,返回 false
  2. 返回 IsSimpleParameterList of FormalParameter
FormalParameter : BindingElement
  1. 返回 IsSimpleParameterList of BindingElement
ArrowParameters : BindingIdentifier
  1. 返回 true
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formals 为由 CoverParenthesizedExpressionAndArrowParameterList 覆盖ArrowFormalParameters
  2. 返回 IsSimpleParameterList of formals
AsyncArrowBindingIdentifier : BindingIdentifier
  1. 返回 true
CoverCallExpressionAndAsyncArrowHead : MemberExpression Arguments
  1. head 为由 CoverCallExpressionAndAsyncArrowHead 覆盖AsyncArrowHead
  2. 返回 IsSimpleParameterList of head

15.1.4 静态语义:HasInitializer

The syntax-directed operation 静态语义:HasInitializer takes no arguments and returns 一个 Boolean. It is defined piecewise over the following productions:

BindingElement : BindingPattern
  1. 返回 false
BindingElement : BindingPattern Initializer
  1. 返回 true
SingleNameBinding : BindingIdentifier
  1. 返回 false
SingleNameBinding : BindingIdentifier Initializer
  1. 返回 true
FormalParameterList : FormalParameterList , FormalParameter
  1. 如果 HasInitializer of FormalParameterListtrue,返回 true
  2. 返回 HasInitializer of FormalParameter

15.1.5 静态语义:ExpectedArgumentCount

The syntax-directed operation 静态语义:ExpectedArgumentCount takes no arguments and returns 一个非负整数. It is defined piecewise over the following productions:

FormalParameters : [empty] FunctionRestParameter
  1. 返回 0。
FormalParameters : FormalParameterList , FunctionRestParameter
  1. 返回 FormalParameterList 的 ExpectedArgumentCount。
Note

FormalParameterList 的 ExpectedArgumentCount 是位于剩余参数或第一个带 Initializer 的 FormalParameter 左侧的 FormalParameters 数目。在第一个带初始值的参数之后仍可出现不带初始值的参数,但这些参数被视为可选,其默认值为 undefined

FormalParameterList : FormalParameter
  1. 如果 HasInitializer of FormalParametertrue,返回 0。
  2. 返回 1。
FormalParameterList : FormalParameterList , FormalParameter
  1. countFormalParameterList 的 ExpectedArgumentCount。
  2. 如果 HasInitializer of FormalParameterListtrue 或 HasInitializer of FormalParametertrue,返回 count
  3. 返回 count + 1。
ArrowParameters : BindingIdentifier
  1. 返回 1。
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formals 为由 CoverParenthesizedExpressionAndArrowParameterList 覆盖ArrowFormalParameters
  2. 返回 formals 的 ExpectedArgumentCount。
PropertySetParameterList : FormalParameter
  1. 如果 HasInitializer of FormalParametertrue,返回 0。
  2. 返回 1。
AsyncArrowBindingIdentifier : BindingIdentifier
  1. 返回 1。

15.2 函数定义 (Function Definitions)

语法 (Syntax)

FunctionDeclaration[Yield, Await, Default] : function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } [+Default] function ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } FunctionExpression : function BindingIdentifier[~Yield, ~Await]opt ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } FunctionBody[Yield, Await] : FunctionStatementList[?Yield, ?Await] FunctionStatementList[Yield, Await] : StatementList[?Yield, ?Await, +Return]opt

15.2.1 静态语义:早期错误 (Static Semantics: Early Errors)

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } Note

FunctionBody 的 LexicallyDeclaredNames 不包含通过 var 或 function 声明绑定的标识符。

FunctionBody : FunctionStatementList

15.2.2 静态语义:FunctionBodyContainsUseStrict

The syntax-directed operation 静态语义:FunctionBodyContainsUseStrict takes no arguments and returns Boolean. It is defined piecewise over the following productions:

FunctionBody : FunctionStatementList
  1. FunctionBody指令序言 (Directive Prologue) 含有 Use Strict 指令,返回 true;否则返回 false

15.2.3 运行时语义:EvaluateFunctionBody

The syntax-directed operation 运行时语义:EvaluateFunctionBody takes arguments functionObject (一个 ECMAScript 函数对象) and argumentsList (ECMAScript 语言值的列表) and returns 一个 return completion 或 throw completion. It is defined piecewise over the following productions:

FunctionBody : FunctionStatementList
  1. 执行 ? FunctionDeclarationInstantiation(functionObject, argumentsList)。
  2. 执行 ? Evaluation of FunctionStatementList
  3. 注:若上一步产生正常完成,则求值已到达 FunctionStatementList 末尾。
  4. 返回 ReturnCompletion(undefined)。

15.2.4 运行时语义:InstantiateOrdinaryFunctionObject

The syntax-directed operation 运行时语义:InstantiateOrdinaryFunctionObject takes arguments env (一个 Environment Record) and privateEnv (一个 PrivateEnvironment Recordnull) and returns 一个 ECMAScript 函数对象. It is defined piecewise over the following productions:

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. nameBindingIdentifier 的 StringValue。
  2. sourceTextFunctionDeclaration 匹配的源文本。
  3. FOrdinaryFunctionCreate(%Function.prototype%, sourceText, FormalParameters, FunctionBody, non-lexical-this, env, privateEnv)。
  4. 执行 SetFunctionName(F, name)。
  5. 执行 MakeConstructor(F)。
  6. 返回 F
FunctionDeclaration : function ( FormalParameters ) { FunctionBody }
  1. sourceTextFunctionDeclaration 匹配的源文本。
  2. FOrdinaryFunctionCreate(%Function.prototype%, sourceText, FormalParameters, FunctionBody, non-lexical-this, env, privateEnv)。
  3. 执行 SetFunctionName(F, "default")。
  4. 执行 MakeConstructor(F)。
  5. 返回 F
Note

匿名 FunctionDeclaration 只能作为 export default 声明的一部分,其函数代码因此总是严格模式代码。

15.2.5 运行时语义:InstantiateOrdinaryFunctionExpression : 一个 ECMAScript 函数对象

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

FunctionExpression : function ( FormalParameters ) { FunctionBody }
  1. name 不存在,设 name""
  2. env 为当前执行上下文的 LexicalEnvironment。
  3. privateEnv 为当前执行上下文的 PrivateEnvironment。
  4. sourceTextFunctionExpression 匹配的源文本。
  5. closureOrdinaryFunctionCreate(%Function.prototype%, sourceText, FormalParameters, FunctionBody, non-lexical-this, env, privateEnv)。
  6. 执行 SetFunctionName(closure, name)。
  7. 执行 MakeConstructor(closure)。
  8. 返回 closure
FunctionExpression : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. 断言:name 不存在。
  2. nameBindingIdentifier 的 StringValue。
  3. outerEnv 为当前执行上下文的 LexicalEnvironment。
  4. funcEnvNewDeclarativeEnvironment(outerEnv)。
  5. 执行 ! funcEnv.CreateImmutableBinding(name, false)。
  6. privateEnv 为当前执行上下文的 PrivateEnvironment。
  7. sourceTextFunctionExpression 匹配的源文本。
  8. closureOrdinaryFunctionCreate(%Function.prototype%, sourceText, FormalParameters, FunctionBody, non-lexical-this, funcEnv, privateEnv)。
  9. 执行 SetFunctionName(closure, name)。
  10. 执行 MakeConstructor(closure)。
  11. 执行 ! funcEnv.InitializeBinding(name, closure)。
  12. 返回 closure
Note

FunctionExpression 中的 BindingIdentifier 可在其 FunctionBody 内部引用以实现递归调用。但与 FunctionDeclaration 不同,该标识符不能从包围 FunctionExpression 的外部作用域引用,也不会影响外部作用域。

15.2.6 运行时语义:求值 (Runtime Semantics: Evaluation)

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. 返回 empty
Note 1 FunctionDeclaration : function ( FormalParameters ) { FunctionBody }
  1. 返回 empty
FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody }
  1. 返回 InstantiateOrdinaryFunctionExpression of FunctionExpression
Note 2

每个通过 FunctionDeclarationFunctionExpression 定义的函数会自动创建一个 "prototype" 属性,以便该函数可作为构造函数使用。

FunctionStatementList : [empty]
  1. 返回 undefined

15.3 箭头函数定义 (Arrow Function Definitions)

语法 (Syntax)

ArrowFunction[In, Yield, Await] : ArrowParameters[?Yield, ?Await] [no LineTerminator here] => ConciseBody[?In] ArrowParameters[Yield, Await] : BindingIdentifier[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] ConciseBody[In] : [lookahead ≠ {] ExpressionBody[?In, ~Await] { FunctionBody[~Yield, ~Await] } ExpressionBody[In, Await] : AssignmentExpression[?In, ~Yield, ?Await]

补充语法 (Supplemental Syntax)

当处理产生式实例:
ArrowParameters[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
时,使用以下语法细化对 CoverParenthesizedExpressionAndArrowParameterList 的解释:

ArrowFormalParameters[Yield, Await] : ( UniqueFormalParameters[?Yield, ?Await] )

15.3.1 静态语义:早期错误 (Static Semantics: Early Errors)

ArrowFunction : ArrowParameters => ConciseBody ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList

15.3.2 静态语义:ConciseBodyContainsUseStrict

The syntax-directed operation 静态语义:ConciseBodyContainsUseStrict takes no arguments and returns Boolean. It is defined piecewise over the following productions:

ConciseBody : ExpressionBody
  1. 返回 false
ConciseBody : { FunctionBody }
  1. 返回 FunctionBodyContainsUseStrict(FunctionBody)。

15.3.3 运行时语义:EvaluateConciseBody

The syntax-directed operation 运行时语义:EvaluateConciseBody takes arguments functionObject (一个 ECMAScript 函数对象) and argumentsList (ECMAScript 语言值的列表) and returns 一个 return completion 或 throw completion. It is defined piecewise over the following productions:

ConciseBody : ExpressionBody
  1. 执行 ? FunctionDeclarationInstantiation(functionObject, argumentsList)。
  2. 返回 ? Evaluation of ExpressionBody

15.3.4 运行时语义:InstantiateArrowFunctionExpression : 一个 ECMAScript 函数对象

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

ArrowFunction : ArrowParameters => ConciseBody
  1. name 不存在,设 name""
  2. env 为当前执行上下文的 LexicalEnvironment。
  3. privateEnv 为当前执行上下文的 PrivateEnvironment。
  4. sourceTextArrowFunction 匹配的源文本。
  5. closureOrdinaryFunctionCreate(%Function.prototype%, sourceText, ArrowParameters, ConciseBody, lexical-this, env, privateEnv)。
  6. 执行 SetFunctionName(closure, name)。
  7. 返回 closure
Note

ArrowFunction 不为 argumentssuperthisnew.target 定义局部绑定;在其内部的此类引用必须解析为词法外层环境中的绑定。尽管 ArrowFunction 可引用 super,但步骤 5 创建的函数对象不会通过 MakeMethod 变成方法;包含 superArrowFunction 始终位于非 ArrowFunction 内,其实现 super 所需状态通过捕获的 env 可用。

15.3.5 运行时语义:求值 (Runtime Semantics: Evaluation)

ArrowFunction : ArrowParameters => ConciseBody
  1. 返回 InstantiateArrowFunctionExpression of ArrowFunction
ExpressionBody : AssignmentExpression
  1. exprRef 为 ? Evaluation of AssignmentExpression
  2. exprValue 为 ? GetValue(exprRef)。
  3. 返回 ReturnCompletion(exprValue)。

15.4 方法定义 (Method Definitions)

语法 (Syntax)

MethodDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } GeneratorMethod[?Yield, ?Await] AsyncMethod[?Yield, ?Await] AsyncGeneratorMethod[?Yield, ?Await] get ClassElementName[?Yield, ?Await] ( ) { FunctionBody[~Yield, ~Await] } set ClassElementName[?Yield, ?Await] ( PropertySetParameterList ) { FunctionBody[~Yield, ~Await] } PropertySetParameterList : FormalParameter[~Yield, ~Await]

15.4.1 静态语义:早期错误 (Static Semantics: Early Errors)

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }

15.4.2 静态语义:HasDirectSuper

The syntax-directed operation 静态语义:HasDirectSuper takes no arguments and returns Boolean. It is defined piecewise over the following productions:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. UniqueFormalParameters Contains SuperCalltrue,返回 true
  2. 返回 FunctionBody Contains SuperCall
MethodDefinition : get ClassElementName ( ) { FunctionBody }
  1. 返回 FunctionBody Contains SuperCall
MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. PropertySetParameterList Contains SuperCalltrue,返回 true
  2. 返回 FunctionBody Contains SuperCall
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. UniqueFormalParameters Contains SuperCalltrue,返回 true
  2. 返回 GeneratorBody Contains SuperCall
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. UniqueFormalParameters Contains SuperCalltrue,返回 true
  2. 返回 AsyncGeneratorBody Contains SuperCall
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. UniqueFormalParameters Contains SuperCalltrue,返回 true
  2. 返回 AsyncFunctionBody Contains SuperCall

15.4.3 静态语义:SpecialMethod

The syntax-directed operation 静态语义:SpecialMethod takes no arguments and returns Boolean. It is defined piecewise over the following productions:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. 返回 false
MethodDefinition : GeneratorMethod AsyncMethod AsyncGeneratorMethod get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. 返回 true

15.4.4 运行时语义:DefineMethod : 正常完成(含 [[Key]][[Closure]] 字段的 Record)或突然完成

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. propKey 为 ? Evaluation of ClassElementName
  2. env 为当前执行上下文的 LexicalEnvironment。
  3. privateEnv 为当前执行上下文的 PrivateEnvironment。
  4. functionPrototype 存在,令 prototype = functionPrototype;否则令 prototype = %Function.prototype%
  5. sourceTextMethodDefinition 匹配的源文本。
  6. closureOrdinaryFunctionCreate(prototype, sourceText, UniqueFormalParameters, FunctionBody, non-lexical-this, env, privateEnv)。
  7. 执行 MakeMethod(closure, object)。
  8. 返回 Record { [[Key]]: propKey, [[Closure]]: closure }。

15.4.5 运行时语义:MethodDefinitionEvaluation

The syntax-directed operation 运行时语义:MethodDefinitionEvaluation takes arguments object (一个 Object) and enumerable (一个 Boolean) and returns 正常完成(含 PrivateElementunused)或突然完成. It is defined piecewise over the following productions:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. methodDef 为 ? DefineMethod of MethodDefinition,参数 object
  2. 执行 SetFunctionName(methodDef.[[Closure]], methodDef.[[Key]])。
  3. 返回 ? DefineMethodProperty(object, methodDef.[[Key]], methodDef.[[Closure]], enumerable)。
MethodDefinition : get ClassElementName ( ) { FunctionBody }
  1. propKey 为 ? Evaluation of ClassElementName
  2. env 为当前执行上下文的 LexicalEnvironment。
  3. privateEnv 为当前执行上下文的 PrivateEnvironment。
  4. sourceTextMethodDefinition 匹配的源文本。
  5. formalParameterList 为产生式 FormalParameters : [empty] 的一个实例。
  6. closureOrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameterList, FunctionBody, non-lexical-this, env, privateEnv)。
  7. 执行 MakeMethod(closure, object)。
  8. 执行 SetFunctionName(closure, propKey, "get")。
  9. propKeyPrivate Name,则
    1. 返回 PrivateElement { [[Key]]: propKey, [[Kind]]: accessor, [[Get]]: closure, [[Set]]: undefined }。
  10. 否则,
    1. desc 为 PropertyDescriptor { [[Get]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true }。
    2. 执行 ? DefinePropertyOrThrow(object, propKey, desc)。
    3. 返回 unused
MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. propKey 为 ? Evaluation of ClassElementName
  2. env 为当前执行上下文的 LexicalEnvironment。
  3. privateEnv 为当前执行上下文的 PrivateEnvironment。
  4. sourceTextMethodDefinition 匹配的源文本。
  5. closureOrdinaryFunctionCreate(%Function.prototype%, sourceText, PropertySetParameterList, FunctionBody, non-lexical-this, env, privateEnv)。
  6. 执行 MakeMethod(closure, object)。
  7. 执行 SetFunctionName(closure, propKey, "set")。
  8. propKeyPrivate Name,则
    1. 返回 PrivateElement { [[Key]]: propKey, [[Kind]]: accessor, [[Get]]: undefined, [[Set]]: closure }。
  9. 否则,
    1. desc 为 PropertyDescriptor { [[Set]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true }。
    2. 执行 ? DefinePropertyOrThrow(object, propKey, desc)。
    3. 返回 unused
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. propKey 为 ? Evaluation of ClassElementName
  2. env 为当前执行上下文的 LexicalEnvironment。
  3. privateEnv 为当前执行上下文的 PrivateEnvironment。
  4. sourceTextGeneratorMethod 匹配的源文本。
  5. closureOrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, UniqueFormalParameters, GeneratorBody, non-lexical-this, env, privateEnv)。
  6. 执行 MakeMethod(closure, object)。
  7. 执行 SetFunctionName(closure, propKey)。
  8. prototypeOrdinaryObjectCreate(%GeneratorPrototype%)。
  9. 执行 ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  10. 返回 ? DefineMethodProperty(object, propKey, closure, enumerable)。
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. propKey 为 ? Evaluation of ClassElementName
  2. env 为当前执行上下文的 LexicalEnvironment。
  3. privateEnv 为当前执行上下文的 PrivateEnvironment。
  4. sourceTextAsyncGeneratorMethod 匹配的源文本。
  5. closureOrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, UniqueFormalParameters, AsyncGeneratorBody, non-lexical-this, env, privateEnv)。
  6. 执行 MakeMethod(closure, object)。
  7. 执行 SetFunctionName(closure, propKey)。
  8. prototypeOrdinaryObjectCreate(%AsyncGeneratorPrototype%)。
  9. 执行 ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  10. 返回 ? DefineMethodProperty(object, propKey, closure, enumerable)。
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. propKey 为 ? Evaluation of ClassElementName
  2. env 为当前执行上下文的 LexicalEnvironment。
  3. privateEnv 为当前执行上下文的 PrivateEnvironment。
  4. sourceTextAsyncMethod 匹配的源文本。
  5. closureOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, UniqueFormalParameters, AsyncFunctionBody, non-lexical-this, env, privateEnv)。
  6. 执行 MakeMethod(closure, object)。
  7. 执行 SetFunctionName(closure, propKey)。
  8. 返回 ? DefineMethodProperty(object, propKey, closure, enumerable)。

15.5 生成器函数定义 (Generator Function Definitions)

语法 (Syntax)

GeneratorDeclaration[Yield, Await, Default] : function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } [+Default] function * ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorExpression : function * BindingIdentifier[+Yield, ~Await]opt ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorMethod[Yield, Await] : * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorBody : FunctionBody[+Yield, ~Await] YieldExpression[In, Await] : yield yield [no LineTerminator here] AssignmentExpression[?In, +Yield, ?Await] yield [no LineTerminator here] * AssignmentExpression[?In, +Yield, ?Await] Note 1

yield 后紧随的语法上下文需要使用 InputElementRegExpOrTemplateTail 词法目标。

Note 2

YieldExpression 不能用于生成器函数的 FormalParameters 内,因为 FormalParameters 中的表达式会在生成的 Generator 进入可恢复状态之前被求值。

Note 3

与生成器相关的抽象操作定义见 27.5.3

15.5.1 静态语义:早期错误 (Static Semantics: Early Errors)

GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody }

15.5.2 运行时语义:EvaluateGeneratorBody

The syntax-directed operation 运行时语义:EvaluateGeneratorBody takes arguments functionObject (一个 ECMAScript 函数对象) and argumentsList (ECMAScript 语言值的列表) and returns 一个 throw completion 或 return completion. It is defined piecewise over the following productions:

GeneratorBody : FunctionBody
  1. 执行 ? FunctionDeclarationInstantiation(functionObject, argumentsList)。
  2. G 为 ? OrdinaryCreateFromConstructor(functionObject, "%GeneratorPrototype%", « [[GeneratorState]], [[GeneratorContext]], [[GeneratorBrand]] »)。
  3. G.[[GeneratorBrand]]empty
  4. G.[[GeneratorState]]suspended-start
  5. 执行 GeneratorStart(G, FunctionBody)。
  6. 返回 ReturnCompletion(G)。

15.5.3 运行时语义:InstantiateGeneratorFunctionObject

The syntax-directed operation 运行时语义:InstantiateGeneratorFunctionObject takes arguments env (一个 Environment Record) and privateEnv (一个 PrivateEnvironment Recordnull) and returns 一个 ECMAScript 函数对象. It is defined piecewise over the following productions:

GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody }
  1. nameBindingIdentifier 的 StringValue。
  2. sourceTextGeneratorDeclaration 匹配的源文本。
  3. FOrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, FormalParameters, GeneratorBody, non-lexical-this, env, privateEnv)。
  4. 执行 SetFunctionName(F, name)。
  5. prototypeOrdinaryObjectCreate(%GeneratorPrototype%)。
  6. 执行 ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  7. 返回 F
GeneratorDeclaration : function * ( FormalParameters ) { GeneratorBody }
  1. sourceTextGeneratorDeclaration 匹配的源文本。
  2. FOrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, FormalParameters, GeneratorBody, non-lexical-this, env, privateEnv)。
  3. 执行 SetFunctionName(F, "default")。
  4. prototypeOrdinaryObjectCreate(%GeneratorPrototype%)。
  5. 执行 ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  6. 返回 F
Note

匿名 GeneratorDeclaration 只能作为 export default 声明的一部分,因此其函数代码总是严格模式代码。

15.5.4 运行时语义:InstantiateGeneratorFunctionExpression : 一个 ECMAScript 函数对象

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

GeneratorExpression : function * ( FormalParameters ) { GeneratorBody }
  1. name 不存在,设 name""
  2. env 为当前执行上下文的 LexicalEnvironment。
  3. privateEnv 为当前执行上下文的 PrivateEnvironment。
  4. sourceTextGeneratorExpression 匹配的源文本。
  5. closureOrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, FormalParameters, GeneratorBody, non-lexical-this, env, privateEnv)。
  6. 执行 SetFunctionName(closure, name)。
  7. prototypeOrdinaryObjectCreate(%GeneratorPrototype%)。
  8. 执行 ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  9. 返回 closure
GeneratorExpression : function * BindingIdentifier ( FormalParameters ) { GeneratorBody }
  1. 断言:name 不存在。
  2. nameBindingIdentifier 的 StringValue。
  3. outerEnv 为当前执行上下文的 LexicalEnvironment。
  4. funcEnvNewDeclarativeEnvironment(outerEnv)。
  5. 执行 ! funcEnv.CreateImmutableBinding(name, false)。
  6. privateEnv 为当前执行上下文的 PrivateEnvironment。
  7. sourceTextGeneratorExpression 匹配的源文本。
  8. closureOrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, FormalParameters, GeneratorBody, non-lexical-this, funcEnv, privateEnv)。
  9. 执行 SetFunctionName(closure, name)。
  10. prototypeOrdinaryObjectCreate(%GeneratorPrototype%)。
  11. 执行 ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  12. 执行 ! funcEnv.InitializeBinding(name, closure)。
  13. 返回 closure
Note

GeneratorExpression 中的 BindingIdentifier 可在其 FunctionBody 内被引用以实现生成器代码自递归。但与 GeneratorDeclaration 不同,该 BindingIdentifier 不可从包围 GeneratorExpression 的作用域引用,也不影响该外层作用域。

15.5.5 运行时语义:求值 (Runtime Semantics: Evaluation)

GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody }
  1. 返回 InstantiateGeneratorFunctionExpression of GeneratorExpression
YieldExpression : yield
  1. 返回 ? Yield(undefined)。
YieldExpression : yield AssignmentExpression
  1. exprRef 为 ? Evaluation of AssignmentExpression
  2. value 为 ? GetValue(exprRef)。
  3. 返回 ? Yield(value)。
YieldExpression : yield * AssignmentExpression
  1. generatorKindGetGeneratorKind()。
  2. 断言:generatorKindsyncasync
  3. exprRef 为 ? Evaluation of AssignmentExpression
  4. value 为 ? GetValue(exprRef)。
  5. iteratorRecord 为 ? GetIterator(value, generatorKind)。
  6. iteratoriteratorRecord.[[Iterator]]
  7. receivedNormalCompletion(undefined)。
  8. 重复,
    1. received 为 normal completion,则
      1. innerResult 为 ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « received.[[Value]] »)。
      2. generatorKindasync,设 innerResult 为 ? Await(innerResult)。
      3. innerResult 不是 Object,抛出 TypeError 异常。
      4. done 为 ? IteratorComplete(innerResult)。
      5. donetrue,则
        1. 返回 ? IteratorValue(innerResult)。
      6. generatorKindasync,设 receivedCompletion(AsyncGeneratorYield(? IteratorValue(innerResult)))。
      7. 否则,设 receivedCompletion(GeneratorYield(innerResult))。
    2. 否则若 received 为 throw completion,则
      1. throw 为 ? GetMethod(iterator, "throw")。
      2. throwundefined,则
        1. innerResult 为 ? Call(throw, iterator, « received.[[Value]] »)。
        2. generatorKindasync,设 innerResult 为 ? Await(innerResult)。
        3. 注:内部迭代器 throw 方法抛出的异常会被传播。其正常完成与内部 next 类似处理。
        4. innerResult 不是 Object,抛出 TypeError 异常。
        5. done 为 ? IteratorComplete(innerResult)。
        6. donetrue,则
          1. 返回 ? IteratorValue(innerResult)。
        7. generatorKindasync,设 receivedCompletion(AsyncGeneratorYield(? IteratorValue(innerResult)))。
        8. 否则设 receivedCompletion(GeneratorYield(innerResult))。
      3. 否则,
        1. 注:若 iterator 不具有 throw 方法,则该抛出将终止 yield* 循环。但需先给予 iterator 清理机会。
        2. closeCompletionNormalCompletion(empty)。
        3. generatorKindasync,执行 ? AsyncIteratorClose(iteratorRecord, closeCompletion)。
        4. 否则,执行 ? IteratorClose(iteratorRecord, closeCompletion)。
        5. 注:下一步抛出 TypeError 以指示 yield* 协议违规:iteratorthrow 方法。
        6. 抛出 TypeError 异常。
    3. 否则,
      1. 断言:received 是 return completion。
      2. return 为 ? GetMethod(iterator, "return")。
      3. returnundefined,则
        1. valuereceived.[[Value]]
        2. generatorKindasync,则
          1. value 为 ? Await(value)。
        3. 返回 ReturnCompletion(value)。
      4. innerReturnResult 为 ? Call(return, iterator, « received.[[Value]] »)。
      5. generatorKindasync,设 innerReturnResult 为 ? Await(innerReturnResult)。
      6. innerReturnResult 不是 Object,抛出 TypeError 异常。
      7. done 为 ? IteratorComplete(innerReturnResult)。
      8. donetrue,则
        1. value 为 ? IteratorValue(innerReturnResult)。
        2. 返回 ReturnCompletion(value)。
      9. generatorKindasync,设 receivedCompletion(AsyncGeneratorYield(? IteratorValue(innerReturnResult)))。
      10. 否则设 receivedCompletion(GeneratorYield(innerReturnResult))。

15.6 异步生成器函数定义 (Async Generator Function Definitions)

语法 (Syntax)

AsyncGeneratorDeclaration[Yield, Await, Default] : async [no LineTerminator here] function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } [+Default] async [no LineTerminator here] function * ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorExpression : async [no LineTerminator here] function * BindingIdentifier[+Yield, +Await]opt ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorMethod[Yield, Await] : async [no LineTerminator here] * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorBody : FunctionBody[+Yield, +Await] Note 1

YieldExpressionAwaitExpression 不能用于异步生成器函数的 FormalParameters 内,因为它们会在 AsyncGenerator 进入可恢复状态前被求值。

Note 2

与 AsyncGenerators 有关的抽象操作27.6.3

15.6.1 静态语义:早期错误 (Static Semantics: Early Errors)

AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody }

15.6.2 运行时语义:EvaluateAsyncGeneratorBody

The syntax-directed operation 运行时语义:EvaluateAsyncGeneratorBody takes arguments functionObject (一个 ECMAScript 函数对象) and argumentsList (ECMAScript 语言值的列表) and returns 一个 throw completion 或 return completion. It is defined piecewise over the following productions:

AsyncGeneratorBody : FunctionBody
  1. 执行 ? FunctionDeclarationInstantiation(functionObject, argumentsList)。
  2. generator 为 ? OrdinaryCreateFromConstructor(functionObject, "%AsyncGeneratorPrototype%", « [[AsyncGeneratorState]], [[AsyncGeneratorContext]], [[AsyncGeneratorQueue]], [[GeneratorBrand]] »)。
  3. generator.[[GeneratorBrand]]empty
  4. generator.[[AsyncGeneratorState]]suspended-start
  5. 执行 AsyncGeneratorStart(generator, FunctionBody)。
  6. 返回 ReturnCompletion(generator)。

15.6.3 运行时语义:InstantiateAsyncGeneratorFunctionObject

The syntax-directed operation 运行时语义:InstantiateAsyncGeneratorFunctionObject takes arguments env (一个 Environment Record) and privateEnv (一个 PrivateEnvironment Recordnull) and returns 一个 ECMAScript 函数对象. It is defined piecewise over the following productions:

AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody }
  1. nameBindingIdentifier 的 StringValue。
  2. sourceTextAsyncGeneratorDeclaration 匹配的源文本。
  3. FOrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, FormalParameters, AsyncGeneratorBody, non-lexical-this, env, privateEnv)。
  4. 执行 SetFunctionName(F, name)。
  5. prototypeOrdinaryObjectCreate(%AsyncGeneratorPrototype%)。
  6. 执行 ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  7. 返回 F
AsyncGeneratorDeclaration : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. sourceTextAsyncGeneratorDeclaration 匹配的源文本。
  2. FOrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, FormalParameters, AsyncGeneratorBody, non-lexical-this, env, privateEnv)。
  3. 执行 SetFunctionName(F, "default")。
  4. prototypeOrdinaryObjectCreate(%AsyncGeneratorPrototype%)。
  5. 执行 ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  6. 返回 F
Note

匿名 AsyncGeneratorDeclaration 只能出现在 export default 声明中。

15.6.4 运行时语义:InstantiateAsyncGeneratorFunctionExpression : 一个 ECMAScript 函数对象

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

AsyncGeneratorExpression : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. name 不存在,设 name""
  2. env 为当前执行上下文的 LexicalEnvironment。
  3. privateEnv 为当前执行上下文的 PrivateEnvironment。
  4. sourceTextAsyncGeneratorExpression 匹配的源文本。
  5. closureOrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, FormalParameters, AsyncGeneratorBody, non-lexical-this, env, privateEnv)。
  6. 执行 SetFunctionName(closure, name)。
  7. prototypeOrdinaryObjectCreate(%AsyncGeneratorPrototype%)。
  8. 执行 ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  9. 返回 closure
AsyncGeneratorExpression : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody }
  1. 断言:name 不存在。
  2. nameBindingIdentifier 的 StringValue。
  3. outerEnv 为当前执行上下文的 LexicalEnvironment。
  4. funcEnvNewDeclarativeEnvironment(outerEnv)。
  5. 执行 ! funcEnv.CreateImmutableBinding(name, false)。
  6. privateEnv 为当前执行上下文的 PrivateEnvironment。
  7. sourceTextAsyncGeneratorExpression 匹配的源文本。
  8. closureOrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, FormalParameters, AsyncGeneratorBody, non-lexical-this, funcEnv, privateEnv)。
  9. 执行 SetFunctionName(closure, name)。
  10. prototypeOrdinaryObjectCreate(%AsyncGeneratorPrototype%)。
  11. 执行 ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  12. 执行 ! funcEnv.InitializeBinding(name, closure)。
  13. 返回 closure
Note

AsyncGeneratorExpression 中的 BindingIdentifier 可在其 AsyncGeneratorBody 内被引用以实现自递归。但与 AsyncGeneratorDeclaration 不同,该标识符不可从包围表达式的作用域引用,也不影响外层作用域。

15.6.5 运行时语义:求值 (Runtime Semantics: Evaluation)

AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody }
  1. 返回 InstantiateAsyncGeneratorFunctionExpression of AsyncGeneratorExpression

15.7 类定义 (Class Definitions)

语法 (Syntax)

ClassDeclaration[Yield, Await, Default] : class BindingIdentifier[?Yield, ?Await] ClassTail[?Yield, ?Await] [+Default] class ClassTail[?Yield, ?Await] ClassExpression[Yield, Await] : class BindingIdentifier[?Yield, ?Await]opt ClassTail[?Yield, ?Await] ClassTail[Yield, Await] : ClassHeritage[?Yield, ?Await]opt { ClassBody[?Yield, ?Await]opt } ClassHeritage[Yield, Await] : extends LeftHandSideExpression[?Yield, ?Await] ClassBody[Yield, Await] : ClassElementList[?Yield, ?Await] ClassElementList[Yield, Await] : ClassElement[?Yield, ?Await] ClassElementList[?Yield, ?Await] ClassElement[?Yield, ?Await] ClassElement[Yield, Await] : MethodDefinition[?Yield, ?Await] static MethodDefinition[?Yield, ?Await] FieldDefinition[?Yield, ?Await] ; static FieldDefinition[?Yield, ?Await] ; ClassStaticBlock ; FieldDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt ClassElementName[Yield, Await] : PropertyName[?Yield, ?Await] PrivateIdentifier ClassStaticBlock : static { ClassStaticBlockBody } ClassStaticBlockBody : ClassStaticBlockStatementList ClassStaticBlockStatementList : StatementList[~Yield, +Await, ~Return]opt Note

类定义始终是严格模式代码。

15.7.1 静态语义:早期错误 (Static Semantics: Early Errors)

ClassTail : ClassHeritageopt { ClassBody }
  • 若未出现 ClassHeritage 且下述算法返回 true,则为语法错误:

    1. constructorClassBody 的 ConstructorMethod。
    2. constructorempty,返回 false
    3. 返回 HasDirectSuper(constructor)。
ClassBody : ClassElementList
  • ClassElementList 的 PrototypePropertyNameList 中出现多于一次 "constructor",则语法错误。
  • ClassElementList 的 PrivateBoundIdentifiers 含有重复条目(除非该名称仅用作一次 getter 与一次 setter 且不出现其他条目,且二者同为 static 或同为非 static),则语法错误。
ClassElement : MethodDefinition ClassElement : static MethodDefinition ClassElement : FieldDefinition ; ClassElement : static FieldDefinition ;
  • FieldDefinition 的 PropName 若为 "prototype""constructor" 则语法错误。
FieldDefinition : ClassElementName Initializeropt ClassElementName : PrivateIdentifier ClassStaticBlockBody : ClassStaticBlockStatementList

15.7.2 静态语义:ClassElementKind

The syntax-directed operation 静态语义:ClassElementKind takes no arguments and returns constructor-methodnon-constructor-methodempty. It is defined piecewise over the following productions:

ClassElement : MethodDefinition
  1. MethodDefinition 的 PropName 为 "constructor",返回 constructor-method
  2. 返回 non-constructor-method
ClassElement : static MethodDefinition FieldDefinition ; static FieldDefinition ;
  1. 返回 non-constructor-method
ClassElement : ClassStaticBlock
  1. 返回 non-constructor-method
ClassElement : ;
  1. 返回 empty

15.7.3 静态语义:ConstructorMethod

The syntax-directed operation 静态语义:ConstructorMethod takes no arguments and returns 一个 ClassElement 解析节点empty. It is defined piecewise over the following productions:

ClassElementList : ClassElement
  1. ClassElement 的 ClassElementKind 为 constructor-method,返回 ClassElement
  2. 返回 empty
ClassElementList : ClassElementList ClassElement
  1. headClassElementList 的 ConstructorMethod。
  2. headempty,返回 head
  3. ClassElement 的 ClassElementKind 为 constructor-method,返回 ClassElement
  4. 返回 empty
Note

早期错误规则确保仅存在一个名为 "constructor" 的方法定义,且它不是访问器属性或生成器定义。

15.7.4 静态语义:IsStatic

The syntax-directed operation 静态语义:IsStatic takes no arguments and returns Boolean. It is defined piecewise over the following productions:

ClassElement : MethodDefinition
  1. 返回 false
ClassElement : static MethodDefinition
  1. 返回 true
ClassElement : FieldDefinition ;
  1. 返回 false
ClassElement : static FieldDefinition ;
  1. 返回 true
ClassElement : ClassStaticBlock
  1. 返回 true
ClassElement : ;
  1. 返回 false

15.7.5 静态语义:NonConstructorElements

The syntax-directed operation 静态语义:NonConstructorElements takes no arguments and returns ClassElement 解析节点的列表. It is defined piecewise over the following productions:

ClassElementList : ClassElement
  1. ClassElement 的 ClassElementKind 为 non-constructor-method,则
    1. 返回 « ClassElement »。
  2. 返回新空列表。
ClassElementList : ClassElementList ClassElement
  1. listClassElementList 的 NonConstructorElements。
  2. ClassElement 的 ClassElementKind 为 non-constructor-method,则
    1. ClassElement 追加至 list 末尾。
  3. 返回 list

15.7.6 静态语义:PrototypePropertyNameList

The syntax-directed operation 静态语义:PrototypePropertyNameList takes no arguments and returns 属性键列表. It is defined piecewise over the following productions:

ClassElementList : ClassElement
  1. propNameClassElement 的 PropName。
  2. propNameempty,返回新空列表。
  3. 若 IsStatic(ClassElement) 为 true,返回新空列表。
  4. 返回 « propName »。
ClassElementList : ClassElementList ClassElement
  1. listClassElementList 的 PrototypePropertyNameList。
  2. propNameClassElement 的 PropName。
  3. propNameempty,返回 list
  4. 若 IsStatic(ClassElement) 为 true,返回 list
  5. 返回 列表连接(list, « propName »)。

15.7.7 静态语义:AllPrivateIdentifiersValid

The syntax-directed operation 静态语义:AllPrivateIdentifiersValid takes argument names (字符串列表) and returns Boolean.

本规范中未列出的所有产生式替代都隐式具有如下默认定义:

  1. 对该解析节点的每个子节点 child
    1. child 是非终结符实例,则
      1. 若 AllPrivateIdentifiersValid(child, names) 为 false,返回 false
  2. 返回 true
MemberExpression : MemberExpression . PrivateIdentifier
  1. names 包含 PrivateIdentifier 的 StringValue,则
    1. 返回 AllPrivateIdentifiersValid(MemberExpression, names)。
  2. 返回 false
CallExpression : CallExpression . PrivateIdentifier
  1. names 包含 PrivateIdentifier 的 StringValue,则
    1. 返回 AllPrivateIdentifiersValid(CallExpression, names)。
  2. 返回 false
OptionalChain : ?. PrivateIdentifier
  1. names 包含 PrivateIdentifier 的 StringValue,返回 true
  2. 返回 false
OptionalChain : OptionalChain . PrivateIdentifier
  1. names 包含 PrivateIdentifier 的 StringValue,则
    1. 返回 AllPrivateIdentifiersValid(OptionalChain, names)。
  2. 返回 false
ClassBody : ClassElementList
  1. newNamesnamesClassBody 的 PrivateBoundIdentifiers 的列表连接。
  2. 返回 AllPrivateIdentifiersValid(ClassElementList, newNames)。
RelationalExpression : PrivateIdentifier in ShiftExpression
  1. names 包含 PrivateIdentifier 的 StringValue,则
    1. 返回 AllPrivateIdentifiersValid(ShiftExpression, names)。
  2. 返回 false

15.7.8 静态语义:PrivateBoundIdentifiers

The syntax-directed operation 静态语义:PrivateBoundIdentifiers takes no arguments and returns 字符串列表. It is defined piecewise over the following productions:

FieldDefinition : ClassElementName Initializeropt
  1. 返回 ClassElementName 的 PrivateBoundIdentifiers。
ClassElementName : PrivateIdentifier
  1. 返回仅包含 PrivateIdentifier 的 StringValue 的列表。
ClassElementName : PropertyName ClassElement : ClassStaticBlock ;
  1. 返回新空列表。
ClassElementList : ClassElementList ClassElement
  1. names1ClassElementList 的 PrivateBoundIdentifiers。
  2. names2ClassElement 的 PrivateBoundIdentifiers。
  3. 返回 列表连接(names1, names2)。
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody } GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody } AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. 返回 ClassElementName 的 PrivateBoundIdentifiers。

15.7.9 静态语义:ContainsArguments

The syntax-directed operation 静态语义:ContainsArguments takes no arguments and returns Boolean.

本规范中未列出的产生式替代默认使用以下定义:

  1. 对该节点的每个子节点 child
    1. child 是非终结符实例:
      1. 若 ContainsArguments(child) 为 true,返回 true
  2. 返回 false
IdentifierReference : Identifier
  1. Identifier 的 StringValue 为 "arguments",返回 true
  2. 返回 false
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 false
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody } GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody } AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. 返回 ContainsArguments(ClassElementName)。

15.7.10 运行时语义:ClassFieldDefinitionEvaluation

The syntax-directed operation 运行时语义:ClassFieldDefinitionEvaluation takes argument homeObject (一个对象) and returns 正常完成(包含一个 ClassFieldDefinition Record)或突然完成. It is defined piecewise over the following productions:

FieldDefinition : ClassElementName Initializeropt
  1. name 为 ? Evaluation of ClassElementName
  2. 若存在 Initializer,则
    1. formalParameterList 为产生式 FormalParameters : [empty] 的一个实例。
    2. env 为当前执行上下文的 LexicalEnvironment。
    3. privateEnv 为当前执行上下文的 PrivateEnvironment。
    4. sourceText 为空的 Unicode 码点序列。
    5. initializerOrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameterList, Initializer, non-lexical-this, env, privateEnv)。
    6. 执行 MakeMethod(initializer, homeObject)。
    7. initializer.[[ClassFieldInitializerName]]name
  3. 否则,
    1. initializerempty
  4. 返回 ClassFieldDefinition Record { [[Name]]: name, [[Initializer]]: initializer }。
Note
initializer 创建的函数不会被 ECMAScript 代码直接访问。

15.7.11 运行时语义:ClassStaticBlockDefinitionEvaluation

The syntax-directed operation 运行时语义:ClassStaticBlockDefinitionEvaluation takes argument homeObject (一个对象) and returns 一个 ClassStaticBlockDefinition Record. It is defined piecewise over the following productions:

ClassStaticBlock : static { ClassStaticBlockBody }
  1. lex 为当前执行上下文的 LexicalEnvironment。
  2. privateEnv 为当前执行上下文的 PrivateEnvironment。
  3. sourceText 为空的 Unicode 码点序列。
  4. formalParameters 为产生式 FormalParameters : [empty] 的实例。
  5. bodyFunctionOrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameters, ClassStaticBlockBody, non-lexical-this, lex, privateEnv)。
  6. 执行 MakeMethod(bodyFunction, homeObject)。
  7. 返回 ClassStaticBlockDefinition Record { [[BodyFunction]]: bodyFunction }。
Note
函数 bodyFunction 不会被 ECMAScript 代码直接访问。

15.7.12 运行时语义:EvaluateClassStaticBlockBody

The syntax-directed operation 运行时语义:EvaluateClassStaticBlockBody takes argument functionObject (一个 ECMAScript 函数对象) and returns 一个 return completion 或 throw completion. It is defined piecewise over the following productions:

ClassStaticBlockBody : ClassStaticBlockStatementList
  1. 断言:functionObject 是由 ClassStaticBlockDefinitionEvaluation 步骤 5 创建的合成函数。
  2. 执行 ! FunctionDeclarationInstantiation(functionObject, « »)。
  3. 执行 ? Evaluation of ClassStaticBlockStatementList
  4. 返回 ReturnCompletion(undefined)。

15.7.13 运行时语义:ClassElementEvaluation

The syntax-directed operation 运行时语义:ClassElementEvaluation takes argument object (一个对象) and returns 正常完成(包含 ClassFieldDefinition RecordClassStaticBlockDefinition RecordPrivateElementunused 之一)或突然完成. It is defined piecewise over the following productions:

ClassElement : FieldDefinition ; static FieldDefinition ;
  1. 返回 ? ClassFieldDefinitionEvaluation(FieldDefinition, object)。
ClassElement : MethodDefinition static MethodDefinition
  1. 返回 ? MethodDefinitionEvaluation(MethodDefinition, object, false)。
ClassElement : ClassStaticBlock
  1. 返回 ClassStaticBlockDefinitionEvaluation(ClassStaticBlock, object)。
ClassElement : ;
  1. 返回 unused

15.7.14 运行时语义:ClassDefinitionEvaluation

The syntax-directed operation 运行时语义:ClassDefinitionEvaluation takes arguments classBinding (一个 String 或 undefined), className (一个属性键Private Name), and sourceText (ECMAScript 源文本) and returns 正常完成(包含一个函数对象)或突然完成.

Note

为便于规范说明,私有方法与访问器与私有字段一起被包含在类实例的 [[PrivateElements]] 槽中。然而,任意给定对象要么拥有该类定义的全部私有方法与访问器,要么一个也没有。该特性被设计为允许实现选择不对每个方法或访问器单独跟踪的策略来实现私有方法与访问器。

例如,实现可以将实例私有方法直接与其对应的 Private Name 关联,并为每个对象跟踪哪些类构造函数以该对象作为 this 值运行。随后在对象上查找一个实例私有方法的过程即是检查定义该方法的类构造函数是否已用于初始化该对象,然后返回与该 Private Name 关联的方法。

这不同于私有字段:由于字段初始化器在类实例化期间可能抛出,单个对象可能只拥有某个类私有字段的真子集,因此一般必须单独跟踪私有字段。

It is defined piecewise over the following productions:

ClassTail : ClassHeritageopt { ClassBodyopt }
  1. env 为正在运行的执行上下文的 LexicalEnvironment。
  2. classEnvNewDeclarativeEnvironment(env)。
  3. classBinding 不为 undefined,则
    1. 执行 ! classEnv.CreateImmutableBinding(classBinding, true)。
  4. outerPrivateEnvironment 为正在运行的执行上下文的 PrivateEnvironment。
  5. classPrivateEnvironmentNewPrivateEnvironment(outerPrivateEnvironment)。
  6. 若存在 ClassBody,则
    1. ClassBody 的 PrivateBoundIdentifiers 中每个字符串 dn
      1. classPrivateEnvironment.[[Names]] 包含 Private Name pnpn.[[Description]]dn,则
        1. 断言:仅 getter/setter 成对时可能。
      2. 否则,
        1. name 为新的 Private Name[[Description]]dn
        2. name 追加至 classPrivateEnvironment.[[Names]]
  7. 若不存在 ClassHeritage,则
    1. protoParent%Object.prototype%
    2. constructorParent%Function.prototype%
  8. 否则,
    1. 将正在运行执行上下文的 LexicalEnvironment 设为 classEnv
    2. 注:计算 ClassHeritage 时运行执行上下文的 PrivateEnvironment 为 outerPrivateEnvironment
    3. superclassRefCompletion(Evaluation of ClassHeritage)。
    4. 将运行执行上下文的 LexicalEnvironment 设回 env
    5. superclass 为 ? GetValue(? superclassRef)。
    6. superclassnull,则
      1. protoParentnull
      2. constructorParent%Function.prototype%
    7. 否则若 IsConstructor(superclass) 为 false,则
      1. 抛出 TypeError 异常。
    8. 否则,
      1. protoParent 为 ? Get(superclass, "prototype")。
      2. protoParent不是 Object 且不是 null,抛出 TypeError 异常。
      3. constructorParentsuperclass
  9. protoOrdinaryObjectCreate(protoParent)。
  10. 若不存在 ClassBody,令 constructorempty
  11. 否则,令 constructorClassBody 的 ConstructorMethod。
  12. 将运行执行上下文的 LexicalEnvironment 设为 classEnv
  13. 将运行执行上下文的 PrivateEnvironment 设为 classPrivateEnvironment
  14. constructorempty,则
    1. defaultConstructor 为一个不带参数且不捕获任何内容的新抽象闭包,被调用时执行:
      1. args 为通过 [[Call]][[Construct]] 传给此函数的参数列表。
      2. 若 NewTarget 为 undefined,抛出 TypeError 异常。
      3. F 为活动函数对象
      4. F.[[ConstructorKind]]derived,则
        1. 注:此分支行为类似 constructor(...args) { super(...args); }。最显著区别是上述 ECMAScript 源码会可观察地调用 %Array.prototype% 上的 %Symbol.iterator% 方法,而此函数不会。
        2. func 为 ! F.[[GetPrototypeOf]]()。
        3. IsConstructor(func) 为 false,抛出 TypeError 异常。
        4. result 为 ? Construct(func, args, NewTarget)。
      5. 否则,
        1. 注:此分支类似 constructor() {}
        2. result 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Object.prototype%")。
      6. 执行 ? InitializeInstanceElements(result, F)。
      7. 返回 NormalCompletion(result)。
    2. FCreateBuiltinFunction(defaultConstructor, 0, className, « [[ConstructorKind]], [[SourceText]] », 当前 Realm Record, constructorParent)。
  15. 否则,
    1. constructorInfo 为 ! DefineMethod of constructor,参数 protoconstructorParent
    2. FconstructorInfo.[[Closure]]
    3. 执行 MakeClassConstructor(F)。
    4. 执行 SetFunctionName(F, className)。
  16. F.[[SourceText]]sourceText
  17. 执行 MakeConstructor(F, false, proto)。
  18. 若存在 ClassHeritage,设 F.[[ConstructorKind]]derived
  19. 执行 ! DefineMethodProperty(proto, "constructor", F, false)。
  20. 若不存在 ClassBody,令 elements 为新空 List
  21. 否则,令 elementsClassBody 的 NonConstructorElements。
  22. instancePrivateMethodsstaticPrivateMethodsinstanceFieldsstaticElements 各为新空 List
  23. elements 中每个 ClassElement e
    1. 若 IsStatic of efalse,则
      1. elementCompletion(ClassElementEvaluation of e,参数 proto)。
    2. 否则,
      1. elementCompletion(ClassElementEvaluation of e,参数 F)。
    3. element 是突然完成,
      1. 将运行执行上下文的 LexicalEnvironment 设为 env
      2. 将运行执行上下文的 PrivateEnvironment 设为 outerPrivateEnvironment
      3. 返回 ? element
    4. element 为 ! element
    5. elementPrivateElement,则
      1. 断言:element.[[Kind]]methodaccessor
      2. 若 IsStatic of efalse,令 containerinstancePrivateMethods;否则令其为 staticPrivateMethods
      3. container 中存在 PrivateElement pepe.[[Key]]element.[[Key]],则
        1. 断言:element.[[Kind]]pe.[[Kind]] 均为 accessor
        2. element.[[Get]]undefined,则
          1. combinedPrivateElement { [[Key]]: element.[[Key]], [[Kind]]: accessor, [[Get]]: pe.[[Get]], [[Set]]: element.[[Set]] }。
        3. 否则,
          1. combinedPrivateElement { [[Key]]: element.[[Key]], [[Kind]]: accessor, [[Get]]: element.[[Get]], [[Set]]: pe.[[Set]] }。
        4. combined 替换 container 中的 pe
      4. 否则,
        1. 追加 elementcontainer
    6. 否则若 elementClassFieldDefinition Record,则
      1. 若 IsStatic of efalse,将 element 追加至 instanceFields;否则追加至 staticElements
    7. 否则若 elementClassStaticBlockDefinition Record,则
      1. 追加 elementstaticElements
  24. 将运行执行上下文的 LexicalEnvironment 设回 env
  25. classBinding 不为 undefined,则
    1. 执行 ! classEnv.InitializeBinding(classBinding, F)。
  26. F.[[PrivateMethods]]instancePrivateMethods
  27. F.[[Fields]]instanceFields
  28. staticPrivateMethods 中每个 PrivateElement method
    1. 执行 ! PrivateMethodOrAccessorAdd(F, method)。
  29. staticElements 中每个元素 elementRecord
    1. elementRecordClassFieldDefinition Record,则
      1. resultCompletion(DefineField(F, elementRecord))。
    2. 否则,
      1. 断言:elementRecordClassStaticBlockDefinition Record
      2. resultCompletion(Call(elementRecord.[[BodyFunction]], F))。
    3. result 为突然完成,
      1. 将运行执行上下文的 PrivateEnvironment 设为 outerPrivateEnvironment
      2. 返回 ? result
  30. 将运行执行上下文的 PrivateEnvironment 设为 outerPrivateEnvironment
  31. 返回 F

15.7.15 运行时语义:BindingClassDeclarationEvaluation

The syntax-directed operation 运行时语义:BindingClassDeclarationEvaluation takes no arguments and returns 正常完成(包含一个函数对象)或突然完成. It is defined piecewise over the following productions:

ClassDeclaration : class BindingIdentifier ClassTail
  1. classNameBindingIdentifier 的 StringValue。
  2. sourceTextClassDeclaration 匹配的源文本。
  3. value 为 ? ClassDefinitionEvaluation of ClassTail,参数 classNameclassNamesourceText
  4. env 为正在运行的执行上下文的 LexicalEnvironment。
  5. 执行 ? InitializeBoundName(className, value, env)。
  6. 返回 value
ClassDeclaration : class ClassTail
  1. sourceTextClassDeclaration 匹配的源文本。
  2. 返回 ? ClassDefinitionEvaluation of ClassTail,参数 undefined"default"sourceText
Note

ClassDeclaration : class ClassTail 只会作为 ExportDeclaration 的一部分出现,其绑定的建立由该产生式的求值动作处理。参见 16.2.3.7

15.7.16 运行时语义:求值 (Runtime Semantics: Evaluation)

ClassDeclaration : class BindingIdentifier ClassTail
  1. 执行 ? BindingClassDeclarationEvaluation of 此 ClassDeclaration
  2. 返回 empty
Note

ClassDeclaration : class ClassTail 仅作为 ExportDeclaration 的一部分出现,且不会被直接求值。

ClassExpression : class ClassTail
  1. sourceTextClassExpression 匹配的源文本。
  2. 返回 ? ClassDefinitionEvaluation of ClassTail,参数 undefined""sourceText
ClassExpression : class BindingIdentifier ClassTail
  1. classNameBindingIdentifier 的 StringValue。
  2. sourceTextClassExpression 匹配的源文本。
  3. 返回 ? ClassDefinitionEvaluation of ClassTail,参数 classNameclassNamesourceText
ClassElementName : PrivateIdentifier
  1. privateIdentifierPrivateIdentifier 的 StringValue。
  2. privateEnvRec 为运行执行上下文的 PrivateEnvironment。
  3. namesprivateEnvRec.[[Names]]
  4. 断言:names 中恰有一个 Private Name[[Description]]privateIdentifier
  5. privateNamenames[[Description]]privateIdentifierPrivate Name
  6. 返回 privateName
ClassStaticBlockStatementList : [empty]
  1. 返回 undefined

15.8 异步函数定义 (Async Function Definitions)

语法 (Syntax)

AsyncFunctionDeclaration[Yield, Await, Default] : async [no LineTerminator here] function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } [+Default] async [no LineTerminator here] function ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionExpression : async [no LineTerminator here] function BindingIdentifier[~Yield, +Await]opt ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncMethod[Yield, Await] : async [no LineTerminator here] ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionBody : FunctionBody[~Yield, +Await] AwaitExpression[Yield] : await UnaryExpression[?Yield, +Await] Note 1

[Await] 参数存在时,await 被解析为 AwaitExpression 的关键字。[Await] 参数在以下上下文的顶层存在,尽管在某些上下文中(例如 FunctionBody)该参数可能缺失:

Script 是语法目标符号时,如果 [Await] 参数缺失,await 可以被解析为标识符。包括以下情形:

Note 2

不同于 YieldExpression,省略 AwaitExpression 的操作数是语法错误。必须等待某个值。

15.8.1 静态语义:早期错误 (Static Semantics: Early Errors)

AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }

15.8.2 运行时语义:InstantiateAsyncFunctionObject

The syntax-directed operation 运行时语义:InstantiateAsyncFunctionObject takes arguments env (一个 Environment Record) and privateEnv (一个 PrivateEnvironment Recordnull) and returns 一个 ECMAScript 函数对象. It is defined piecewise over the following productions:

AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }
  1. nameBindingIdentifier 的 StringValue。
  2. sourceTextAsyncFunctionDeclaration 匹配的源文本。
  3. FOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, FormalParameters, AsyncFunctionBody, non-lexical-this, env, privateEnv)。
  4. 执行 SetFunctionName(F, name)。
  5. 返回 F
AsyncFunctionDeclaration : async function ( FormalParameters ) { AsyncFunctionBody }
  1. sourceTextAsyncFunctionDeclaration 匹配的源文本。
  2. FOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, FormalParameters, AsyncFunctionBody, non-lexical-this, env, privateEnv)。
  3. 执行 SetFunctionName(F, "default")。
  4. 返回 F

15.8.3 运行时语义:InstantiateAsyncFunctionExpression : 一个 ECMAScript 函数对象

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

AsyncFunctionExpression : async function ( FormalParameters ) { AsyncFunctionBody }
  1. name 不存在,设 name""
  2. env 为运行执行上下文的 LexicalEnvironment。
  3. privateEnv 为运行执行上下文的 PrivateEnvironment。
  4. sourceTextAsyncFunctionExpression 匹配的源文本。
  5. closureOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, FormalParameters, AsyncFunctionBody, non-lexical-this, env, privateEnv)。
  6. 执行 SetFunctionName(closure, name)。
  7. 返回 closure
AsyncFunctionExpression : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }
  1. 断言:name 不存在。
  2. nameBindingIdentifier 的 StringValue。
  3. outerEnv 为运行执行上下文的 LexicalEnvironment。
  4. funcEnvNewDeclarativeEnvironment(outerEnv)。
  5. 执行 ! funcEnv.CreateImmutableBinding(name, false)。
  6. privateEnv 为运行执行上下文的 PrivateEnvironment。
  7. sourceTextAsyncFunctionExpression 匹配的源文本。
  8. closureOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, FormalParameters, AsyncFunctionBody, non-lexical-this, funcEnv, privateEnv)。
  9. 执行 SetFunctionName(closure, name)。
  10. 执行 ! funcEnv.InitializeBinding(name, closure)。
  11. 返回 closure
Note

AsyncFunctionExpression 中的 BindingIdentifier 可在其 AsyncFunctionBody 内引用以允许函数自递归。然而,与 FunctionDeclaration 不同,AsyncFunctionExpression 中的 BindingIdentifier 不能被其外层作用域引用,也不影响外层作用域。

15.8.4 运行时语义:EvaluateAsyncFunctionBody

The syntax-directed operation 运行时语义:EvaluateAsyncFunctionBody takes arguments functionObject (一个 ECMAScript 函数对象) and argumentsList (ECMAScript 语言值列表) and returns 一个 return completion. It is defined piecewise over the following productions:

AsyncFunctionBody : FunctionBody
  1. promiseCapability 为 ! NewPromiseCapability(%Promise%)。
  2. completionCompletion(FunctionDeclarationInstantiation(functionObject, argumentsList))。
  3. completion 是突然完成,则
    1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « completion.[[Value]] »)。
  4. 否则,
    1. 执行 AsyncFunctionStart(promiseCapability, FunctionBody)。
  5. 返回 ReturnCompletion(promiseCapability.[[Promise]])。

15.8.5 运行时语义:求值 (Runtime Semantics: Evaluation)

AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 InstantiateAsyncFunctionExpression of AsyncFunctionExpression
AwaitExpression : await UnaryExpression
  1. exprRef 为 ? Evaluation of UnaryExpression
  2. value 为 ? GetValue(exprRef)。
  3. 返回 ? Await(value)。

15.9 异步箭头函数定义 (Async Arrow Function Definitions)

语法 (Syntax)

AsyncArrowFunction[In, Yield, Await] : async [no LineTerminator here] AsyncArrowBindingIdentifier[?Yield] [no LineTerminator here] => AsyncConciseBody[?In] CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody[?In] AsyncConciseBody[In] : [lookahead ≠ {] ExpressionBody[?In, +Await] { AsyncFunctionBody } AsyncArrowBindingIdentifier[Yield] : BindingIdentifier[?Yield, +Await] CoverCallExpressionAndAsyncArrowHead[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

补充语法 (Supplemental Syntax)

处理产生式实例:
AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
时,对 CoverCallExpressionAndAsyncArrowHead 的解释使用下列语法细化:

AsyncArrowHead : async [no LineTerminator here] ArrowFormalParameters[~Yield, +Await]

15.9.1 静态语义:早期错误 (Static Semantics: Early Errors)

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody

15.9.2 静态语义:AsyncConciseBodyContainsUseStrict

The syntax-directed operation 静态语义:AsyncConciseBodyContainsUseStrict takes no arguments and returns Boolean. It is defined piecewise over the following productions:

AsyncConciseBody : ExpressionBody
  1. 返回 false
AsyncConciseBody : { AsyncFunctionBody }
  1. 返回 FunctionBodyContainsUseStrict(AsyncFunctionBody)。

15.9.3 运行时语义:EvaluateAsyncConciseBody

The syntax-directed operation 运行时语义:EvaluateAsyncConciseBody takes arguments functionObject (一个 ECMAScript 函数对象) and argumentsList (ECMAScript 语言值列表) and returns 一个 return completion. It is defined piecewise over the following productions:

AsyncConciseBody : ExpressionBody
  1. promiseCapability 为 ! NewPromiseCapability(%Promise%)。
  2. completionCompletion(FunctionDeclarationInstantiation(functionObject, argumentsList))。
  3. completion 为突然完成,则
    1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « completion.[[Value]] »)。
  4. 否则,
    1. 执行 AsyncFunctionStart(promiseCapability, ExpressionBody)。
  5. 返回 ReturnCompletion(promiseCapability.[[Promise]])。

15.9.4 运行时语义:InstantiateAsyncArrowFunctionExpression : 一个 ECMAScript 函数对象

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody
  1. name 不存在,设 name""
  2. env 为当前执行上下文的 LexicalEnvironment。
  3. privateEnv 为当前执行上下文的 PrivateEnvironment。
  4. sourceTextAsyncArrowFunction 匹配的源文本。
  5. parametersAsyncArrowBindingIdentifier
  6. closureOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, parameters, AsyncConciseBody, lexical-this, env, privateEnv)。
  7. 执行 SetFunctionName(closure, name)。
  8. 返回 closure
AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. name 不存在,设 name""
  2. env 为当前执行上下文的 LexicalEnvironment。
  3. privateEnv 为当前执行上下文的 PrivateEnvironment。
  4. sourceTextAsyncArrowFunction 匹配的源文本。
  5. headCoverCallExpressionAndAsyncArrowHead 覆盖AsyncArrowHead
  6. parametersheadArrowFormalParameters
  7. closureOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, parameters, AsyncConciseBody, lexical-this, env, privateEnv)。
  8. 执行 SetFunctionName(closure, name)。
  9. 返回 closure

15.9.5 运行时语义:求值 (Runtime Semantics: Evaluation)

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. 返回 InstantiateAsyncArrowFunctionExpression of AsyncArrowFunction

15.10 尾位置调用 (Tail Position Calls)

15.10.1 静态语义:IsInTailPosition ( call )

The abstract operation 静态语义:IsInTailPosition takes argument call (一个 CallExpression 解析节点MemberExpression 解析节点OptionalChain 解析节点) and returns Boolean. It performs the following steps when called:

  1. 若 IsStrict(call) 为 false,返回 false
  2. call 不被包含在 FunctionBodyConciseBodyAsyncConciseBody 内,返回 false
  3. body 为最贴近包含 callFunctionBodyConciseBodyAsyncConciseBody
  4. bodyGeneratorBodyFunctionBody,返回 false
  5. bodyAsyncFunctionBodyFunctionBody,返回 false
  6. bodyAsyncGeneratorBodyFunctionBody,返回 false
  7. bodyAsyncConciseBody,返回 false
  8. 返回 HasCallInTailPosition(body, call) 的结果。
Note

尾位置调用仅在严格模式代码中定义,这是因为存在常见的非标准语言扩展(参见 10.2.4)允许观察调用者上下文链。

15.10.2 静态语义:HasCallInTailPosition

The syntax-directed operation 静态语义:HasCallInTailPosition takes argument call (一个 CallExpression 解析节点MemberExpression 解析节点OptionalChain 解析节点) and returns Boolean.

Note 1

call 是表示特定源文本范围的解析节点。以下算法比较 call 与另一解析节点时,测试的是它们是否表示同一段源文本。

Note 2

紧随其后的 return GetValue(调用结果) 的潜在尾位置调用同样视为可能的尾位置调用。函数调用不会返回 Reference Record,因此该 GetValue 操作总会返回与函数调用结果相同的值。

It is defined piecewise over the following productions:

StatementList : StatementList StatementListItem
  1. has 为 HasCallInTailPosition(StatementList, call)。
  2. hastrue,返回 true
  3. 返回 HasCallInTailPosition(StatementListItem, call)。
FunctionStatementList : [empty] StatementListItem : Declaration Statement : VariableStatement EmptyStatement ExpressionStatement ContinueStatement BreakStatement ThrowStatement DebuggerStatement Block : { } ReturnStatement : return ; LabelledItem : FunctionDeclaration ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement CaseBlock : { }
  1. 返回 false
IfStatement : if ( Expression ) Statement else Statement
  1. has 为第一个 Statement 的 HasCallInTailPosition(call)。
  2. hastrue,返回 true
  3. 返回第二个 Statement 的 HasCallInTailPosition(call)。
IfStatement : if ( Expression ) Statement DoWhileStatement : do Statement while ( Expression ) ; WhileStatement : while ( Expression ) Statement ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement WithStatement : with ( Expression ) Statement
  1. 返回 HasCallInTailPosition(Statement, call)。
LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 HasCallInTailPosition(LabelledItem, call)。
ReturnStatement : return Expression ;
  1. 返回 HasCallInTailPosition(Expression, call)。
SwitchStatement : switch ( Expression ) CaseBlock
  1. 返回 HasCallInTailPosition(CaseBlock, call)。
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. hasfalse
  2. 若首个 CaseClauses 存在,设 has 为 HasCallInTailPosition(首个 CaseClauses, call)。
  3. hastrue,返回 true
  4. has 为 HasCallInTailPosition(DefaultClause, call)。
  5. hastrue,返回 true
  6. 若第二个 CaseClauses 存在,设 has 为 HasCallInTailPosition(第二个 CaseClauses, call)。
  7. 返回 has
CaseClauses : CaseClauses CaseClause
  1. has 为 HasCallInTailPosition(CaseClauses, call)。
  2. hastrue,返回 true
  3. 返回 HasCallInTailPosition(CaseClause, call)。
CaseClause : case Expression : StatementListopt DefaultClause : default : StatementListopt
  1. StatementList 存在,返回 HasCallInTailPosition(StatementList, call)。
  2. 返回 false
TryStatement : try Block Catch
  1. 返回 HasCallInTailPosition(Catch, call)。
TryStatement : try Block Finally try Block Catch Finally
  1. 返回 HasCallInTailPosition(Finally, call)。
Catch : catch ( CatchParameter ) Block
  1. 返回 HasCallInTailPosition(Block, call)。
AssignmentExpression : YieldExpression ArrowFunction AsyncArrowFunction LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression CallExpression : SuperCall ImportCall CallExpression [ Expression ] CallExpression . IdentifierName CallExpression . PrivateIdentifier NewExpression : new NewExpression MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier PrimaryExpression : this IdentifierReference Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral
  1. 返回 false
Expression : AssignmentExpression Expression , AssignmentExpression
  1. 返回 HasCallInTailPosition(AssignmentExpression, call)。
ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
  1. has 为第一个 AssignmentExpression 的 HasCallInTailPosition(call)。
  2. hastrue,返回 true
  3. 返回第二个 AssignmentExpression 的 HasCallInTailPosition(call)。
LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
  1. 返回 HasCallInTailPosition(BitwiseORExpression, call)。
LogicalORExpression : LogicalORExpression || LogicalANDExpression
  1. 返回 HasCallInTailPosition(LogicalANDExpression, call)。
CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression
  1. 返回 HasCallInTailPosition(BitwiseORExpression, call)。
CallExpression : CoverCallExpressionAndAsyncArrowHead CallExpression Arguments CallExpression TemplateLiteral
  1. 若此 CallExpressioncall,返回 true
  2. 返回 false
OptionalExpression : MemberExpression OptionalChain CallExpression OptionalChain OptionalExpression OptionalChain
  1. 返回 HasCallInTailPosition(OptionalChain, call)。
OptionalChain : ?. [ Expression ] ?. IdentifierName ?. PrivateIdentifier OptionalChain [ Expression ] OptionalChain . IdentifierName OptionalChain . PrivateIdentifier
  1. 返回 false
OptionalChain : ?. Arguments OptionalChain Arguments
  1. 若此 OptionalChaincall,返回 true
  2. 返回 false
MemberExpression : MemberExpression TemplateLiteral
  1. 若此 MemberExpressioncall,返回 true
  2. 返回 false
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprCoverParenthesizedExpressionAndArrowParameterList 覆盖ParenthesizedExpression
  2. 返回 HasCallInTailPosition(expr, call)。
ParenthesizedExpression : ( Expression )
  1. 返回 HasCallInTailPosition(Expression, call)。

15.10.3 PrepareForTailCall ( )

The abstract operation PrepareForTailCall takes no arguments and returns unused. It performs the following steps when called:

  1. 断言:当前执行上下文在后续不会再用于求值任意 ECMAScript 代码或内建函数。调用本抽象操作之后的 Call 调用将在进行任何此类求值前创建并压入一个新的执行上下文。
  2. 丢弃与当前执行上下文关联的所有资源。
  3. 返回 unused

尾位置调用必须在调用目标函数前释放与当前正在执行的函数执行上下文关联的任何瞬态内部资源,或复用这些资源以支持目标函数。

Note

例如,尾位置调用应当只按“目标函数激活记录大小减去调用方激活记录大小”的差额增长实现的激活记录栈;若目标函数的激活记录更小,则栈总大小应减小。

16 ECMAScript 语言:脚本与模块

16.1 脚本 (Scripts)

语法 (Syntax)

Script : ScriptBodyopt ScriptBody : StatementList[~Yield, ~Await, ~Return]

16.1.1 静态语义:早期错误 (Static Semantics: Early Errors)

Script : ScriptBody
  • ScriptBody 的 LexicallyDeclaredNames 含有任意重复条目,则为语法错误。
  • ScriptBody 的 LexicallyDeclaredNames 中任一元素也出现在 ScriptBody 的 VarDeclaredNames 中,则为语法错误。
ScriptBody : StatementList
  • StatementList Contains supertrue(除非包含 super 的源文本为正通过直接 eval 处理的 eval 代码),则为语法错误。直接 eval 中 super 的额外早期错误规则定义在 19.2.1.1
  • StatementList Contains NewTargettrue(除非包含 NewTarget 的源文本为正通过直接 eval 处理的 eval 代码),则为语法错误。直接 eval 中 NewTarget 的额外早期错误规则定义在 19.2.1.1
  • 若 ContainsDuplicateLabels(StatementList, « ») 为 true,则为语法错误。
  • 若 ContainsUndefinedBreakTarget(StatementList, « ») 为 true,则为语法错误。
  • 若 ContainsUndefinedContinueTarget(StatementList, « », « ») 为 true,则为语法错误。
  • 若 AllPrivateIdentifiersValid(StatementList, « ») 为 false(除非包含 ScriptBody 的源文本为正通过直接 eval 处理的 eval 代码),则为语法错误。

16.1.2 静态语义:ScriptIsStrict

The syntax-directed operation 静态语义:ScriptIsStrict takes no arguments and returns Boolean. It is defined piecewise over the following productions:

Script : ScriptBodyopt
  1. ScriptBody 存在且 ScriptBody 的指令序言包含 Use Strict 指令,返回 true;否则返回 false

16.1.3 运行时语义:求值 (Runtime Semantics: Evaluation)

Script : [empty]
  1. 返回 undefined

16.1.4 脚本记录 (Script Records)

脚本记录封装了正被求值的脚本的信息。每个脚本记录包含 Table 37 中列出的字段。

Table 37: 脚本记录字段
字段名 值类型 含义
[[Realm]] 一个 Realm Record 此脚本被创建时所在的领域。
[[ECMAScriptCode]] 一个 Script 解析节点 解析此脚本源文本的结果。
[[LoadedModules]] LoadedModuleRequest Record 的列表 从此脚本导入的说明符字符串到已解析的 Module Record 的映射。列表不包含两个不同的记录 r1r2 使得 ModuleRequestsEqual(r1, r2) 为 true
[[HostDefined]] 任意类型(默认值为 empty 为需要将额外信息与脚本关联的宿主环境保留的字段。

16.1.5 ParseScript ( sourceText, realm, hostDefined )

The abstract operation ParseScript takes arguments sourceText (ECMAScript 源文本), realm (一个 Realm Record), and hostDefined (任意类型) and returns 一个 Script Record 或非空的 SyntaxError 对象列表. 基于将 sourceText 解析为 Script 的结果创建一个 Script Record。 It performs the following steps when called:

  1. script 为 ParseText(sourceText, Script)。
  2. script 为错误列表,返回 script
  3. 返回 Script Record { [[Realm]]: realm, [[ECMAScriptCode]]: script, [[LoadedModules]]: « », [[HostDefined]]: hostDefined }。
Note

实现可以在对该脚本源文本求值 ParseScript 之前解析脚本源文本并分析早期错误条件。然而,任何错误的报告必须推迟到本规范实际对该源文本执行 ParseScript 的时候。

16.1.6 ScriptEvaluation ( scriptRecord )

The abstract operation ScriptEvaluation takes argument scriptRecord (一个 Script Record) and returns 正常完成(包含一个 ECMAScript 语言值)或突然完成. It performs the following steps when called:

  1. globalEnvscriptRecord.[[Realm]].[[GlobalEnv]]
  2. scriptContext 为一个新的 ECMAScript 代码执行上下文
  3. scriptContext 的 Function 为 null
  4. scriptContextRealmscriptRecord.[[Realm]]
  5. scriptContext 的 ScriptOrModule 为 scriptRecord
  6. scriptContext 的 VariableEnvironment 为 globalEnv
  7. scriptContext 的 LexicalEnvironment 为 globalEnv
  8. scriptContext 的 PrivateEnvironment 为 null
  9. 暂停正在运行的执行上下文。
  10. scriptContext 压入执行上下文栈;scriptContext 现在成为正在运行的执行上下文。
  11. scriptscriptRecord.[[ECMAScriptCode]]
  12. resultCompletion(GlobalDeclarationInstantiation(script, globalEnv))。
  13. result正常完成,则
    1. resultCompletion(Evaluation of script)。
    2. result正常完成result.[[Value]]empty,则
      1. resultNormalCompletion(undefined)。
  14. 暂停 scriptContext 并从执行上下文栈中移除它。
  15. 断言:执行上下文栈非空。
  16. 恢复现在位于执行上下文栈顶的上下文作为正在运行的执行上下文。
  17. 返回 ? result

16.1.7 GlobalDeclarationInstantiation ( script, env )

The abstract operation GlobalDeclarationInstantiation takes arguments script (一个 Script 解析节点) and env (一个 Global Environment Record) and returns 正常完成(包含 unused)或 throw completion. script 是正为其建立执行上下文的 Scriptenv 是要在其中创建绑定的全局环境。

Note 1

当为求值脚本建立执行上下文时,声明在当前全局环境中实例化。代码中声明的每个全局绑定都被实例化。

被调用时执行以下步骤:

  1. lexNamesscript 的 LexicallyDeclaredNames。
  2. varNamesscript 的 VarDeclaredNames。
  3. lexNames 的每个元素 name
    1. HasLexicalDeclaration(env, name) 为 true,抛出 SyntaxError 异常。
    2. hasRestrictedGlobal 为 ? HasRestrictedGlobalProperty(env, name)。
    3. 注:全局 varfunction 绑定(除了由非严格直接 eval 引入的那些)是不可配置的,因此是受限的全局属性。
    4. hasRestrictedGlobaltrue,抛出 SyntaxError 异常。
  4. varNames 的每个元素 name
    1. HasLexicalDeclaration(env, name) 为 true,抛出 SyntaxError 异常。
  5. varDeclarationsscript 的 VarScopedDeclarations。
  6. functionsToInitialize 为新的空列表。
  7. declaredFunctionNames 为新的空列表。
  8. varDeclarations 的每个元素 d,以反向列表顺序:
    1. d 既不是 VariableDeclarationForBinding 也不是 BindingIdentifier,则
      1. 断言:dFunctionDeclarationGeneratorDeclarationAsyncFunctionDeclarationAsyncGeneratorDeclaration
      2. 注:若同一名称有多个函数声明,使用最后的声明。
      3. fnd 的 BoundNames 的唯一元素。
      4. declaredFunctionNames 不包含 fn,则
        1. fnDefinable 为 ? CanDeclareGlobalFunction(env, fn)。
        2. fnDefinablefalse,抛出 TypeError 异常。
        3. fn 追加到 declaredFunctionNames
        4. d 插入为 functionsToInitialize 的第一个元素。
  9. declaredVarNames 为新的空列表。
  10. varDeclarations 的每个元素 d
    1. dVariableDeclarationForBindingBindingIdentifier,则
      1. d 的 BoundNames 中每个字符串 vn
        1. declaredFunctionNames 不包含 vn,则
          1. vnDefinable 为 ? CanDeclareGlobalVar(env, vn)。
          2. vnDefinablefalse,抛出 TypeError 异常。
          3. declaredVarNames 不包含 vn,则
            1. vn 追加到 declaredVarNames
  11. 注:若全局对象是普通对象,此算法步骤之后不会发生异常终止。然而,若全局对象是 Proxy 异域对象,它可能表现出在某些后续步骤中导致异常终止的行为。
  12. Normative Optional
    宿主是 Web 浏览器或以其他方式支持 块级函数声明 Web 历史兼容语义,则
    1. strict 为 ScriptIsStrict(script)。
    2. strictfalse,则
      1. declaredFunctionOrVarNamesdeclaredFunctionNamesdeclaredVarNames 的列表连接。
      2. 对直接包含在任意 BlockCaseClauseDefaultClause xStatementList 中的每个 FunctionDeclaration f(使得 script Contains xtrue):
        1. FfBindingIdentifier 的 StringValue。
        2. 若将 FunctionDeclaration f 替换为以 F 作为 BindingIdentifierVariableStatement 不会为 script 产生任何早期错误,则
          1. HasLexicalDeclaration(env, F) 为 false,则
            1. fnDefinable 为 ? CanDeclareGlobalVar(env, F)。
            2. fnDefinabletrue,则
              1. 注:F 的 var 绑定仅在它既不是 VarDeclaredName 也不是另一个 FunctionDeclaration 的名称时才在此实例化。
              2. declaredFunctionOrVarNames 不包含 F,则
                1. 执行 ? CreateGlobalVarBinding(env, F, false)。
                2. F 追加到 declaredFunctionOrVarNames
              3. FunctionDeclaration f 被求值时,执行以下步骤而不是 15.2.6 中提供的 FunctionDeclaration 求值算法:
                1. gEnv 为正在运行的执行上下文的 VariableEnvironment。
                2. bEnv 为正在运行的执行上下文的 LexicalEnvironment。
                3. fObj 为 ! bEnv.GetBindingValue(F, false)。
                4. 执行 ? gEnv.SetMutableBinding(F, fObj, false)。
                5. 返回 unused
  13. lexDeclarationsscript 的 LexicallyScopedDeclarations。
  14. privateEnvnull
  15. lexDeclarations 的每个元素 d
    1. 注:词法声明的名称仅在此实例化但不初始化。
    2. d 的 BoundNames 的每个元素 dn
      1. 若 IsConstantDeclaration(d) 为 true,则
        1. 执行 ? env.CreateImmutableBinding(dn, true)。
      2. 否则,
        1. 执行 ? env.CreateMutableBinding(dn, false)。
  16. functionsToInitialize 的每个解析节点 f
    1. fnf 的 BoundNames 的唯一元素。
    2. fo 为 InstantiateFunctionObject(f, env, privateEnv)。
    3. 执行 ? CreateGlobalFunctionBinding(env, fn, fo, false)。
  17. declaredVarNames 的每个字符串 vn
    1. 执行 ? CreateGlobalVarBinding(env, vn, false)。
  18. 返回 unused
Note 2

16.1.1 中指定的早期错误防止了 function/var 声明与 let/const/class 声明之间的名称冲突,以及单个 Script 内声明的 let/const/class 绑定的重复声明。然而,跨越多个 Script 的此类冲突和重复声明在 GlobalDeclarationInstantiation 期间被检测为运行时错误。若检测到任何此类错误,不会为脚本实例化绑定。然而,若全局对象使用 Proxy 异域对象定义,则冲突声明的运行时测试可能不可靠,导致突然完成且某些全局声明未被实例化。若发生这种情况,Script 的代码不会被求值。

与显式的 var 或 function 声明不同,直接在全局对象上创建的属性会产生可能被 let/const/class 声明遮蔽的全局绑定。

16.2 模块 (Modules)

语法 (Syntax)

Module : ModuleBodyopt ModuleBody : ModuleItemList ModuleItemList : ModuleItem ModuleItemList ModuleItem ModuleItem : ImportDeclaration ExportDeclaration StatementListItem[~Yield, +Await, ~Return] ModuleExportName : IdentifierName StringLiteral

16.2.1 模块语义 (Module Semantics)

16.2.1.1 静态语义:早期错误 (Static Semantics: Early Errors)

ModuleBody : ModuleItemList
  • ModuleItemList 的 LexicallyDeclaredNames 包含任何重复条目,则为语法错误。
  • ModuleItemList 的 LexicallyDeclaredNames 中的任何元素也出现在 ModuleItemList 的 VarDeclaredNames 中,则为语法错误。
  • ModuleItemList 的 ExportedNames 包含任何重复条目,则为语法错误。
  • ModuleItemList 的 ExportedBindings 中的任何元素也不出现在 ModuleItemList 的 VarDeclaredNames 或 LexicallyDeclaredNames 中,则为语法错误。
  • ModuleItemList Contains super,则为语法错误。
  • ModuleItemList Contains NewTarget,则为语法错误。
  • 若 ContainsDuplicateLabels(ModuleItemList, « ») 为 true,则为语法错误。
  • 若 ContainsUndefinedBreakTarget(ModuleItemList, « ») 为 true,则为语法错误。
  • 若 ContainsUndefinedContinueTarget(ModuleItemList, « », « ») 为 true,则为语法错误。
  • 若 AllPrivateIdentifiersValid(ModuleItemList, « ») 为 false,则为语法错误。
Note

重复 ExportedNames 规则意味着在 ModuleBody 中有多个 export default ExportDeclaration 项是语法错误。与冲突或重复声明相关的额外错误条件在模块链接期间、Module 求值之前检查。如果检测到任何此类错误,Module 不会被求值。

ModuleExportName : StringLiteral
  • 若 IsStringWellFormedUnicode(SV of StringLiteral) 为 false,则为语法错误。

16.2.1.2 静态语义:ImportedLocalNames ( importEntries )

The abstract operation 静态语义:ImportedLocalNames takes argument importEntries (ImportEntry Record 列表) and returns 字符串列表. 创建由 importEntries 定义的所有本地名称绑定的列表。 It performs the following steps when called:

  1. localNames 为新的空列表。
  2. 对于 importEntries 的每个 ImportEntry Record i
    1. i.[[LocalName]] 追加到 localNames
  3. 返回 localNames

16.2.1.3 ModuleRequest 记录 (ModuleRequest Records)

ModuleRequest Record 表示使用给定导入属性导入模块的请求。它由以下字段组成:

Table 38: ModuleRequest Record 字段
字段名 值类型 含义
[[Specifier]] 字符串 模块说明符
[[Attributes]] ImportAttribute Record 列表 导入属性

LoadedModuleRequest Record 表示导入模块的请求以及生成的 Module Record。它由表 Table 38 中定义的相同字段组成,另外添加了 [[Module]]

Table 39: LoadedModuleRequest Record 字段
字段名 值类型 含义
[[Specifier]] 字符串 模块说明符
[[Attributes]] ImportAttribute Record 列表 导入属性
[[Module]] Module Record 对应此模块请求的已加载模块

ImportAttribute Record 由以下字段组成:

Table 40: ImportAttribute Record 字段
字段名 值类型 含义
[[Key]] 字符串 属性键
[[Value]] 字符串 属性值

16.2.1.3.1 ModuleRequestsEqual ( left, right )

The abstract operation ModuleRequestsEqual takes arguments left (ModuleRequest RecordLoadedModuleRequest Record) and right (ModuleRequest RecordLoadedModuleRequest Record) and returns Boolean. It performs the following steps when called:

  1. left.[[Specifier]] 不是 right.[[Specifier]],返回 false
  2. leftAttrsleft.[[Attributes]]
  3. rightAttrsright.[[Attributes]]
  4. leftAttrsCountleftAttrs 中元素的数量。
  5. rightAttrsCountrightAttrs 中元素的数量。
  6. leftAttrsCountrightAttrsCount,返回 false
  7. 对于 leftAttrs 的每个 ImportAttribute Record l
    1. rightAttrs 不包含满足 l.[[Key]]r.[[Key]]l.[[Value]]r.[[Value]]ImportAttribute Record r,返回 false
  8. 返回 true

16.2.1.4 静态语义:ModuleRequests

The syntax-directed operation 静态语义:ModuleRequests takes no arguments and returns ModuleRequest Record 列表. It is defined piecewise over the following productions:

Module : [empty]
  1. 返回新的空列表。
ModuleItemList : ModuleItem
  1. 返回 ModuleItem 的 ModuleRequests。
ModuleItemList : ModuleItemList ModuleItem
  1. requestsModuleItemList 的 ModuleRequests。
  2. additionalRequestsModuleItem 的 ModuleRequests。
  3. 对于 additionalRequests 的每个 ModuleRequest Record mr
    1. requests 不包含满足 ModuleRequestsEqual(mr, mr2) 为 trueModuleRequest Record mr2,则
      1. mr 追加到 requests
  4. 返回 requests
ModuleItem : StatementListItem
  1. 返回新的空列表。
ImportDeclaration : import ImportClause FromClause ;
  1. specifierFromClause 的 SV。
  2. 返回唯一元素为 ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: « » } 的列表。
ImportDeclaration : import ImportClause FromClause WithClause ;
  1. specifierFromClause 的 SV。
  2. attributes 为 WithClauseToAttributes of WithClause
  3. 返回唯一元素为 ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: attributes } 的列表。
ImportDeclaration : import ModuleSpecifier ;
  1. specifierModuleSpecifier 的 SV。
  2. 返回唯一元素为 ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: « » } 的列表。
ImportDeclaration : import ModuleSpecifier WithClause ;
  1. specifierModuleSpecifier 的 SV。
  2. attributes 为 WithClauseToAttributes of WithClause
  3. 返回唯一元素为 ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: attributes } 的列表。
ExportDeclaration : export ExportFromClause FromClause ;
  1. specifierFromClause 的 SV。
  2. 返回唯一元素为 ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: « » } 的列表。
ExportDeclaration : export ExportFromClause FromClause WithClause ;
  1. specifierFromClause 的 SV。
  2. attributes 为 WithClauseToAttributes of WithClause
  3. 返回唯一元素为 ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: attributes } 的列表。
ExportDeclaration : export NamedExports ; export VariableStatement export Declaration export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression ;
  1. 返回新的空列表。

16.2.1.5 抽象模块记录 (Abstract Module Records)

Module Record 封装了关于单个模块导入和导出的结构信息。这些信息用于链接连接模块集合的导入和导出。Module Record 包含四个仅在求值模块时使用的字段。

出于规范目的,Module Record 值是 Record 规范类型的值,可以看作存在于简单的面向对象层次结构中,其中 Module Record 是具有抽象和具体子类的抽象类。本规范定义了名为 Cyclic Module Record 的抽象子类及其名为 Source Text Module Record 的具体子类。其他规范和实现可以定义对应于它们所定义的替代模块定义工具的其他 Module Record 子类。

Module Record 定义了 Table 41 中列出的字段。所有 Module Definition 子类至少包含这些字段。Module Record 还定义了 Table 42 中的抽象方法列表。所有 Module definition 子类必须提供这些抽象方法的具体实现。

Table 41: Module Record 字段
字段名 值类型 含义
[[Realm]] Realm Record 创建此模块的领域。
[[Environment]] Module Environment Recordempty 包含此模块顶级绑定的 Environment Record。此字段在模块链接时设置。
[[Namespace]] Object 或 empty Module Namespace Object(28.3),如果已为此模块创建。
[[HostDefined]] 任意类型(默认值为 undefined 为需要将附加信息与模块关联的宿主环境保留的字段。
Table 42: Module Record 的抽象方法
方法 目的
LoadRequestedModules([hostDefined])

通过递归加载所有依赖项来准备模块以进行链接,并返回一个 promise。

GetExportedNames([exportStarSet])

返回从此模块直接或间接导出的所有名称的列表。

在调用此方法之前,LoadRequestedModules 必须已成功完成。

ResolveExport(exportName [, resolveSet])

返回此模块导出的名称的绑定。绑定由 ResolvedBinding Record 表示,形式为 { [[Module]]: Module Record, [[BindingName]]: String | namespace }。如果导出是没有任何模块中直接绑定的 Module Namespace Object,[[BindingName]] 将设置为 namespace。如果名称无法解析则返回 null,如果找到多个绑定则返回 ambiguous

每次使用特定 exportNameresolveSet 对作为参数调用此操作时,必须返回相同结果。

在调用此方法之前,LoadRequestedModules 必须已成功完成。

Link()

通过传递性地解析所有模块依赖项并创建 Module Environment Record 来准备模块以进行求值。

在调用此方法之前,LoadRequestedModules 必须已成功完成。

Evaluate()

返回此模块及其依赖项求值的 promise,在成功求值或已成功求值时解决,在求值错误或已求值失败时拒绝。如果 promise 被拒绝,期望宿主处理 promise 拒绝并重新抛出求值错误。

在调用此方法之前,Link 必须已成功完成。

16.2.1.5.1 EvaluateModuleSync ( module )

The abstract operation EvaluateModuleSync takes argument module (Module Record) and returns 包含 unused正常完成或 throw completion. 同步求值 module,前提是调用者保证 module 的求值将返回已定已 promise。 It performs the following steps when called:

  1. 断言:module 不是 Cyclic Module Record
  2. promisemodule.Evaluate()。
  3. 断言:promise.[[PromiseState]]fulfilledrejected
  4. promise.[[PromiseState]]rejected,则
    1. promise.[[PromiseIsHandled]]false,执行 HostPromiseRejectionTracker(promise, "handle")。
    2. promise.[[PromiseIsHandled]]true
    3. 返回 ThrowCompletion(promise.[[PromiseResult]])。
  5. 返回 unused

16.2.1.6 循环模块记录 (Cyclic Module Records)

Cyclic Module Record(循环模块记录) 用于表示一个模块与其它同属 Cyclic Module Record 类型子类的模块之间可以形成依赖环的信息。不是 Cyclic Module Record 类型子类的 Module Record 不得与 Source Text Module Record 形成依赖环。

Table 41 中定义的字段外,循环模块记录还具有 Table 43 中列出的附加字段。

Table 43: 循环模块记录的附加字段 (Additional Fields of Cyclic Module Records)
字段名 (Field Name) 值类型 (Value Type) 含义 (Meaning)
[[Status]] new, unlinked, linking, linked, evaluating, evaluating-async, 或 evaluated 初始为 new。在模块生命周期推进过程中按顺序转变为 unlinked, linking, linked, evaluating, 可能的 evaluating-async, 最终 evaluatedevaluating-async 表示该模块已排队等待其异步依赖完成后执行,或其 [[HasTLA]]true 且已开始执行,正在等待顶层完成。
[[EvaluationError]] throw completion 或 empty 表示求值期间发生的异常的 throw completion。若无异常或 [[Status]] 不是 evaluated,则为 undefined
[[DFSAncestorIndex]] 整数或 empty 仅在 Link 与 Evaluate 过程中使用的辅助字段。若 [[Status]]linkingevaluating,此值为该模块的深度优先遍历索引或其所在强连通分量中“更早”模块的索引。
[[RequestedModules]] ModuleRequest Record 列表 与该模块中的 import 相关联的 ModuleRequest Record 列表,按源码出现顺序排列。
[[LoadedModules]] LoadedModuleRequest Record 列表 将此记录所代表模块使用的说明符字符串(及相对导入属性)映射到解析得到的 Module Record。该列表不包含两个不同记录 r1r2 使得 ModuleRequestsEqual(r1, r2) 为 true
[[CycleRoot]] Cyclic Module Recordempty 环的首个访问模块,即强连通分量(SCC)的深度优先根祖先。对不在环中的模块,该字段为其自身。Evaluate 完成后,模块的 [[DFSAncestorIndex]] 等于其 [[CycleRoot]] 的深度优先遍历索引。
[[HasTLA]] Boolean 该模块自身是否为异步(例如包含顶层 await 的 Source Text Module Record)。拥有异步依赖不意味着此字段为 true。解析后不得再改变。
[[AsyncEvaluationOrder]] unset、整数或 done 初始为 unset,同步模块保持 unset。对自身异步或拥有异步依赖的模块,设为一个整数,用于决定 16.2.1.6.1.3.4 排队执行的顺序。待执行完毕后设为 done
[[TopLevelCapability]] PromiseCapability Recordempty 若此模块是某个环的 [[CycleRoot]] 且对该环中某模块调用了 Evaluate(),此字段保存该整体求值的 PromiseCapability,用于完成 Evaluate() 返回的 Promise。除非对依赖发起顶层 Evaluate(),否则依赖的该字段为 empty
[[AsyncParentModules]] Cyclic Module Record 列表 若此模块或其依赖具有 [[HasTLA]] true 且执行中,记录在顶层执行作业中依赖它的父导入者。在其完成之前这些父模块不会开始执行。
[[PendingAsyncDependencies]] 整数或 empty 若该模块有异步依赖,此值跟踪剩余尚未执行完成的异步依赖模块数量。计数降至 0 且无执行错误时,该模块执行。

Table 42 中的方法外,循环模块记录还具有 Table 44 中列出的附加抽象方法。

Table 44: 循环模块记录的附加抽象方法 (Additional Abstract Methods of Cyclic Module Records)
方法 (Method) 目的 (Purpose)
InitializeEnvironment() 初始化模块的 Environment Record(包括解析全部导入绑定)并创建模块的执行上下文。
ExecuteModule([promiseCapability]) 在其执行上下文内求值模块代码。若模块 [[HasTLA]]true,则传入 PromiseCapability Record,方法应 resolve 或 reject 该能力;此时不得抛出异常,需通过 reject 处理。

GraphLoadingState Record(图加载状态记录) 是包含模块图加载流程信息的记录,用于在 HostLoadImportedModule 调用后继续加载。每个记录包含 Table 45 中的字段:

Table 45: 图加载状态记录字段 (GraphLoadingState Record Fields)
字段名 (Field Name) 值类型 (Value Type) 含义 (Meaning)
[[PromiseCapability]] PromiseCapability Record 加载流程完成时要 resolve 的 promise。
[[IsLoading]] Boolean 若加载流程尚未成功或失败完成则为 true
[[PendingModulesCount]] 非负整数 跟踪未完成 HostLoadImportedModule 调用的数量。
[[Visited]] Cyclic Module Record 列表 已在本次加载过程中加载的循环模块集合,用于避免循环依赖无限循环。
[[HostDefined]] 任意(默认 empty 宿主传入、供 LoadRequestedModules 到 HostLoadImportedModule 传递的宿主定义数据。

16.2.1.6.1 模块记录抽象方法的具体实现 (Implementation of Module Record Abstract Methods)

以下为循环模块记录对 Table 42 中相应模块记录抽象方法的具体实现。

16.2.1.6.1.1 LoadRequestedModules ( [ hostDefined ] )

The LoadRequestedModules concrete method of Cyclic Module Record module takes optional argument hostDefined (anything) and returns Promise. 填充 module 依赖图中所有 Module Record[[LoadedModules]](主要工作由辅助函数 InnerModuleLoading 完成)。可选参数 hostDefined 将传递给 HostLoadImportedModule 钩子。 It performs the following steps when called:

  1. hostDefined 未传入,令 hostDefinedempty
  2. pc 为 ! NewPromiseCapability(%Promise%)。
  3. state 为 GraphLoadingState Record { [[IsLoading]]: true, [[PendingModulesCount]]: 1, [[Visited]]: « », [[PromiseCapability]]: pc, [[HostDefined]]: hostDefined }。
  4. 执行 InnerModuleLoading(state, module)。
  5. 返回 pc.[[Promise]]
Note
参数 hostDefined 可传递获取导入模块所需的额外信息。例如 HTML 用它为 <link rel="preload" as="..."> 设置正确的 fetch destination。import() 表达式不会设置该参数。

16.2.1.6.1.1.1 InnerModuleLoading ( state, module )

The abstract operation InnerModuleLoading takes arguments state (GraphLoadingState Record) and module (Module Record) and returns unused. 被 LoadRequestedModules 使用,递归执行 module 依赖图的实际加载过程。 It performs the following steps when called:

  1. 断言:state.[[IsLoading]]true
  2. module 是 Cyclic Module Recordmodule.[[Status]]newstate.[[Visited]] 不含 module,则
    1. module 追加至 state.[[Visited]]
    2. requestedModulesCountmodule.[[RequestedModules]] 的元素数。
    3. state.[[PendingModulesCount]] = state.[[PendingModulesCount]] + requestedModulesCount
    4. module.[[RequestedModules]] 每个 ModuleRequest Record request
      1. AllImportAttributesSupported(request.[[Attributes]]) 为 false,则
        1. errorThrowCompletion(新建的 SyntaxError 对象)。
        2. 执行 ContinueModuleLoading(state, error)。
      2. 否则若 module.[[LoadedModules]]LoadedModuleRequest Record record 使 ModuleRequestsEqual(record, request) 为 true,则
        1. 执行 InnerModuleLoading(state, record.[[Module]])。
      3. 否则,
        1. 执行 HostLoadImportedModule(module, request, state.[[HostDefined]], state)。
        2. 注:HostLoadImportedModule 将调用 FinishLoadingImportedModule,经由 ContinueModuleLoading 重新进入图加载流程。
      4. state.[[IsLoading]]false,返回 unused
  3. 断言:state.[[PendingModulesCount]] ≥ 1。
  4. state.[[PendingModulesCount]] = state.[[PendingModulesCount]] - 1。
  5. state.[[PendingModulesCount]] = 0,则
    1. state.[[IsLoading]] = false
    2. state.[[Visited]] 中每个 Cyclic Module Record loaded
      1. loaded.[[Status]]new,设其为 unlinked
    3. 执行 ! Call(state.[[PromiseCapability]].[[Resolve]], undefined, « undefined »)。
  6. 返回 unused

16.2.1.6.1.1.2 ContinueModuleLoading ( state, moduleCompletion )

The abstract operation ContinueModuleLoading takes arguments state (GraphLoadingState Record) and moduleCompletion (正常完成(含 Module Record)或 throw completion) and returns unused. 在 HostLoadImportedModule 返回后重新进入加载流程。 It performs the following steps when called:

  1. state.[[IsLoading]]false,返回 unused
  2. moduleCompletion正常完成,则
    1. 执行 InnerModuleLoading(state, moduleCompletion.[[Value]])。
  3. 否则,
    1. state.[[IsLoading]] = false
    2. 执行 ! Call(state.[[PromiseCapability]].[[Reject]], undefined, « moduleCompletion.[[Value]] »)。
  4. 返回 unused

16.2.1.6.1.2 Link ( )

The Link concrete method of Cyclic Module Record module takes no arguments and returns 正常完成(含 unused)或 throw completion. 成功时将 [[Status]]unlinked 过渡到 linked。失败时抛出异常且保持 unlinked。(主要工作由辅助函数 InnerModuleLinking 完成。) It performs the following steps when called:

  1. 断言:module.[[Status]] 属于 unlinked, linked, evaluating-async, evaluated 之一。
  2. stack 为新空列表。
  3. resultCompletion(InnerModuleLinking(module, stack, 0))。
  4. result 为突然完成,则
    1. stack 中每个 Cyclic Module Record m
      1. 断言:m.[[Status]]linking
      2. m.[[Status]] = unlinked
    2. 断言:module.[[Status]]unlinked
    3. 返回 ? result
  5. 断言:module.[[Status]] 属于 linked, evaluating-async, evaluated
  6. 断言:stack 为空。
  7. 返回 unused

16.2.1.6.1.2.1 InnerModuleLinking ( module, stack, index )

The abstract operation InnerModuleLinking takes arguments module (Module Record), stack (Cyclic Module Record 列表), and index (非负整数) and returns 正常完成(含非负整数)或 throw completion. Link 使用它执行 module 的实际链接,并递归链接其依赖图的其它模块。参数 stackindex 以及模块的 [[DFSAncestorIndex]] 用于跟踪深度优先遍历(DFS),借此发现强连通分量(SCC),确保同一 SCC 内模块一起转为 linked。 It performs the following steps when called:

  1. module 不是 Cyclic Module Record,则
    1. 执行 ? module.Link()。
    2. 返回 index
  2. module.[[Status]] 属于 linking, linked, evaluating-async, evaluated,则
    1. 返回 index
  3. 断言:module.[[Status]]unlinked
  4. module.[[Status]] = linking
  5. moduleIndex = index
  6. module.[[DFSAncestorIndex]] = index
  7. index = index + 1。
  8. module 追加到 stack
  9. module.[[RequestedModules]] 每个 ModuleRequest Record request
    1. requiredModule = GetImportedModule(module, request)。
    2. index = ? InnerModuleLinking(requiredModule, stack, index)。
    3. requiredModule 是 Cyclic Module Record,则
      1. 断言:其 [[Status]] 属于 linking, linked, evaluating-async, evaluated
      2. 断言:requiredModule.[[Status]]linking 当且仅当 stack 含有它。
      3. 若为 linking,则
        1. module.[[DFSAncestorIndex]] = min(module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]])。
  10. 执行 ? module.InitializeEnvironment()。
  11. 断言:modulestack 中仅出现一次。
  12. 断言:module.[[DFSAncestorIndex]]moduleIndex
  13. module.[[DFSAncestorIndex]] = moduleIndex,则
    1. done = false
    2. donefalse 循环:
      1. requiredModulestack 最末元素。
      2. 移除该末元素。
      3. 断言:requiredModule 为 Cyclic Module Record
      4. requiredModule.[[Status]] = linked
      5. requiredModulemodule 相同,设 done = true
  14. 返回 index

16.2.1.6.1.3 Evaluate ( )

The Evaluate concrete method of Cyclic Module Record module takes no arguments and returns Promise. Evaluate 将 [[Status]]linked 过渡为 evaluating-asyncevaluated。在给定强连通分量中第一次对任一模块调用时创建并返回 Promise,直至模块求值完成。该 Promise 存入该分量 [[CycleRoot]][[TopLevelCapability]]。随后对分量中任何模块的调用返回同一 Promise。(主要工作由 InnerModuleEvaluation 完成。) It performs the following steps when called:

  1. 断言:本次 Evaluate 调用未与同代理内另一 Evaluate 并发。
  2. 断言:module.[[Status]] 属于 linked, evaluating-async, evaluated
  3. [[Status]]evaluating-asyncevaluated,令 module = module.[[CycleRoot]]
  4. module.[[TopLevelCapability]]empty,返回其 [[Promise]]
  5. stack 为新空列表。
  6. capability = ! NewPromiseCapability(%Promise%)。
  7. module.[[TopLevelCapability]] = capability
  8. result = Completion(InnerModuleEvaluation(module, stack, 0))。
  9. result 为突然完成,则
    1. stack 中每个 Cyclic Module Record m
      1. 断言:m.[[Status]]evaluating
      2. 断言:m.[[AsyncEvaluationOrder]]unset
      3. m.[[Status]] = evaluated
      4. m.[[EvaluationError]] = result
    2. 断言:module.[[Status]]evaluated
    3. 断言:module.[[EvaluationError]]result 为同一 Completion Record
    4. 执行 ! Call(capability.[[Reject]], undefined, « result.[[Value]] »)。
  10. 否则,
    1. 断言:module.[[Status]]evaluating-asyncevaluated
    2. 断言:module.[[EvaluationError]]empty
    3. module.[[Status]]evaluated,则
      1. 注:表示同步完成求值。
      2. 断言:module.[[AsyncEvaluationOrder]]unset
      3. 执行 ! Call(capability.[[Resolve]], undefined, « undefined »)。
    4. 断言:stack 为空。
  11. 返回 capability.[[Promise]]

16.2.1.6.1.3.1 InnerModuleEvaluation ( module, stack, index )

The abstract operation InnerModuleEvaluation takes arguments module (Module Record), stack (Cyclic Module Record 列表), and index (非负整数) and returns 正常完成(含非负整数)或 throw completion. Evaluate 使用它执行 module 的实际求值,并递归应用于依赖图的其它模块。stack / index[[DFSAncestorIndex]] 用法与 InnerModuleLinking 相同。 It performs the following steps when called:

  1. module 非 Cyclic Module Record,则
    1. 执行 ? EvaluateModuleSync(module)。
    2. 返回 index
  2. module.[[Status]]evaluating-asyncevaluated,则
    1. [[EvaluationError]]empty,返回 index
    2. 否则返回 ? module.[[EvaluationError]]
  3. module.[[Status]]evaluating,返回 index
  4. 断言:module.[[Status]]linked
  5. module.[[Status]] = evaluating
  6. moduleIndex = index
  7. module.[[DFSAncestorIndex]] = index
  8. module.[[PendingAsyncDependencies]] = 0。
  9. index = index + 1。
  10. module 追加至 stack
  11. module.[[RequestedModules]] 每个 ModuleRequest Record request
    1. requiredModule = GetImportedModule(module, request)。
    2. index = ? InnerModuleEvaluation(requiredModule, stack, index)。
    3. requiredModule 为 Cyclic Module Record,则
      1. 断言:其 [[Status]] 属于 evaluating, evaluating-async, evaluated
      2. 断言:当且仅当 stack 含其时状态为 evaluating
      3. 若为 evaluating,设 module.[[DFSAncestorIndex]] = min(两者索引)。
      4. 否则,
        1. requiredModule = requiredModule.[[CycleRoot]]
        2. 断言:其 [[Status]]evaluating-asyncevaluated
        3. 若其 [[EvaluationError]]empty,返回 ? 该错误。
      5. requiredModule.[[AsyncEvaluationOrder]] 为整数,则
        1. module.[[PendingAsyncDependencies]] += 1。
        2. module 追加至 requiredModule.[[AsyncParentModules]]
  12. module.[[PendingAsyncDependencies]] > 0 或 [[HasTLA]]true,则
    1. 断言:module.[[AsyncEvaluationOrder]]unset
    2. module.[[AsyncEvaluationOrder]] = IncrementModuleAsyncEvaluationCount()。
    3. module.[[PendingAsyncDependencies]] = 0,执行 ExecuteAsyncModule(module)。
  13. 否则,
    1. 执行 ? module.ExecuteModule()
  14. 断言:modulestack 中仅出现一次。
  15. 断言:module.[[DFSAncestorIndex]]moduleIndex
  16. module.[[DFSAncestorIndex]] = moduleIndex,则
    1. done = false
    2. donefalse
      1. requiredModulestack 最末元素并移除。
      2. 断言:其为 Cyclic Module Record
      3. 断言:其 [[AsyncEvaluationOrder]] 为整数或 unset
      4. 若为 unset,设其 [[Status]] = evaluated;否则设为 evaluating-async
      5. 若与 module 相同,设 done = true
      6. requiredModule.[[CycleRoot]] = module
  17. 返回 index
Note 1

模块在 InnerModuleEvaluation 遍历时为 evaluating;若执行完成则为 evaluated,若执行期间自身 [[HasTLA]]true 或有异步依赖则为 evaluating-async

Note 2

依赖某异步环的模块在该环不处于 evaluating 时,通过 [[CycleRoot]] 依赖环根的执行,确保环作为单个强连通分量对待。

16.2.1.6.1.3.2 ExecuteAsyncModule ( module )

The abstract operation ExecuteAsyncModule takes argument module (Cyclic Module Record) and returns unused. It performs the following steps when called:

  1. 断言:module.[[Status]]evaluatingevaluating-async
  2. 断言:module.[[HasTLA]]true
  3. capability = ! NewPromiseCapability(%Promise%)。
  4. fulfilledClosure 为捕获 module 的无参抽象闭包,调用时:
    1. 执行 AsyncModuleExecutionFulfilled(module)。
    2. 返回 NormalCompletion(undefined)。
  5. onFulfilled = CreateBuiltinFunction(fulfilledClosure, 0, "", « »)。
  6. rejectedClosure 为捕获 module 的抽象闭包(参数 error):
    1. 执行 AsyncModuleExecutionRejected(module, error)。
    2. 返回 NormalCompletion(undefined)。
  7. onRejected = CreateBuiltinFunction(rejectedClosure, 0, "", « »)。
  8. 执行 PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected)。
  9. 执行 ! module.ExecuteModule(capability)。
  10. 返回 unused

16.2.1.6.1.3.3 GatherAvailableAncestors ( module, execList )

The abstract operation GatherAvailableAncestors takes arguments module (Cyclic Module Record) and execList (Cyclic Module Record 列表) and returns unused. It performs the following steps when called:

  1. module.[[AsyncParentModules]] 中每个 Cyclic Module Record m
    1. execList 不含 mm.[[CycleRoot]].[[EvaluationError]]empty,则
      1. 断言:m.[[Status]]evaluating-async
      2. 断言:m.[[EvaluationError]]empty
      3. 断言:m.[[AsyncEvaluationOrder]] 为整数。
      4. 断言:m.[[PendingAsyncDependencies]] > 0。
      5. m.[[PendingAsyncDependencies]] = m.[[PendingAsyncDependencies]] - 1。
      6. 若其为 0,则
        1. m 追加至 execList
        2. m.[[HasTLA]]false,执行 GatherAvailableAncestors(m, execList)。
  2. 返回 unused
Note

当根 module 的异步执行 fulfilled 时,此函数确定可同步继续执行的模块集合,填入 execList

16.2.1.6.1.3.4 AsyncModuleExecutionFulfilled ( module )

The abstract operation AsyncModuleExecutionFulfilled takes argument module (Cyclic Module Record) and returns unused. It performs the following steps when called:

  1. module.[[Status]]evaluated,则
    1. 断言:module.[[EvaluationError]]empty
    2. 返回 unused
  2. 断言:module.[[Status]]evaluating-async
  3. 断言:module.[[AsyncEvaluationOrder]] 为整数。
  4. 断言:module.[[EvaluationError]]empty
  5. module.[[AsyncEvaluationOrder]] = done
  6. module.[[Status]] = evaluated
  7. module.[[TopLevelCapability]]empty,则
    1. 断言:module.[[CycleRoot]]module 为同一记录。
    2. 执行 ! Call(module.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »)。
  8. execList 为新空列表。
  9. 执行 GatherAvailableAncestors(module, execList)。
  10. 断言:execList 各元素之 [[AsyncEvaluationOrder]] 为整数、[[PendingAsyncDependencies]] 为 0、[[EvaluationError]]empty
  11. sortedExecList 为按 [[AsyncEvaluationOrder]] 升序排序的 execList 拷贝。
  12. sortedExecList 每个 Cyclic Module Record m
    1. m.[[Status]]evaluated,断言其 [[EvaluationError]]empty
    2. 否则若 m.[[HasTLA]]true,执行 ExecuteAsyncModule(m)。
    3. 否则,
      1. result = m.ExecuteModule()
      2. result 为突然完成,执行 AsyncModuleExecutionRejected(m, result.[[Value]])。
      3. 否则,
        1. m.[[AsyncEvaluationOrder]] = done
        2. m.[[Status]] = evaluated
        3. m.[[TopLevelCapability]]empty
          1. 断言:m.[[CycleRoot]]m 相同。
          2. 执行 ! Call(m.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »)。
  13. 返回 unused

16.2.1.6.1.3.5 AsyncModuleExecutionRejected ( module, error )

The abstract operation AsyncModuleExecutionRejected takes arguments module (Cyclic Module Record) and error (ECMAScript 语言值) and returns unused. It performs the following steps when called:

  1. module.[[Status]]evaluated,则
    1. 断言:module.[[EvaluationError]]empty
    2. 返回 unused
  2. 断言:module.[[Status]]evaluating-async
  3. 断言:module.[[AsyncEvaluationOrder]] 为整数。
  4. 断言:module.[[EvaluationError]]empty
  5. module.[[EvaluationError]] = ThrowCompletion(error)。
  6. module.[[Status]] = evaluated
  7. module.[[AsyncEvaluationOrder]] = done
  8. 注:出于与 AsyncModuleExecutionFulfilled 对称,在出现错误时也设为 done;当 [[EvaluationError]]empty 时,其 [[AsyncEvaluationOrder]] 不再使用。
  9. module.[[AsyncParentModules]] 中每个 Cyclic Module Record m
    1. 执行 AsyncModuleExecutionRejected(m, error)。
  10. module.[[TopLevelCapability]]empty,则
    1. 断言:module.[[CycleRoot]]module 相同。
    2. 执行 ! Call(module.[[TopLevelCapability]].[[Reject]], undefined, « error »)。
  11. 返回 unused

16.2.1.6.2 循环模块记录图示例 (Example Cyclic Module Record Graphs)

本非规范性章节展示若干常见模块图的链接与求值示例,重点说明错误如何出现。

先看一个简单模块图:

Figure 2: 简单模块图 (A simple module graph)
模块 A 依赖模块 B,模块 B 依赖模块 C 的模块图

假设无错误:宿主首先调用 A.LoadRequestedModules()(递归加载 BC 的依赖),然后将 ABC[[Status]] 设为 unlinked。接着调用 A.Link(),三者转为 linked。稍后宿主在需要触发副作用时调用 A.Evaluate(),按顺序先求值 CB,最终三者 [[Status]]evaluated,Promise resolve 为 undefined

若在成功的 A.LoadRequestedModules() 之后出现链接错误:例如 InnerModuleLinking 处理 C 成功但随后 B 失败(导入不存在的内容),则 A.Link() 失败,AB 保持 unlinkedClinked

若在成功 Link() 后出现求值错误:例如 C 求值成功但 B 中代码抛出异常,则 A.Evaluate() 返回被拒绝的 Promise;异常记录在 AB[[EvaluationError]],二者变为 evaluatedC 也为 evaluated 但无错误。记录异常保证后续再次 Evaluate() 遇到相同错误。

接着看一个无法解析模块的情形:

Figure 3: 含缺失模块的模块图 (A module graph with an unresolvable module)
模块 A 依赖一个缺失模块 ??? 的模块图

此时 A 依赖的模块不存在(HostLoadImportedModule 最终以异常完成 FinishLoadingImportedModule)。可能原因包括资源不存在或解析返回错误。宿主可选择暴露失败原因。该异常导致加载失败,A.[[Status]] 保持 new

加载、链接与求值错误的差异:

  • 求值只应执行一次(可能有副作用),需记住是否已求值及其结果(包含异常)。
  • 链接无副作用,可失败后重试。
  • 加载与宿主交互紧密,宿主可能允许在临时网络错误后重试。

现在看一个包含环的模块图:

Figure 4: 循环模块图 (A cyclic module graph)
模块 A 依赖 B 和 C,且 B 依赖 A 的模块图

A 为入口,LoadRequestedModules 触发对 BC 的加载;因循环再次访问 A 时不再重复。成功后所有模块状态同时从 new 转为 unlinked

随后 Link 通过 DFS 对环进行 InnerModuleLinking,遇回返时不重复,最终在回溯根时同时把 SCC 中的 AB 设为 linkedC 已先行)。求值阶段的成功路径类同。

A 存在链接错误(如从 C 导入不存在的绑定),第二次回到 A 时提前返回,但最终在 InitializeEnvironment(调用 C.ResolveExport 后)抛出 SyntaxError。异常向上使当前栈中仍 linkingAB 重置为 unlinkedC 保持 linked

A 存在求值错误(源码抛异常),则求值阶段对应逻辑使 A 与仍 evaluatingB 记录错误并转为 evaluatedC 成功为 evaluated 且无错误。包含顶层 await 的路径通过 [[AsyncParentModules]] 传播。

最后看一个所有模块异步完成的循环图:

Figure 5: 异步循环模块图 (An asynchronous cyclic module graph)
模块 A 依赖 B 与 C,B 依赖 D,C 依赖 D 与 E,D 依赖 A 的模块图

加载与链接后全部为 linked

调用 A.Evaluate():ABD 设为 evaluatingD 无待依赖触发 ExecuteAsyncModule(D);回溯时 B 记录等待;继续处理 C 及其 D(无操作)与 E(执行异步)。最终整个环出栈,转为 evaluating-async,其字段如 Table 46

Table 46: 初次 Evaluate() 后的模块字段 (Module fields after the initial Evaluate() call)
字段 / 模块
Module
A B C D E
[[DFSAncestorIndex]] 0 0 0 0 4
[[Status]] evaluating-async evaluating-async evaluating-async evaluating-async evaluating-async
[[AsyncEvaluationOrder]] 4 1 3 0 2
[[AsyncParentModules]] « » « A » « A » « B, C » « C »
[[PendingAsyncDependencies]] 2 (B, C) 1 (D) 2 (D, E) 0 0

假设 E 先完成,调用 AsyncModuleExecutionFulfilledEevaluatedC.[[PendingAsyncDependencies]] 减至 1;字段见 Table 47

Table 47: 模块 E 完成后的字段 (Module fields after module E finishes executing)
字段
Module
C E
[[DFSAncestorIndex]] 0 4
[[Status]] evaluating-async evaluated
[[AsyncEvaluationOrder]] 3 done
[[AsyncParentModules]] « A » « C »
[[PendingAsyncDependencies]] 1 (D) 0

接着 D 完成:D 设为 evaluated,其可激活祖先为 B(顺序 1)与 C(顺序 3),因此先处理 B:其 Pending 变为 0,执行 ExecuteAsyncModule(B);随后 C 也开始执行;字段见 Table 48

Table 48: 模块 D 完成后的字段 (Module fields after module D finishes executing)
字段
Module
B C D
[[DFSAncestorIndex]]000
[[Status]]evaluating-asyncevaluating-asyncevaluated
[[AsyncEvaluationOrder]]13done
[[AsyncParentModules]]« A »« A »« B, C »
[[PendingAsyncDependencies]]000

然后 C 完成:设为 evaluatedA.Pending 减为 1;见 Table 49

Table 49: 模块 C 完成后的字段 (Module fields after module C finishes executing)
字段
Module
A C
[[DFSAncestorIndex]]00
[[Status]]evaluating-asyncevaluated
[[AsyncEvaluationOrder]]4done
[[AsyncParentModules]]« »« A »
[[PendingAsyncDependencies]]1 (B)0

随后 B 完成:设为 evaluatedA.Pending 减为 0,执行 ExecuteAsyncModule(A);见 Table 50

Table 50: 模块 B 完成后的字段 (Module fields after module B finishes executing)
字段
Module
A B
[[DFSAncestorIndex]]00
[[Status]]evaluating-asyncevaluated
[[AsyncEvaluationOrder]]4done
[[AsyncParentModules]]« »« A »
[[PendingAsyncDependencies]]00

最终 A 完成:A 设为 evaluated,其 [[TopLevelCapability]] 的 Promise resolve,图处理结束;见 Table 51

Table 51: 模块 A 完成后的字段 (Module fields after module A finishes executing)
字段
Module
A
[[DFSAncestorIndex]]0
[[Status]]evaluated
[[AsyncEvaluationOrder]]done
[[AsyncParentModules]]« »
[[PendingAsyncDependencies]]0

若失败:假设 C 先执行出错,在 AsyncModuleExecutionRejectedC 设为 evaluated 且记录错误,并沿 AsyncParentModules 传播;见 Table 52

Table 52: 模块 C 错误后的字段 (Module fields after module C finishes with an error)
字段
Module
A C
[[DFSAncestorIndex]]00
[[Status]]evaluatedevaluated
[[AsyncEvaluationOrder]]donedone
[[AsyncParentModules]]« »« A »
[[PendingAsyncDependencies]]1 (B)0
[[EvaluationError]]emptyC 的求值错误

A 也被拒绝并记录相同错误;见 Table 53

Table 53: 模块 A 被拒绝后的字段 (Module fields after module A is rejected)
字段
Module
A
[[DFSAncestorIndex]]0
[[Status]]evaluated
[[AsyncEvaluationOrder]]done
[[AsyncParentModules]]« »
[[PendingAsyncDependencies]]0
[[EvaluationError]]C 的 Evaluation Error

若随后 B 正常完成AsyncModuleExecutionFulfilled 运行但因 A(环根)已有错误,不再继续执行;未来导入 B 的模块通过 B.[[CycleRoot]].[[EvaluationError]] 看到同一错误;见 Table 54

Table 54: 错误图中 B 完成后的字段 (Module fields after module B finishes executing in an erroring graph)
字段
Module
A B
[[DFSAncestorIndex]]00
[[Status]]evaluatedevaluated
[[AsyncEvaluationOrder]]41
[[AsyncParentModules]]« »« A »
[[PendingAsyncDependencies]]00
[[EvaluationError]]C 的 Evaluation Errorempty

16.2.1.7 源码文本模块记录 (Source Text Module Records)

Source Text Module Record(源码文本模块记录) 表示由 ECMAScript 源文本(11,以 Module目标符号)解析出的模块信息。其字段包含模块导入与导出的摘要,具体方法利用这些摘要进行链接与求值。

该记录可与其它 Module Record 子类共存于模块图,并可与其它 Cyclic Module Record 子类构成环。

Table 43 字段外,还拥有 Table 55 中列出的附加字段,均在 ParseModule 中初始化。

Table 55: 源码文本模块记录附加字段 (Additional Fields of Source Text Module Records)
字段名 值类型 含义
[[ECMAScriptCode]] Parse Node Module目标符号解析该模块源文本的结果。
[[Context]] ECMAScript 代码执行上下文empty 与模块关联的执行上下文;在环境初始化前为 empty
[[ImportMeta]] Object 或 empty 通过 import.meta 暴露的对象;首次访问前为 empty
[[ImportEntries]] ImportEntry Record 列表 源码导入语句解析出的 ImportEntry 列表。
[[LocalExportEntries]] ExportEntry Record 列表 对应模块内部声明的导出。
[[IndirectExportEntries]] ExportEntry Record 列表 对应重导出的导入或 export * as namespace 的导出。
[[StarExportEntries]] ExportEntry Record 列表 对应 export *(不含 export * as namespace)的导出。

ImportEntry Record(导入项记录) 汇总单个声明式导入的信息,其字段见 Table 56

Table 56: ImportEntry 记录字段 (ImportEntry Record Fields)
字段名 值类型 含义
[[ModuleRequest]] ModuleRequest Record 表示 ImportDeclarationModuleSpecifier 与导入属性。
[[ImportName]] String 或 namespace-object 目标模块中导出的绑定名称。namespace-object 表示请求模块命名空间对象。
[[LocalName]] String 在本模块中访问该导入值的局部名字。
Note 1

Table 57 展示不同导入语法与 ImportEntry 字段的映射:

Table 57 (Informative): 导入语法到 ImportEntry 映射 (Import Forms Mappings to ImportEntry Records)
导入语句形式 [[ModuleRequest]] [[ImportName]] [[LocalName]]
import v from "mod"; "mod" "default" "v"
import * as ns from "mod"; "mod" namespace-object "ns"
import {x} from "mod"; "mod" "x" "x"
import {x as v} from "mod"; "mod" "x" "v"
import "mod"; 不创建 ImportEntry Record

ExportEntry Record(导出项记录) 汇总单个声明式导出信息,字段见 Table 58

Table 58: ExportEntry 记录字段 (ExportEntry Record Fields)
字段名 值类型 含义
[[ExportName]] String 或 null 对外导出的名称。
[[ModuleRequest]] ModuleRequest Recordnull 表示 ExportDeclarationModuleSpecifier 与导入属性;无则为 null
[[ImportName]] String、nullallall-but-default [[ModuleRequest]] 指定模块导出的绑定名;export * as nsallexport *all-but-default。无则 null
[[LocalName]] String 或 null 在本模块内部访问该导出值的名字;若非本地可访问则为 null
Note 2

Table 59 展示导出语法与 ExportEntry 字段映射:

Table 59 (Informative): 导出语法到 ExportEntry 映射 (Export Forms Mappings to ExportEntry Records)
导出语句形式 [[ExportName]] [[ModuleRequest]] [[ImportName]] [[LocalName]]
export var v; "v" null null "v"
export default function f() {} "default" null null "f"
export default function () {} "default" null null "default*"*
export default 42; "default" null null "default*"*
export {x}; "x" null null "x"
export {v as x}; "x" null null "v"
export {x} from "mod"; "x" "mod" "x" null
export {v as x} from "mod"; "x" "mod" "v" null
export * from "mod"; null "mod" all-but-default null
export * as ns from "mod"; "ns" "mod" all null

以下定义 Source Text Module Record 所需的具体方法与相关抽象操作

16.2.1.7.1 ParseModule ( sourceText, realm, hostDefined )

The abstract operation ParseModule takes arguments sourceText (ECMAScript 源文本), realm (Realm Record), and hostDefined (任意) and returns Source Text Module Record 或非空 SyntaxError 对象列表. 将 sourceTextModule 解析并创建 Source Text Module Record。 It performs the following steps when called:

  1. body = ParseText(sourceText, Module)。
  2. body 为错误列表,返回之。
  3. requestedModules = ModuleRequests(body)。
  4. importEntries = ImportEntries(body)。
  5. importedBoundNames = ImportedLocalNames(importEntries)。
  6. indirectExportEntrieslocalExportEntriesstarExportEntries 各为新空列表。
  7. exportEntries = ExportEntries(body)。
  8. exportEntries 每个 ExportEntry Record ee
    1. ee.[[ModuleRequest]]null,则
      1. importedBoundNames 不含 ee.[[LocalName]],追加 eelocalExportEntries
      2. 否则,
        1. ieimportEntries[[LocalName]] 等于该名的元素。
        2. ie.[[ImportName]]namespace-object
          1. 注:重导出模块命名空间对象。
          2. 追加 eelocalExportEntries
        3. 否则:
          1. 注:重导出单一名称。
          2. 追加 ExportEntry { [[ModuleRequest]]: ie.[[ModuleRequest]], [[ImportName]]: ie.[[ImportName]], [[LocalName]]: null, [[ExportName]]: ee.[[ExportName]] } 至 indirectExportEntries
    2. 否则若 ee.[[ImportName]]all-but-default
      1. 断言:ee.[[ExportName]]null
      2. 追加 eestarExportEntries
    3. 否则追加 eeindirectExportEntries
  9. async = body Contains await
  10. 返回 Source Text Module Record { [[Realm]]: realm, [[Environment]]: empty, [[Namespace]]: empty, [[CycleRoot]]: empty, [[HasTLA]]: async, [[AsyncEvaluationOrder]]: unset, [[TopLevelCapability]]: empty, [[AsyncParentModules]]: « », [[PendingAsyncDependencies]]: empty, [[Status]]: new, [[EvaluationError]]: empty, [[HostDefined]]: hostDefined, [[ECMAScriptCode]]: body, [[Context]]: empty, [[ImportMeta]]: empty, [[RequestedModules]]: requestedModules, [[LoadedModules]]: « », [[ImportEntries]]: importEntries, [[LocalExportEntries]]: localExportEntries, [[IndirectExportEntries]]: indirectExportEntries, [[StarExportEntries]]: starExportEntries, [[DFSAncestorIndex]]: empty }。
Note

实现可提前解析并检查早期错误,但错误报告需延迟到实际调用 ParseModule 时。

16.2.1.7.2 模块记录抽象方法实现 (Implementation of Module Record Abstract Methods)

以下为 Source Text Module RecordTable 42 中模块记录抽象方法的具体实现。

16.2.1.7.2.1 GetExportedNames ( [ exportStarSet ] )

The GetExportedNames concrete method of Source Text Module Record module takes optional argument exportStarSet (Source Text Module Record 列表) and returns String 列表. It performs the following steps when called:

  1. 断言:module.[[Status]]new
  2. exportStarSet 未传入,设为新空列表。
  3. exportStarSetmodule
    1. 断言:达到 export * 循环起点。
    2. 返回新空列表。
  4. 追加 moduleexportStarSet
  5. exportedNames 为新空列表。
  6. module.[[LocalExportEntries]] 每个 e
    1. 断言:存在直接绑定。
    2. 断言:e.[[ExportName]]null
    3. 追加该名称。
  7. module.[[IndirectExportEntries]] 每个 e
    1. 断言:导入特定绑定。
    2. 追加 e.[[ExportName]]
  8. module.[[StarExportEntries]] 每个 e
    1. 断言:e.[[ModuleRequest]]null
    2. requestedModule = GetImportedModule(module, e.[[ModuleRequest]])。
    3. starNames = requestedModule.GetExportedNames(exportStarSet)。
    4. starNames 每个 n
      1. n"default"exportedNames 不含 n,则追加。
  9. 返回 exportedNames
Note

GetExportedNames 不过滤或抛出模糊的星号再导出绑定。

16.2.1.7.2.2 ResolveExport ( exportName [ , resolveSet ] )

The ResolveExport concrete method of Source Text Module Record module takes argument exportName (String) and optional argument resolveSet (记录列表(字段 [[Module]] Module Record[[ExportName]] String)) and returns ResolvedBinding Recordnullambiguous.

尝试解析导出名称到定义的模块与局部绑定名。若是命名空间导出且无本地绑定,则 [[BindingName]]namespaceresolveSet 用于检测循环路径;若对同一 (module, exportName) 再次出现则返回 null。找到单一定义返回 ResolvedBinding;无定义或循环返回 null;多重模糊返回 ambiguous

It performs the following steps when called:

  1. 断言:module.[[Status]]new
  2. resolveSet 未传入,设为新空列表。
  3. resolveSet 中存在记录与 (module, exportName) 相同:
    1. 断言:循环导出请求。
    2. 返回 null
  4. 追加 { [[Module]]: module, [[ExportName]]: exportName } 至 resolveSet
  5. 遍历 [[LocalExportEntries]]
    1. 若匹配 exportName,返回 { [[Module]]: module, [[BindingName]]: e.[[LocalName]] }。
  6. 遍历 [[IndirectExportEntries]]
    1. 若匹配:
      1. 断言有 [[ModuleRequest]]
      2. importedModule = GetImportedModule(module, e.[[ModuleRequest]])。
      3. e.[[ImportName]]all
        1. 返回 { [[Module]]: importedModule, [[BindingName]]: namespace }。
      4. 否则返回 importedModule.ResolveExport(e.[[ImportName]], resolveSet)。
  7. exportName"default"
    1. 返回 null。(默认导出不会由 export * from 提供)
  8. starResolution = null
  9. 遍历 [[StarExportEntries]]
    1. importedModule = GetImportedModule(... )。
    2. resolution = importedModule.ResolveExport(exportName, resolveSet)。
    3. ambiguous 返回 ambiguous
    4. 若非 null
      1. starResolutionnull,设之。
      2. 否则若模块不同或 BindingName 不兼容(含命名空间冲突)返回 ambiguous
  10. 返回 starResolution

16.2.1.7.3 循环模块记录抽象方法的实现 (Implementation of Cyclic Module Record Abstract Methods)

以下为 Source Text Module RecordTable 44 中循环模块记录抽象方法的实现。

16.2.1.7.3.1 InitializeEnvironment ( )

The InitializeEnvironment concrete method of Source Text Module Record module takes no arguments and returns 正常完成(含 unused)或 throw completion. It performs the following steps when called:

  1. module.[[IndirectExportEntries]] 每个 e
    1. 断言 e.[[ExportName]]null
    2. resolution = module.ResolveExport(e.[[ExportName]])。
    3. 若为 nullambiguousSyntaxError
  2. 断言所有命名导出可解析。
  3. realm = module.[[Realm]]
  4. 断言非 undefined
  5. env = NewModuleEnvironment(realm.[[GlobalEnv]])。
  6. module.[[Environment]] = env
  7. module.[[ImportEntries]] 每个 in
    1. importedModule = GetImportedModule(... )。
    2. in.[[ImportName]]namespace-object
      1. namespace = GetModuleNamespace(importedModule)。
      2. ! CreateImmutableBinding + InitializeBinding。
    3. 否则:
      1. resolution = importedModule.ResolveExport(in.[[ImportName]])。
      2. nullambiguousSyntaxError
      3. resolution.[[BindingName]]namespace
        1. 获取命名空间并绑定。
      4. 否则 CreateImportBinding
  8. 创建执行上下文 moduleContext 并关联环境。
  9. 推入执行上下文栈并获取 code
  10. 处理 VarScopedDeclarations:为每个唯一变量创建并初始化 undefined
  11. 处理 LexicallyScopedDeclarations:创建(可变或不可变)绑定;若是函数类声明,实例化函数对象并初始化绑定。
  12. 弹出执行上下文。
  13. 返回 unused

16.2.1.7.3.2 ExecuteModule ( [ capability ] )

The ExecuteModule concrete method of Source Text Module Record module takes optional argument capability (PromiseCapability Record) and returns 正常完成(含 unused)或 throw completion. It performs the following steps when called:

  1. 创建新执行上下文 moduleContext 并关联 module.[[Environment]]
  2. 暂停当前执行上下文。
  3. module.[[HasTLA]]false
    1. 断言 capability 未提供。
    2. 推入 moduleContext
    3. result = Completion(Evaluation of module.[[ECMAScriptCode]])。
    4. 弹出并恢复上层上下文。
    5. result 为突然完成,返回 ? result
  4. 否则:
    1. 断言 capability 存在。
    2. 执行 AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleContext)。
  5. 返回 unused

16.2.1.8 合成模块记录 (Synthetic Module Records)

Synthetic Module Record(合成模块记录) 表示由规范定义的模块,其导出名称在创建时静态确定,但值可通过 SetSyntheticModuleExport 动态更新;无导入或依赖。

Note
可用于定义多种模块类型,如 JSON 模块或 CSS 模块。

Table 41 字段外,还具有 Table 60 中附加字段。

Table 60: 合成模块记录附加字段 (Additional Fields of Synthetic Module Records)
字段名 值类型 含义
[[ExportNames]] 字符串列表 模块的导出名称;无重复。
[[EvaluationSteps]] 抽象闭包 求值期间的初始化逻辑,以模块自身为唯一参数;不得修改 [[ExportNames]];可返回突然完成。

16.2.1.8.1 CreateDefaultExportSyntheticModule ( defaultExport )

The abstract operation CreateDefaultExportSyntheticModule takes argument defaultExport (ECMAScript 语言值) and returns Synthetic Module Record. 创建一个默认导出为 defaultExport 的合成模块记录。 It performs the following steps when called:

  1. realm当前 Realm Record
  2. setDefaultExport 为捕获 defaultExport 的抽象闭包(module):
    1. 执行 SetSyntheticModuleExport(module, "default", defaultExport)。
    2. 返回 NormalCompletion(unused)。
  3. 返回 { [[Realm]]: realm, [[Environment]]: empty, [[Namespace]]: empty, [[HostDefined]]: undefined, [[ExportNames]]: « "default" », [[EvaluationSteps]]: setDefaultExport } 的 Synthetic Module Record

16.2.1.8.2 ParseJSONModule ( source )

The abstract operation ParseJSONModule takes argument source (String) and returns 正常完成(含 Synthetic Module Record)或 throw completion. It performs the following steps when called:

  1. json = ? ParseJSON(source)。
  2. 返回 CreateDefaultExportSyntheticModule(json)。

16.2.1.8.3 SetSyntheticModuleExport ( module, exportName, exportValue )

The abstract operation SetSyntheticModuleExport takes arguments module (Synthetic Module Record), exportName (String), and exportValue (ECMAScript 语言值) and returns unused. 设置或更新合成模块已存在导出的值。 It performs the following steps when called:

  1. 断言:module.[[ExportNames]]exportName
  2. envRec = module.[[Environment]]
  3. 断言:envRecempty
  4. 执行 envRec.SetMutableBinding(exportName, exportValue, true)。
  5. 返回 unused

16.2.1.8.4 模块记录抽象方法实现 (Implementation of Module Record Abstract Methods)

以下为合成模块记录对 Table 42 抽象方法的实现。

16.2.1.8.4.1 LoadRequestedModules ( )

The LoadRequestedModules concrete method of Synthetic Module Record module takes no arguments and returns Promise. It performs the following steps when called:

  1. 返回 ! PromiseResolve(%Promise%, undefined)。
Note
合成模块记录无依赖。

16.2.1.8.4.2 GetExportedNames ( )

The GetExportedNames concrete method of Synthetic Module Record module takes no arguments and returns 字符串列表. It performs the following steps when called:

  1. 返回 module.[[ExportNames]]

16.2.1.8.4.3 ResolveExport ( exportName )

The ResolveExport concrete method of Synthetic Module Record module takes argument exportName (String) and returns ResolvedBinding Recordnull. It performs the following steps when called:

  1. 若不含 exportName,返回 null
  2. 返回 { [[Module]]: module, [[BindingName]]: exportName }。

16.2.1.8.4.4 Link ( )

The Link concrete method of Synthetic Module Record module takes no arguments and returns 正常完成(含 unused). It performs the following steps when called:

  1. realm = module.[[Realm]]
  2. env = NewModuleEnvironment(realm.[[GlobalEnv]])。
  3. module.[[Environment]] = env
  4. module.[[ExportNames]] 每个 exportName
    1. ! CreateMutableBinding + InitializeBinding(exportName, undefined)。
  5. 返回 NormalCompletion(unused)。

16.2.1.8.4.5 Evaluate ( )

The Evaluate concrete method of Synthetic Module Record module takes no arguments and returns Promise. It performs the following steps when called:

  1. 创建执行上下文 moduleContext 并关联环境。
  2. 暂停当前执行上下文并推入 moduleContext
  3. steps = module.[[EvaluationSteps]]
  4. result = Completion(steps(module))。
  5. 弹出 moduleContext 并恢复。
  6. pc = ! NewPromiseCapability(%Promise%)。
  7. IfAbruptRejectPromise(result, pc)。
  8. 执行 ! Call(pc.[[Resolve]], undefined, « undefined »)。
  9. 返回 pc.[[Promise]]

16.2.1.9 GetImportedModule ( referrer, request )

The abstract operation GetImportedModule takes arguments referrer (Cyclic Module Record) and request (ModuleRequest Record) and returns Module Record. It performs the following steps when called:

  1. recordsreferrer.[[LoadedModules]] 中满足 ModuleRequestsEqual(r, request) 为 trueLoadedModuleRequest Record 列表。
  2. 断言:records 恰有一个元素。
  3. record 为其唯一元素。
  4. 返回 record.[[Module]]

16.2.1.10 HostLoadImportedModule ( referrer, moduleRequest, hostDefined, payload )

The host-defined abstract operation HostLoadImportedModule takes arguments referrer (Script Record、Cyclic Module RecordRealm Record), moduleRequest (ModuleRequest Record), hostDefined (任意), and payload (GraphLoadingState RecordPromiseCapability Record) and returns unused.

Note 1

在浏览器中,用户点击:

<button type="button" onclick="import('./foo.mjs')">Click me</button>

执行 import() 时可能没有活动脚本或模块(执行上下文栈顶 ScriptOrModule 为 null),因此 referrer 可能是 Realm Record

HostLoadImportedModule 的实现需满足:

实际过程由宿主定义,通常包括执行所需 I/O 以加载 Module Record。不同 (referrer, 说明符, 属性) 组合可映射到同一模块实例,说明符标准化过程由宿主定义(如解析相对与简写路径)。

Note 2

上述要求宿主type: "json" 时支持 JSON 模块(且正常完成),但不禁止在缺省类型下支持 JSON。

16.2.1.11 FinishLoadingImportedModule ( referrer, moduleRequest, payload, result )

The abstract operation FinishLoadingImportedModule takes arguments referrer (一个 Script Record、Cyclic Module RecordRealm Record), moduleRequest (一个 ModuleRequest Record), payload (一个 GraphLoadingState RecordPromiseCapability Record), and result (正常完成(包含一个 Module Record)或 throw completion) and returns unused. It performs the following steps when called:

  1. 如果 result正常完成,则
    1. 如果 referrer.[[LoadedModules]] 包含某个 LoadedModuleRequest Record recordModuleRequestsEqual(record, moduleRequest) 为 true,则
      1. 断言:record.[[Module]]result.[[Value]] 是同一个 Module Record
    2. 否则,
      1. LoadedModuleRequest Record { [[Specifier]]: moduleRequest.[[Specifier]], [[Attributes]]: moduleRequest.[[Attributes]], [[Module]]: result.[[Value]] } 追加到 referrer.[[LoadedModules]]
  2. 如果 payload 是 GraphLoadingState Record,则
    1. 执行 ContinueModuleLoading(payload, result)。
  3. 否则,
    1. 执行 ContinueDynamicImport(payload, result)。
  4. 返回 unused

16.2.1.12 AllImportAttributesSupported ( attributes )

The abstract operation AllImportAttributesSupported takes argument attributes (ImportAttribute Records 的列表) and returns Boolean. It performs the following steps when called:

  1. supportedHostGetSupportedImportAttributes()。
  2. attributes 的每个 ImportAttribute Record attribute
    1. 如果 supported 不包含 attribute.[[Key]],返回 false
  3. 返回 true

16.2.1.12.1 HostGetSupportedImportAttributes ( )

The host-defined abstract operation HostGetSupportedImportAttributes takes no arguments and returns 字符串列表. 允许宿主环境指明其支持的 import 属性。只有具有受支持键的属性才会提供给宿主

HostGetSupportedImportAttributes 的实现必须符合以下要求:

  • 必须返回一个字符串列表,每个字符串表示一个受支持的属性。
  • 每次调用都必须返回同一个包含相同内容且顺序相同的列表。

默认实现返回一个新的空列表。

Note
要求宿主声明支持的导入属性,而不是将全部属性传给宿主再筛选,旨在确保不同宿主对不支持属性的处理一致。

16.2.1.13 GetModuleNamespace ( module )

The abstract operation GetModuleNamespace takes argument module (Module Record 具体子类的一个实例) and returns Module Namespace Object. 获取表示 module 导出的 Module Namespace Object,第一次请求时惰性创建并存入 module.[[Namespace]] 以供后续复用。 It performs the following steps when called:

  1. 断言:若 module 是 Cyclic Module Record,则 module.[[Status]] 不为 newunlinked
  2. namespacemodule.[[Namespace]]
  3. 如果 namespaceempty,则
    1. exportedNamesmodule.GetExportedNames()。
    2. unambiguousNames 为新的空列表。
    3. exportedNames 的每个元素 name
      1. resolutionmodule.ResolveExport(name)。
      2. 如果 resolutionResolvedBinding Record,将 name 追加到 unambiguousNames
    4. namespaceModuleNamespaceCreate(module, unambiguousNames)。
  4. 返回 namespace
Note

GetModuleNamespace 不会抛出异常。不可解析的名称此时直接排除;除非它们全是未被显式请求的歧义星号导出,否则稍后会导致真实的链接错误。

16.2.1.14 运行时语义:求值 (Runtime Semantics: Evaluation)

Module : [empty]
  1. 返回 undefined
ModuleBody : ModuleItemList
  1. resultCompletion(Evaluation of ModuleItemList)。
  2. 如果 result正常完成result.[[Value]]empty,则
    1. 返回 undefined
  3. 返回 ? result
ModuleItemList : ModuleItemList ModuleItem
  1. sl 为 ? Evaluation of ModuleItemList
  2. sCompletion(Evaluation of ModuleItem)。
  3. 返回 ? UpdateEmpty(s, sl)。
Note

ModuleItemList 的值是其中最后一个产生值的条目的值。

ModuleItem : ImportDeclaration
  1. 返回 empty

16.2.2 导入 (Imports)

语法 (Syntax)

ImportDeclaration : import ImportClause FromClause WithClauseopt ; import ModuleSpecifier WithClauseopt ; ImportClause : ImportedDefaultBinding NameSpaceImport NamedImports ImportedDefaultBinding , NameSpaceImport ImportedDefaultBinding , NamedImports ImportedDefaultBinding : ImportedBinding NameSpaceImport : * as ImportedBinding NamedImports : { } { ImportsList } { ImportsList , } FromClause : from ModuleSpecifier ImportsList : ImportSpecifier ImportsList , ImportSpecifier ImportSpecifier : ImportedBinding ModuleExportName as ImportedBinding ModuleSpecifier : StringLiteral ImportedBinding : BindingIdentifier[~Yield, +Await] WithClause : with { } with { WithEntries ,opt } WithEntries : AttributeKey : StringLiteral AttributeKey : StringLiteral , WithEntries AttributeKey : IdentifierName StringLiteral

16.2.2.1 静态语义:早期错误 (Static Semantics: Early Errors)

ModuleItem : ImportDeclaration
  • ImportDeclaration 的 BoundNames 含有任意重复条目,则为语法错误。
WithClause : with { WithEntries ,opt }
  • WithClause 的 WithClauseToAttributes 具有两个不同条目 aba.[[Key]]b.[[Key]],则为语法错误。

16.2.2.2 静态语义:ImportEntries

The syntax-directed operation 静态语义:ImportEntries takes no arguments and returns ImportEntry Record 列表. It is defined piecewise over the following productions:

Module : [empty]
  1. 返回新的空列表。
ModuleItemList : ModuleItemList ModuleItem
  1. entries1ModuleItemList 的 ImportEntries。
  2. entries2ModuleItem 的 ImportEntries。
  3. 返回 entries1entries2 的列表连接。
ModuleItem : ExportDeclaration StatementListItem
  1. 返回新的空列表。
ImportDeclaration : import ImportClause FromClause WithClauseopt ;
  1. moduleImportDeclaration 的 ModuleRequests 的唯一元素。
  2. 返回 ImportClause 的 ImportEntriesForModule,参数 module
ImportDeclaration : import ModuleSpecifier WithClauseopt ;
  1. 返回新的空列表。

16.2.2.3 静态语义:ImportEntriesForModule

The syntax-directed operation 静态语义:ImportEntriesForModule takes argument module (ModuleRequest Record) and returns ImportEntry Record 列表. It is defined piecewise over the following productions:

ImportClause : ImportedDefaultBinding , NameSpaceImport
  1. entries1ImportedDefaultBinding 的 ImportEntriesForModule,参数 module
  2. entries2NameSpaceImport 的 ImportEntriesForModule,参数 module
  3. 返回 entries1entries2 的列表连接。
ImportClause : ImportedDefaultBinding , NamedImports
  1. entries1ImportedDefaultBinding 的 ImportEntriesForModule,参数 module
  2. entries2NamedImports 的 ImportEntriesForModule,参数 module
  3. 返回 entries1entries2 的列表连接。
ImportedDefaultBinding : ImportedBinding
  1. localNameImportedBinding 的 BoundNames 的唯一元素。
  2. defaultEntry 为 ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: "default", [[LocalName]]: localName }。
  3. 返回 « defaultEntry »。
NameSpaceImport : * as ImportedBinding
  1. localNameImportedBinding 的 StringValue。
  2. entry 为 ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: namespace-object, [[LocalName]]: localName }。
  3. 返回 « entry »。
NamedImports : { }
  1. 返回新的空列表。
ImportsList : ImportsList , ImportSpecifier
  1. specs1ImportsList 的 ImportEntriesForModule,参数 module
  2. specs2ImportSpecifier 的 ImportEntriesForModule,参数 module
  3. 返回 specs1specs2 的列表连接。
ImportSpecifier : ImportedBinding
  1. localNameImportedBinding 的 BoundNames 的唯一元素。
  2. entry 为 ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: localName, [[LocalName]]: localName }。
  3. 返回 « entry »。
ImportSpecifier : ModuleExportName as ImportedBinding
  1. importNameModuleExportName 的 StringValue。
  2. localNameImportedBinding 的 StringValue。
  3. entry 为 ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName }。
  4. 返回 « entry »。

16.2.2.4 静态语义:WithClauseToAttributes

The syntax-directed operation 静态语义:WithClauseToAttributes takes no arguments and returns ImportAttribute Record 列表. It is defined piecewise over the following productions:

WithClause : with { }
  1. 返回新的空列表。
WithClause : with { WithEntries ,opt }
  1. attributesWithEntries 的 WithClauseToAttributes。
  2. 按其 [[Key]] 字段的字典序(视各字段值为 UTF-16 代码单元序列)对 attributes 排序。注:该排序的可观察性仅体现在宿主被禁止基于枚举顺序改变行为。
  3. 返回 attributes
WithEntries : AttributeKey : StringLiteral
  1. keyAttributeKey 的 PropName。
  2. entryImportAttribute Record { [[Key]]: key, [[Value]]: StringLiteral 的 SV }。
  3. 返回 « entry »。
WithEntries : AttributeKey : StringLiteral , WithEntries
  1. keyAttributeKey 的 PropName。
  2. entryImportAttribute Record { [[Key]]: key, [[Value]]: StringLiteral 的 SV }。
  3. restWithEntries 的 WithClauseToAttributes。
  4. 返回 « entry » 与 rest 的列表连接。

16.2.3 导出 (Exports)

语法 (Syntax)

ExportDeclaration : export ExportFromClause FromClause WithClauseopt ; export NamedExports ; export VariableStatement[~Yield, +Await] export Declaration[~Yield, +Await] export default HoistableDeclaration[~Yield, +Await, +Default] export default ClassDeclaration[~Yield, +Await, +Default] export default [lookahead ∉ { function, async [no LineTerminator here] function, class }] AssignmentExpression[+In, ~Yield, +Await] ; ExportFromClause : * * as ModuleExportName NamedExports NamedExports : { } { ExportsList } { ExportsList , } ExportsList : ExportSpecifier ExportsList , ExportSpecifier ExportSpecifier : ModuleExportName ModuleExportName as ModuleExportName

16.2.3.1 静态语义:早期错误 (Static Semantics: Early Errors)

ExportDeclaration : export NamedExports ;
  • NamedExports 的 ReferencedBindings 包含任意 StringLiteral,则为语法错误。
  • 对于 NamedExports 的 ReferencedBindings 中每个 IdentifierName n:若 n 的 StringValue 是 ReservedWord,或其值是 "implements""interface""let""package""private""protected""public""static" 之一,则为语法错误。
Note

上述规则意味着 NamedExports 的每个 ReferencedBindings 被视作一个 IdentifierReference

16.2.3.2 静态语义:ExportedBindings

The syntax-directed operation 静态语义:ExportedBindings takes no arguments and returns 字符串列表.

Note

ExportedBindings 是一个 Module 的 ExportedNames 显式映射到的本地绑定名称集合。

It is defined piecewise over the following productions:

ModuleItemList : ModuleItemList ModuleItem
  1. names1ModuleItemList 的 ExportedBindings。
  2. names2ModuleItem 的 ExportedBindings。
  3. 返回 names1names2 的列表连接。
ModuleItem : ImportDeclaration StatementListItem
  1. 返回新的空列表。
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ;
  1. 返回新的空列表。
ExportDeclaration : export NamedExports ;
  1. 返回 NamedExports 的 ExportedBindings。
ExportDeclaration : export VariableStatement
  1. 返回 VariableStatement 的 BoundNames。
ExportDeclaration : export Declaration
  1. 返回 Declaration 的 BoundNames。
ExportDeclaration : export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression ;
  1. 返回此 ExportDeclaration 的 BoundNames。
NamedExports : { }
  1. 返回新的空列表。
ExportsList : ExportsList , ExportSpecifier
  1. names1ExportsList 的 ExportedBindings。
  2. names2ExportSpecifier 的 ExportedBindings。
  3. 返回 names1names2 的列表连接。
ExportSpecifier : ModuleExportName
  1. 返回仅含 ModuleExportName 的 StringValue 的列表。
ExportSpecifier : ModuleExportName as ModuleExportName
  1. 返回仅含第一个 ModuleExportName 的 StringValue 的列表。

16.2.3.3 静态语义:ExportedNames

The syntax-directed operation 静态语义:ExportedNames takes no arguments and returns 字符串列表.

Note

ExportedNames 是 Module 显式映射到其本地绑定的对外可见名称集合。

It is defined piecewise over the following productions:

ModuleItemList : ModuleItemList ModuleItem
  1. names1ModuleItemList 的 ExportedNames。
  2. names2ModuleItem 的 ExportedNames。
  3. 返回 names1names2 的列表连接。
ModuleItem : ExportDeclaration
  1. 返回 ExportDeclaration 的 ExportedNames。
ModuleItem : ImportDeclaration StatementListItem
  1. 返回新的空列表。
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ;
  1. 返回 ExportFromClause 的 ExportedNames。
ExportFromClause : *
  1. 返回新的空列表。
ExportFromClause : * as ModuleExportName
  1. 返回仅含 ModuleExportName 的 StringValue 的列表。
ExportFromClause : NamedExports
  1. 返回 NamedExports 的 ExportedNames。
ExportDeclaration : export VariableStatement
  1. 返回 VariableStatement 的 BoundNames。
ExportDeclaration : export Declaration
  1. 返回 Declaration 的 BoundNames。
ExportDeclaration : export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression ;
  1. 返回 « "default" »。
NamedExports : { }
  1. 返回新的空列表。
ExportsList : ExportsList , ExportSpecifier
  1. names1ExportsList 的 ExportedNames。
  2. names2ExportSpecifier 的 ExportedNames。
  3. 返回 names1names2 的列表连接。
ExportSpecifier : ModuleExportName
  1. 返回仅含 ModuleExportName 的 StringValue 的列表。
ExportSpecifier : ModuleExportName as ModuleExportName
  1. 返回仅含第二个 ModuleExportName 的 StringValue 的列表。

16.2.3.4 静态语义:ExportEntries

The syntax-directed operation 静态语义:ExportEntries takes no arguments and returns ExportEntry Record 列表. It is defined piecewise over the following productions:

Module : [empty]
  1. 返回新的空列表。
ModuleItemList : ModuleItemList ModuleItem
  1. entries1ModuleItemList 的 ExportEntries。
  2. entries2ModuleItem 的 ExportEntries。
  3. 返回 entries1entries2 的列表连接。
ModuleItem : ImportDeclaration StatementListItem
  1. 返回新的空列表。
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ;
  1. moduleExportDeclaration 的 ModuleRequests 的唯一元素。
  2. 返回 ExportFromClause 的 ExportEntriesForModule,参数 module
ExportDeclaration : export NamedExports ;
  1. 返回 NamedExports 的 ExportEntriesForModule,参数 null
ExportDeclaration : export VariableStatement
  1. entries 为新的空列表。
  2. namesVariableStatement 的 BoundNames。
  3. names 中每个 name
    1. 将 ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name } 追加至 entries
  4. 返回 entries
ExportDeclaration : export Declaration
  1. entries 为新的空列表。
  2. namesDeclaration 的 BoundNames。
  3. names 中每个 name
    1. 将 ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name } 追加至 entries
  4. 返回 entries
ExportDeclaration : export default HoistableDeclaration
  1. namesHoistableDeclaration 的 BoundNames。
  2. localNamenames 的唯一元素。
  3. 返回唯一元素为新 ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default" } 的列表。
ExportDeclaration : export default ClassDeclaration
  1. namesClassDeclaration 的 BoundNames。
  2. localNamenames 的唯一元素。
  3. 返回唯一元素为新 ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default" } 的列表。
ExportDeclaration : export default AssignmentExpression ;
  1. entry 为 ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: "*default*", [[ExportName]]: "default" }。
  2. 返回 « entry »。
Note

"*default*" 在本规范中用作匿名默认导出值的合成名称。详见 该注释

16.2.3.5 静态语义:ExportEntriesForModule

The syntax-directed operation 静态语义:ExportEntriesForModule takes argument module (ModuleRequest Recordnull) and returns ExportEntry Record 列表. It is defined piecewise over the following productions:

ExportFromClause : *
  1. entry 为 ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: all-but-default, [[LocalName]]: null, [[ExportName]]: null }。
  2. 返回 « entry »。
ExportFromClause : * as ModuleExportName
  1. exportNameModuleExportName 的 StringValue。
  2. entry 为 ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: all, [[LocalName]]: null, [[ExportName]]: exportName }。
  3. 返回 « entry »。
NamedExports : { }
  1. 返回新的空列表。
ExportsList : ExportsList , ExportSpecifier
  1. specs1ExportsList 的 ExportEntriesForModule,参数 module
  2. specs2ExportSpecifier 的 ExportEntriesForModule,参数 module
  3. 返回 specs1specs2 的列表连接。
ExportSpecifier : ModuleExportName
  1. sourceNameModuleExportName 的 StringValue。
  2. modulenull,则
    1. localNamesourceName
    2. importNamenull
  3. 否则,
    1. localNamenull
    2. importNamesourceName
  4. 返回仅含新 ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: sourceName } 的列表。
ExportSpecifier : ModuleExportName as ModuleExportName
  1. sourceName 为第一个 ModuleExportName 的 StringValue。
  2. exportName 为第二个 ModuleExportName 的 StringValue。
  3. modulenull,则
    1. localNamesourceName
    2. importNamenull
  4. 否则,
    1. localNamenull
    2. importNamesourceName
  5. 返回仅含新 ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: exportName } 的列表。

16.2.3.6 静态语义:ReferencedBindings

The syntax-directed operation 静态语义:ReferencedBindings takes no arguments and returns 解析节点列表. It is defined piecewise over the following productions:

NamedExports : { }
  1. 返回新的空列表。
ExportsList : ExportsList , ExportSpecifier
  1. names1ExportsList 的 ReferencedBindings。
  2. names2ExportSpecifier 的 ReferencedBindings。
  3. 返回 names1names2 的列表连接。
ExportSpecifier : ModuleExportName as ModuleExportName
  1. 返回第一个 ModuleExportName 的 ReferencedBindings。
ModuleExportName : IdentifierName
  1. 返回仅含该 IdentifierName 的列表。
ModuleExportName : StringLiteral
  1. 返回仅含该 StringLiteral 的列表。

16.2.3.7 运行时语义:求值 (Runtime Semantics: Evaluation)

ExportDeclaration : export ExportFromClause FromClause WithClauseopt ; export NamedExports ;
  1. 返回 empty
ExportDeclaration : export VariableStatement
  1. 返回 ? 对 VariableStatement 的 Evaluation。
ExportDeclaration : export Declaration
  1. 返回 ? 对 Declaration 的 Evaluation。
ExportDeclaration : export default HoistableDeclaration
  1. 返回 ? 对 HoistableDeclaration 的 Evaluation。
ExportDeclaration : export default ClassDeclaration
  1. value 为 ? 对 ClassDeclaration 的 BindingClassDeclarationEvaluation。
  2. classNameClassDeclaration 的 BoundNames 的唯一元素。
  3. className"*default*",则
    1. env 为正在运行的执行上下文的 LexicalEnvironment。
    2. 执行 ? InitializeBoundName("*default*", value, env)。
  4. 返回 empty
ExportDeclaration : export default AssignmentExpression ;
  1. 若 IsAnonymousFunctionDefinition(AssignmentExpression) 为 true,则
    1. value 为 ? NamedEvaluation(AssignmentExpression, "default")。
  2. 否则,
    1. rhs 为 ? Evaluation(AssignmentExpression)。
    2. value 为 ? GetValue(rhs)。
  3. env 为正在运行的执行上下文的 LexicalEnvironment。
  4. 执行 ? InitializeBoundName("*default*", value, env)。
  5. 返回 empty

17 错误处理与语言扩展 (Error Handling and Language Extensions)

实现必须在相关 ECMAScript 语言结构被求值时报告大多数错误。early error(早期错误) 是指可在包含该错误的 Script 的任意结构被求值之前就能检测并报告的错误。存在早期错误会阻止该结构的求值。实现必须在 ParseScript 解析 Script 时,将其中的早期错误作为解析的一部分报告。Module 中的早期错误在该 Module 将被求值的时刻报告,并且该 Module 永远不会被初始化。eval 代码中的早期错误在调用 eval 时报告,并阻止 eval 代码的求值。所有不是早期错误的错误都是运行时错误。

实现必须将本规范各 “Static Semantics: Early Errors” 子小节中列出的条件的任何出现作为早期错误报告。

实现不得将其他类型的错误视为早期错误,即使编译器可以证明某个结构在任何情况下都无法无错执行。此类情形下实现可以发出早期警告,但不应在相关结构真正执行之前报告该错误。

实现应按规范报告所有错误,但以下情况除外:

17.1 禁止的扩展 (Forbidden Extensions)

实现不得以下述方式扩展本规范:

18 ECMAScript 标准内建对象 (ECMAScript Standard Built-in Objects)

当任意 ECMAScript ScriptModule 开始执行时,有若干内建对象可用。其中,全局对象是正在执行程序的全局环境的一部分。其他对象作为全局对象的初始属性或作为已可访问内建对象的属性间接访问。

除非另有说明,可作为函数调用的内建对象是具有 10.3 所述特性的内建函数对象。除非另有说明,内建对象的 [[Extensible]] 内部槽初始值为 true。每个内建函数对象都有 [[Realm]] 内部槽,其值为创建该对象时所属领域的 Realm Record

许多内建对象是函数:它们可带参数调用。其中一些还是构造器:它们旨在与 new 运算符一起使用。对于每个内建函数,本规范描述该函数所需的参数及函数对象的属性。对于每个内建构造器,本规范还描述该构造器原型对象的属性以及由调用该构造器的 new 表达式返回的特定对象实例的属性。

除非在特定函数的描述中另有说明,如果给内建函数或构造器的实参少于其规范要求的数量,则该函数或构造器的行为与补足缺失的参数(每个缺失参数为 undefined)完全一致。此类缺失参数被视为 “not present”,规范算法可据此识别。在特定函数的描述中,“this value” 与 “NewTarget” 术语具有 10.3 中给出的含义。

除非在特定函数的描述中另有说明,如果调用所描述的内建函数或构造器时提供的参数多于其允许的数量,多余的参数会被求值但随后被函数忽略。但是,实现可针对这些参数定义实现特定行为,只要该行为不只是因为存在额外参数而抛出 TypeError 异常。

Note 1

为向内建函数集合添加额外能力的实现,鼓励通过添加新函数而非为现有函数增加新参数来实现。

除非另有说明,每个内建函数与每个内建构造器的 [[Prototype]] 内部槽值为 Function 原型对象,即表达式 Function.prototype20.2.3)的初始值。

除非另有说明,每个内建原型对象(除 Object 原型对象本身外)的 [[Prototype]] 内部槽值为 Object 原型对象,即表达式 Object.prototype20.1.3)的初始值。

若本规范通过算法步骤定义了某内建构造器的行为,则该行为同时适用于 [[Call]][[Construct]]。若该算法需要区分两种情形,它通过检测 NewTarget 是否为 undefined(表示 [[Call]] 调用)来实现。

未标识为构造器的内建函数对象除非另有说明,否则不实现 [[Construct]] 内部方法。

未作为构造器的内建函数对象除非另有说明,否则没有 "prototype" 属性。

本规范中定义的每个内建函数(包括构造器)均通过调用 CreateBuiltinFunction 抽象操作10.3.4)创建。参数 lengthname 的值作为 "length""name" 属性的初始值(如下文所述)。prefix 参数的值同样如下文所述。

每个内建函数对象(包括构造器)都有 "length" 属性,其值为非负整数 Number。除非另有说明,该值为函数描述小节标题中列出的必需参数数量。可选参数与剩余参数不计入参数数目。

Note 2

例如,Array 原型对象 "map" 属性初始值的函数对象,其标题 «Array.prototype.map (callback [ , thisArg])» 展示两个命名参数 callback 与 thisArg(后者可选);因此该函数对象"length" 属性值是 1𝔽

除非另有说明,内建函数对象"length" 属性具有属性特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

每个内建函数对象(包括构造器)都有 "name" 属性,其值为 String。除非另有说明,该值为本规范赋予该函数的名称。标识为匿名函数的使用空字符串作为 "name" 属性值。若函数作为对象的属性指定,其名称值为用于访问该函数的属性名字符串。作为内建属性的 getter 或 setter 访问器函数指定的函数,在调用 CreateBuiltinFunction 时分别将 "get""set" 传给 prefix 参数。

属性键为 Symbol 值的每个内建函数,其 "name" 属性值在规范中被明确指定。若该值以 "get ""set " 前缀开头且函数是某内建属性的 get 或 set 访问器,则去掉前缀的值传给 name 参数,而 "get""set"(分别)传给 prefix 参数。

除非另有说明,内建函数对象"name" 属性具有属性特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

1928 各小节以及附录 B.2 中描述的所有其他数据属性,除非另有说明,具有属性特性 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }。

1928 各小节以及附录 B.2 中描述的所有访问器属性,除非另有说明,具有属性特性 { [[Enumerable]]: false, [[Configurable]]: true }。若仅描述了 get 访问器函数,则 set 访问器函数为默认值 undefined。若仅描述了 set 访问器函数,则 get 访问器为默认值 undefined

19 全局对象 (The Global Object)

global object(全局对象)

19.1 全局对象的值属性 (Value Properties of the Global Object)

19.1.1 globalThis

Realm Record realm 中全局对象 "globalThis" 属性的初始值为 realm.[[GlobalEnv]].[[GlobalThisValue]]

该属性具有特性 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }。

19.1.2 Infinity

Infinity 的值为 +∞𝔽(见 6.1.6.1)。该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

19.1.3 NaN

NaN 的值为 NaN(见 6.1.6.1)。该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

19.1.4 undefined

undefined 的值为 undefined(见 6.1.1)。该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

19.2 全局对象的函数属性 (Function Properties of the Global Object)

19.2.1 eval ( x )

此函数是 %eval% 本源对象。

调用时执行以下步骤:

  1. 返回 ? PerformEval(x, false, false)。

19.2.1.1 PerformEval ( x, strictCaller, direct )

The abstract operation PerformEval takes arguments x (一个 ECMAScript 语言值), strictCaller (Boolean), and direct (Boolean) and returns 正常完成(含 ECMAScript 语言值)或 throw completion. It performs the following steps when called:

  1. 断言:若 directfalse,则 strictCaller 也为 false
  2. x 不是 String,返回 x
  3. evalRealm当前 Realm Record
  4. 注:直接 eval 情况下,evalRealm 同时是调用 eval 的调用者与 eval 函数自身的 realm
  5. 执行 ? HostEnsureCanCompileStrings(evalRealm, « », x, direct)。
  6. inFunctionfalse
  7. inMethodfalse
  8. inDerivedConstructorfalse
  9. inClassFieldInitializerfalse
  10. directtrue,则
    1. thisEnvRec = GetThisEnvironment()。
    2. thisEnvRecFunction Environment Record,则
      1. F = thisEnvRec.[[FunctionObject]]
      2. inFunctiontrue
      3. inMethodthisEnvRec.HasSuperBinding()。
      4. F.[[ConstructorKind]]derived,设 inDerivedConstructortrue
      5. classFieldInitializerNameF.[[ClassFieldInitializerName]]
      6. classFieldInitializerNameempty,设 inClassFieldInitializertrue
  11. 按实现定义顺序执行以下子步骤,可交织解析与错误检测:
    1. script 为 ParseText(x, Script)。
    2. script 为错误列表,抛出 SyntaxError
    3. script Contains ScriptBodyfalse,返回 undefined
    4. bodyscriptScriptBody
    5. inFunctionfalsebody Contains NewTarget,抛出 SyntaxError
    6. inMethodfalsebody Contains SuperProperty,抛出 SyntaxError
    7. inDerivedConstructorfalsebody Contains SuperCall,抛出 SyntaxError
    8. inClassFieldInitializertrue 且 ContainsArguments(body) 为 true,抛出 SyntaxError
  12. strictCallertrue,令 strictEvaltrue
  13. 否则,令 strictEval 为 ScriptIsStrict(script)。
  14. runningContext 为正在运行的执行上下文。
  15. 注:若 directtruerunningContext 是执行直接 eval 的上下文;否则为 eval 调用的执行上下文。
  16. directtrue,则
    1. lexEnv = NewDeclarativeEnvironment(runningContext.LexicalEnvironment)。
    2. varEnv = runningContext.VariableEnvironment。
    3. privateEnv = runningContext.PrivateEnvironment。
  17. 否则,
    1. lexEnv = NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]])。
    2. varEnv = evalRealm.[[GlobalEnv]]
    3. privateEnv = null
  18. strictEvaltrue,设 varEnv = lexEnv
  19. runningContext 尚未被暂停,则暂停之。
  20. evalContext 为新的 ECMAScript 代码执行上下文
  21. 设其 Function 为 null
  22. 设其 RealmevalRealm
  23. 设其 ScriptOrModule 为 runningContext.ScriptOrModule。
  24. 设其 VariableEnvironment 为 varEnv
  25. 设其 LexicalEnvironment 为 lexEnv
  26. 设其 PrivateEnvironment 为 privateEnv
  27. 压入 evalContext;其成为正在运行的执行上下文。
  28. result = Completion(EvalDeclarationInstantiation(body, varEnv, lexEnv, privateEnv, strictEval))。
  29. result正常完成,则
    1. result = Completion(Evaluation of body)。
  30. result正常完成result.[[Value]]empty,则
    1. result = NormalCompletion(undefined)。
  31. 暂停 evalContext 并将其移出执行上下文栈。
  32. 恢复当前栈顶上下文。
  33. 返回 ? result
Note

若调用者代码或 eval 代码为严格模式代码,eval 代码不得在调用上下文的变量环境中实例化变量或函数绑定;此时这些绑定在新建的 VariableEnvironment 中实例化,仅对 eval 代码可见。由 letconstclass 声明引入的绑定总是在新 LexicalEnvironment 中实例化。

19.2.1.2 HostEnsureCanCompileStrings ( calleeRealm, parameterStrings, bodyString, direct )

The host-defined abstract operation HostEnsureCanCompileStrings takes arguments calleeRealm (Realm Record), parameterStrings (字符串列表), bodyString (字符串), and direct (Boolean) and returns 正常完成(含 unused)或 throw completion. 允许宿主环境阻止某些可让开发者将字符串解释并求值为 ECMAScript 代码的 ECMAScript 函数。

parameterStrings 表示使用函数构造器时会被连接以构造参数列表的字符串。bodyString 表示函数体或传递给 eval 的字符串。 direct 表示是否为直接 eval。

默认实现返回 NormalCompletion(unused)。

19.2.1.3 EvalDeclarationInstantiation ( body, varEnv, lexEnv, privateEnv, strict )

The abstract operation EvalDeclarationInstantiation takes arguments body (ScriptBody 解析节点), varEnv (Environment Record), lexEnv (Declarative Environment Record), privateEnv (PrivateEnvironment Recordnull), and strict (Boolean) and returns 正常完成(含 unused)或 throw completion. It performs the following steps when called:

  1. varNamesbody 的 VarDeclaredNames。
  2. varDeclarationsbody 的 VarScopedDeclarations。
  3. strictfalse,则
    1. varEnvGlobal Environment Record,则
      1. varNames 每个 name
        1. HasLexicalDeclaration(varEnv, name) 为 true,抛 SyntaxError
        2. 注:eval 不会创建会被全局词法声明遮蔽的全局 var 声明。
    2. thisEnv = lexEnv
    3. 断言:以下循环会终止。
    4. 重复,条件:thisEnvthisEnvvarEnv 不同:
      1. thisEnv 不是 Object Environment Record,则
        1. 注:with 语句环境不含词法声明,因此不需检查 var/let 提升冲突。
        2. varNames 每个 name
          1. 若 ! thisEnv.HasBinding(name) 为 true,则
            1. Normative Optional
              宿主为浏览器或支持 Catch 块中的 VariableStatements
              1. thisEnv 不是 Catch 子句的 Environment Record,抛 SyntaxError
            2. 否则,抛 SyntaxError
          2. 注:直接 eval 不会将 var 声明提升越过同名词法声明。
      2. thisEnvthisEnv.[[OuterEnv]]
  4. privateIdentifiers 为新空列表。
  5. pointer = privateEnv
  6. 重复,条件:pointernull
    1. pointer.[[Names]] 每个 Private Name binding
      1. privateIdentifiers 不含 binding.[[Description]],追加之。
    2. pointer = pointer.[[OuterPrivateEnvironment]]
  7. 若 AllPrivateIdentifiersValid(body, privateIdentifiers) 为 false,抛 SyntaxError
  8. functionsToInitialize 为新空列表。
  9. declaredFunctionNames 为新空列表。
  10. 逆序遍历 varDeclarations 中每个 d
    1. d 不是 VariableDeclarationForBindingBindingIdentifier,则
      1. 断言:dFunctionDeclarationGeneratorDeclarationAsyncFunctionDeclarationAsyncGeneratorDeclaration
      2. 注:若同名多次函数声明,最后一个生效。
      3. fn 为其 BoundNames 唯一元素。
      4. declaredFunctionNames 不含 fn,则
        1. varEnvGlobal Environment Record,则
          1. fnDefinable = ? CanDeclareGlobalFunction(varEnv, fn)。
          2. fnDefinablefalse,抛 TypeError
        2. 追加 fndeclaredFunctionNames
        3. d 插入 functionsToInitialize 首位。
  11. declaredVarNames 为新空列表。
  12. 遍历 varDeclarations 中每个 d
    1. dVariableDeclarationForBindingBindingIdentifier,则
      1. 对其 BoundNames 每个字符串 vn
        1. declaredFunctionNames 不含 vn,则
          1. varEnvGlobal Environment Record,则
            1. vnDefinable = ? CanDeclareGlobalVar(varEnv, vn)。
            2. vnDefinablefalse,抛 TypeError
          2. declaredVarNames 不含 vn,则追加之。
  13. Normative Optional
    strictfalse宿主为浏览器或支持 块级函数声明 Web 历史兼容语义,则
    1. declaredFunctionOrVarNamesdeclaredFunctionNamesdeclaredVarNames 的连接。
    2. 对每个直接包含于任何 BlockCaseClauseDefaultClauseStatementList 中、且使 body Contains 该子节点为 trueFunctionDeclaration f
      1. F 为其 BindingIdentifier 的 StringValue。
      2. 若将 f 替换为以 FBindingIdentifierVariableStatement 不会为 body 产生早期错误,则
        1. bindingExistsfalse
        2. thisEnv = lexEnv
        3. 断言:以下循环终止。
        4. 重复,条件:thisEnvvarEnv
          1. thisEnv 不是 Object Environment Record,则
            1. 若 ! thisEnv.HasBinding(F) 为 true,则
              1. Normative Optional
                宿主为浏览器或支持 Catch 块中的 VariableStatements
                1. thisEnv 不是 Catch 子句的 Environment Record,设 bindingExiststrue
              2. 否则设 bindingExiststrue
          2. thisEnv = thisEnv.[[OuterEnv]]
        5. bindingExistsfalsevarEnvGlobal Environment Record,则
          1. HasLexicalDeclaration(varEnv, F) 为 false,则
            1. fnDefinable = ? CanDeclareGlobalVar(varEnv, F)。
          2. 否则设 fnDefinablefalse
        6. 否则,
          1. fnDefinabletrue
        7. bindingExistsfalsefnDefinabletrue,则
          1. declaredFunctionOrVarNames 不含 F,则
            1. varEnvGlobal Environment Record,则
              1. 执行 ? CreateGlobalVarBinding(varEnv, F, true)。
            2. 否则,
              1. bindingExists = ! varEnv.HasBinding(F)。
              2. bindingExistsfalse,则
                1. 执行 ! varEnv.CreateMutableBinding(F, true)。
                2. 执行 ! varEnv.InitializeBinding(F, undefined)。
            3. 追加 FdeclaredFunctionOrVarNames
          2. FunctionDeclaration f 被求值时,执行以下步骤替代 15.2.6 中的求值算法:
            1. gEnv 为正在运行执行上下文的 VariableEnvironment。
            2. bEnv 为正在运行执行上下文的 LexicalEnvironment。
            3. fObj 为 ! bEnv.GetBindingValue(F, false)。
            4. 执行 ? gEnv.SetMutableBinding(F, fObj, false)。
            5. 返回 unused
  14. 注:除非 varEnvGlobal Environment Record 且全局对象为 Proxy 异域对象,此后不再出现异常终止。
  15. lexDeclarationsbody 的 LexicallyScopedDeclarations。
  16. lexDeclarations 每个 d
    1. 注:词法声明名此处仅实例化,未初始化。
    2. d 的 BoundNames 每个 dn
      1. 若 IsConstantDeclaration(d) 为 true,执行 ? lexEnv.CreateImmutableBinding(dn, true)。
      2. 否则执行 ? lexEnv.CreateMutableBinding(dn, false)。
  17. functionsToInitialize 每个解析节点 f
    1. fn 为其 BoundNames 唯一元素。
    2. fo 为 InstantiateFunctionObject(f, lexEnv, privateEnv)。
    3. varEnvGlobal Environment Record,则
      1. 执行 ? CreateGlobalFunctionBinding(varEnv, fn, fo, true)。
    4. 否则,
      1. bindingExists = ! varEnv.HasBinding(fn)。
      2. false
        1. 注:因前置验证,不会异常。
        2. 执行 ! varEnv.CreateMutableBinding(fn, true)。
        3. 执行 ! varEnv.InitializeBinding(fn, fo)。
      3. 否则执行 ! varEnv.SetMutableBinding(fn, fo, false)。
  18. declaredVarNames 每个字符串 vn
    1. varEnvGlobal Environment Record,则
      1. 执行 ? CreateGlobalVarBinding(varEnv, vn, true)。
    2. 否则,
      1. bindingExists = ! varEnv.HasBinding(vn)。
      2. false
        1. 注:因前置验证不异常。
        2. 执行 ! varEnv.CreateMutableBinding(vn, true)。
        3. 执行 ! varEnv.InitializeBinding(vn, undefined)。
  19. 返回 unused

19.2.2 isFinite ( number )

此函数是 %isFinite% 本源对象。

调用时执行:

  1. num = ? ToNumber(number)。
  2. num 不是有限值,返回 false
  3. 否则返回 true

19.2.3 isNaN ( number )

此函数是 %isNaN% 本源对象。

调用时执行:

  1. num = ? ToNumber(number)。
  2. numNaN,返回 true
  3. 否则返回 false
Note

在 ECMAScript 中检测值 X 是否为 NaN 的可靠方式是 X !== X;仅当且仅当 XNaN 时结果为 true

19.2.4 parseFloat ( string )

该函数根据对参数 string 内容按十进制字面量的解释产生一个 Number 值。

它是 %parseFloat% 本源对象。

调用时执行:

  1. inputString = ? ToString(string)。
  2. trimmedString = ! TrimString(inputString, start)。
  3. trimmed = StringToCodePoints(trimmedString)。
  4. trimmedPrefixtrimmed 的最长前缀,满足 StrDecimalLiteral 语法,可能等于 trimmed 本身。若不存在,返回 NaN
  5. parsedNumber = ParseText(trimmedPrefix, StrDecimalLiteral)。
  6. 断言:parsedNumber解析节点
  7. 返回 parsedNumber 的 StringNumericValue。
Note

该函数可能仅将 string 的前导部分解释为 Number;忽略无法视为十进制字面量部分的代码单元,且不会指示有代码单元被忽略。

19.2.5 parseInt ( string, radix )

该函数依据指定 radixstring 内容的解释产生一个整数 Number。忽略 string 前导空白。若 radix 强制为 0(如其为 undefined),除非数字表示以 "0x""0X" 开头,否则假设为 10;若以其开头则假设为 16。若 radix 为 16,数字表示可选以 "0x""0X" 开头。

它是 %parseInt% 本源对象。

调用时执行:

  1. inputString = ? ToString(string)。
  2. S = ! TrimString(inputString, start)。
  3. sign = 1。
  4. S 非空且首代码单元为 0x002D,设 sign = -1。
  5. S 非空且首代码单元为 0x002B 或 0x002D,设 S 为去掉首单元的子串。
  6. R = (? ToInt32(radix))。
  7. stripPrefix = true
  8. R ≠ 0,则
    1. R < 2 或 R > 36,返回 NaN
    2. R ≠ 16,设 stripPrefix = false
  9. 否则设 R = 10。
  10. stripPrefixtrue,则
    1. S 长度 ≥ 2 且前两代码单元为 "0x""0X",则
      1. S 为从索引 2 起子串。
      2. R = 16。
  11. S 含有非基数 R 数字的代码单元,令 end 为首此类代码单元索引;否则 endS 长度。
  12. Z = S 从 0 到 end 的子串。
  13. Z 为空,返回 NaN
  14. mathInt 为以基数-R 表示 Z 的整数值,使用字母 A-Z / a-z 表示 10 到 35。(但若 R = 10 且 Z 含超过 20 个有效数字,实现可将第 21 位及之后替换为 0;若 R 不在 {2,4,8,10,16,32},mathInt 可为实现近似值。)
  15. mathInt = 0,则
    1. sign = -1,返回 -0𝔽
    2. 返回 +0𝔽
  16. 返回 𝔽(sign × mathInt)。
Note

该函数可能仅将 string 的前导部分解释为整数;忽略无法视为整数表示的代码单元,且不会给出被忽略的提示。

19.2.6 URI 处理函数 (URI Handling Functions)

统一资源标识符(URI)是识别资源(如网页或文件)及其访问传输协议(如 HTTP、FTP)的字符串。ECMAScript 语言本身除提供按本节描述进行 URI 编解码的函数外,不提供使用 URI 的支持。encodeURIdecodeURI 针对完整 URI;它们假设保留字符具特殊含义(如作为分隔符),故不编码它们。encodeURIComponentdecodeURIComponent 针对 URI 的各个组成部分;它们假设保留字符代表文本,需编码以在该组成部分成为完整 URI 的一部分时避免特殊含义。

Note 1

保留字符集合基于 RFC 2396,未反映较新的 RFC 3986 所引入的变化。

Note 2

许多 ECMAScript 实现提供额外操作网页的函数与方法;这些超出本标准范围。

19.2.6.1 decodeURI ( encodedURI )

此函数计算一个新 URI,将每个可能由 encodeURI 引入的转义序列与 UTF-8 编码替换为其表示码点的 UTF-16 编码。encodeURI 不会引入的转义序列不会被替换。

它是 %decodeURI% 本源对象。

调用时执行:

  1. uriString = ? ToString(encodedURI)。
  2. preserveEscapeSet = ";/?:@&=+$,#"
  3. 返回 ? Decode(uriString, preserveEscapeSet)。

19.2.6.2 decodeURIComponent ( encodedURIComponent )

此函数计算新 URI,将每个可能由 encodeURIComponent 引入的转义序列与 UTF-8 编码替换为相应码点的 UTF-16 编码。

它是 %decodeURIComponent% 本源对象。

调用时执行:

  1. componentString = ? ToString(encodedURIComponent)。
  2. preserveEscapeSet 为空字符串。
  3. 返回 ? Decode(componentString, preserveEscapeSet)。

19.2.6.3 encodeURI ( uri )

此函数对一个 UTF-16 编码(6.1.4)的 URI 进行处理,将特定码点的每个实例替换为表示该码点 UTF-8 编码的一至四个转义序列。

它是 %encodeURI% 本源对象。

调用时执行:

  1. uriString = ? ToString(uri)。
  2. extraUnescaped = ";/?:@&=+$,#"
  3. 返回 ? Encode(uriString, extraUnescaped)。

19.2.6.4 encodeURIComponent ( uriComponent )

此函数对一个 UTF-16 编码(6.1.4)的 URI 组成部分处理,将特定码点的每个实例替换为表示该码点 UTF-8 编码的一至四个转义序列。

它是 %encodeURIComponent% 本源对象。

调用时执行:

  1. componentString = ? ToString(uriComponent)。
  2. extraUnescaped 为空字符串。
  3. 返回 ? Encode(componentString, extraUnescaped)。

19.2.6.5 Encode ( string, extraUnescaped )

The abstract operation Encode takes arguments string (字符串) and extraUnescaped (字符串) and returns 正常完成(含字符串)或 throw completion. 执行 URI 编码与转义,将 string 视为 6.1.4 所述的 UTF-16 编码码点序列。若字符在 RFC 2396 标记为未保留或出现在 extraUnescaped 中,则不转义。 It performs the following steps when called:

  1. lenstring 长度。
  2. R 为空字符串。
  3. alwaysUnescaped 为 ASCII 单词字符与 "-.!~*'()" 的串联。
  4. unescapedSet = alwaysUnescapedextraUnescaped 的串联。
  5. k = 0。
  6. 重复,条件:k < len
    1. Cstring 索引 k 的代码单元。
    2. unescapedSet 包含 C,则
      1. kk + 1。
      2. RRC 串联。
    3. 否则,
      1. cp = CodePointAt(string, k)。
      2. cp.[[IsUnpairedSurrogate]]true,抛 URIError
      3. kk + cp.[[CodeUnitCount]]
      4. Octets 为将 cp.[[CodePoint]] 进行 UTF-8 转换得到的八位组列表。
      5. Octets 每个 octet
        1. hexoctet 的大写十六进制字符串。
        2. RR"%"StringPad(hex, 2, "0", start) 串联。
  7. 返回 R
Note

因百分号编码表示单个八位组,一个码点可能由多个连续转义序列(其 UTF-8 各字节)表示。

19.2.6.6 Decode ( string, preserveEscapeSet )

The abstract operation Decode takes arguments string (字符串) and preserveEscapeSet (字符串) and returns 正常完成(含字符串)或 throw completion. 执行 URI 反转义与解码,保留对应 preserveEscapeSet 中基本拉丁字符的转义序列。 It performs the following steps when called:

  1. lenstring 长度。
  2. R 为空字符串。
  3. k = 0。
  4. 重复,条件:k < len
    1. Cstring 索引 k 的代码单元。
    2. S = C
    3. C 为 0x0025,则
      1. k + 3 > len,抛 URIError
      2. escape 为从 kk + 3 的子串。
      3. B = ParseHexOctet(string, k + 1)。
      4. B 非整数,抛 URIError
      5. kk + 2。
      6. nB 中前导 1 比特数。
      7. n = 0,则
        1. asciiChar 为数值 B 的代码单元。
        2. preserveEscapeSet 包含 asciiChar,设 S = escape;否则 S = asciiChar
      8. 否则,
        1. n = 1 或 n > 4,抛 URIError
        2. Octets = « B »。
        3. j = 1。
        4. 重复,条件:j < n
          1. kk + 1。
          2. k + 3 > len,抛 URIError
          3. 若索引 k 代码单元不是 0x0025,抛 URIError
          4. continuationByte = ParseHexOctet(string, k + 1)。
          5. 若其非整数,抛 URIError
          6. 追加 continuationByteOctets
          7. kk + 2。
          8. jj + 1。
        5. 断言:Octets 长度为 n
        6. Octets 不含有效 UTF-8 编码,抛 URIError
        7. V 为对 Octets 应用 UTF-8 转换得到的码点。
        8. S = UTF16EncodeCodePoint(V)。
    4. RRS 串联。
    5. kk + 1。
  5. 返回 R
Note

RFC 3629 禁止解码无效 UTF-8 序列。例如,无效序列 0xC0 0x80 不得解码为 0x0000。Decode 算法的实现遇到此类无效序列必须抛 URIError

19.2.6.7 ParseHexOctet ( string, position )

The abstract operation ParseHexOctet takes arguments string (字符串) and position (非负整数) and returns 非负整数或非空 SyntaxError 对象列表. 解析 stringposition 位置的两个十六进制字符序列为无符号 8 位整数。 It performs the following steps when called:

  1. lenstring 长度。
  2. 断言:position + 2 ≤ len
  3. hexDigits 为从 positionposition + 2 的子串。
  4. parseResult = ParseText(hexDigits, HexDigits[~Sep])。
  5. parseResult 不是解析节点,返回 parseResult
  6. nparseResult 的 MV。
  7. 断言:n 在 [0,255] 范围。
  8. 返回 n

19.3 全局对象的构造器属性 (Constructor Properties of the Global Object)

19.3.1 AggregateError ( . . . )

20.5.7.1

19.3.2 Array ( . . . )

23.1.1

19.3.3 ArrayBuffer ( . . . )

25.1.4

19.3.4 BigInt ( . . . )

21.2.1

19.3.5 BigInt64Array ( . . . )

23.2.5

19.3.6 BigUint64Array ( . . . )

23.2.5

19.3.7 Boolean ( . . . )

20.3.1

19.3.8 DataView ( . . . )

25.3.2

19.3.9 Date ( . . . )

21.4.2

19.3.10 Error ( . . . )

20.5.1

19.3.11 EvalError ( . . . )

20.5.5.1

19.3.12 FinalizationRegistry ( . . . )

26.2.1

19.3.13 Float16Array ( . . . )

23.2.5

19.3.14 Float32Array ( . . . )

23.2.5

19.3.15 Float64Array ( . . . )

23.2.5

19.3.16 Function ( . . . )

20.2.1

19.3.17 Int8Array ( . . . )

23.2.5

19.3.18 Int16Array ( . . . )

23.2.5

19.3.19 Int32Array ( . . . )

23.2.5

19.3.20 Iterator ( . . . )

27.1.3.1

19.3.21 Map ( . . . )

24.1.1

19.3.22 Number ( . . . )

21.1.1

19.3.23 Object ( . . . )

20.1.1

19.3.24 Promise ( . . . )

27.2.3

19.3.25 Proxy ( . . . )

28.2.1

19.3.26 RangeError ( . . . )

20.5.5.2

19.3.27 ReferenceError ( . . . )

20.5.5.3

19.3.28 RegExp ( . . . )

22.2.4

19.3.29 Set ( . . . )

24.2.2

19.3.30 SharedArrayBuffer ( . . . )

25.2.3

19.3.31 String ( . . . )

22.1.1

19.3.32 Symbol ( . . . )

20.4.1

19.3.33 SyntaxError ( . . . )

20.5.5.4

19.3.34 TypeError ( . . . )

20.5.5.5

19.3.35 Uint8Array ( . . . )

23.2.5

19.3.36 Uint8ClampedArray ( . . . )

23.2.5

19.3.37 Uint16Array ( . . . )

23.2.5

19.3.38 Uint32Array ( . . . )

23.2.5

19.3.39 URIError ( . . . )

20.5.5.6

19.3.40 WeakMap ( . . . )

24.3.1

19.3.41 WeakRef ( . . . )

26.1.1

19.3.42 WeakSet ( . . . )

24.4

19.4 全局对象的其他属性 (Other Properties of the Global Object)

19.4.1 Atomics

25.4

19.4.2 JSON

25.5

19.4.3 Math

21.3

19.4.4 Reflect

28.1

20 基础对象 (Fundamental Objects)

20.1 Object 对象 (Object Objects)

20.1.1 Object 构造函数 (The Object Constructor)

Object 构造函数

  • %Object%
  • 是全局对象 "Object" 属性的初始值。
  • 作为构造函数调用时创建一个新的普通对象
  • 作为函数而非构造函数调用时执行一次类型转换。
  • 可用作类定义的 extends 子句的取值。

20.1.1.1 Object ( [ value ] )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 既不是 undefined 也不是活动函数对象,则
    1. 返回 ? OrdinaryCreateFromConstructor(NewTarget, "%Object.prototype%")。
  2. 如果 valueundefinednull,返回 OrdinaryObjectCreate(%Object.prototype%)。
  3. 返回 ! ToObject(value)。

20.1.2 Object 构造函数的属性 (Properties of the Object Constructor)

Object 构造函数

  • 拥有一个 [[Prototype]] 内部槽,其值为 %Function.prototype%
  • "length" 属性,其值为 1𝔽
  • 具有以下附加属性:

20.1.2.1 Object.assign ( target, ...sources )

该函数将一个或多个源对象自身的可枚举自有属性的值拷贝到 target 对象。

调用时执行以下步骤:

  1. to 为 ? ToObject(target)。
  2. 如果只传入一个参数,返回 to
  3. sources 中每个元素 nextSource,执行
    1. 如果 nextSource 既不是 undefined 也不是 null,则
      1. from 为 ! ToObject(nextSource)。
      2. keys 为 ? from.[[OwnPropertyKeys]]()
      3. keys 中每个元素 nextKey,执行
        1. desc 为 ? from.[[GetOwnProperty]](nextKey)。
        2. 如果 desc 不为 undefineddesc.[[Enumerable]]true,则
          1. propValue 为 ? Get(from, nextKey)。
          2. 执行 ? Set(to, nextKey, propValue, true)。
  4. 返回 to

此函数的 "length" 属性值为 2𝔽

20.1.2.2 Object.create ( O, Properties )

该函数创建一个具有指定原型的新对象。

调用时执行以下步骤:

  1. 如果 O 不是 ObjectO 不是 null,抛出 TypeError 异常。
  2. objOrdinaryObjectCreate(O)。
  3. 如果 Properties 不是 undefined,则
    1. 返回 ? ObjectDefineProperties(obj, Properties)。
  4. 返回 obj

20.1.2.3 Object.defineProperties ( O, Properties )

该函数为对象添加自有属性和/或更新已有自有属性的特性。

调用时执行以下步骤:

  1. 如果 O 不是 Object,抛出 TypeError 异常。
  2. 返回 ? ObjectDefineProperties(O, Properties)。

20.1.2.3.1 ObjectDefineProperties ( O, Properties )

The abstract operation ObjectDefineProperties takes arguments O (an Object) and Properties (an ECMAScript language value) and returns 一个包含 Object 的正常完成或一个 throw completion. It performs the following steps when called:

  1. props 为 ? ToObject(Properties)。
  2. keys 为 ? props.[[OwnPropertyKeys]]()
  3. descriptors 为一个新的空列表。
  4. keys 中每个元素 nextKey,执行
    1. propDesc 为 ? props.[[GetOwnProperty]](nextKey)。
    2. 如果 propDesc 不为 undefinedpropDesc.[[Enumerable]]true,则
      1. descObj 为 ? Get(props, nextKey)。
      2. desc 为 ? ToPropertyDescriptor(descObj)。
      3. 将记录 { [[Key]]: nextKey, [[Descriptor]]: desc } 追加到 descriptors
  5. descriptors 中每个元素 property,执行
    1. 执行 ? DefinePropertyOrThrow(O, property.[[Key]], property.[[Descriptor]])。
  6. 返回 O

20.1.2.4 Object.defineProperty ( O, P, Attributes )

该函数为对象添加一个自有属性和/或更新已有自有属性的特性。

调用时执行以下步骤:

  1. 如果 O 不是 Object,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(P)。
  3. desc 为 ? ToPropertyDescriptor(Attributes)。
  4. 执行 ? DefinePropertyOrThrow(O, key, desc)。
  5. 返回 O

20.1.2.5 Object.entries ( O )

该函数被调用时执行以下步骤:

  1. obj 为 ? ToObject(O)。
  2. entryList 为 ? EnumerableOwnProperties(obj, key+value)。
  3. 返回 CreateArrayFromList(entryList)。

20.1.2.6 Object.freeze ( O )

该函数被调用时执行以下步骤:

  1. 如果 O 不是 Object,返回 O
  2. status 为 ? SetIntegrityLevel(O, frozen)。
  3. 如果 statusfalse,抛出 TypeError 异常。
  4. 返回 O

20.1.2.7 Object.fromEntries ( iterable )

该函数被调用时执行以下步骤:

  1. 执行 ? RequireObjectCoercible(iterable)。
  2. objOrdinaryObjectCreate(%Object.prototype%)。
  3. 断言:obj 是一个可扩展且无自有属性的普通对象
  4. closure 为一个新的抽象闭包,参数 (key, value),捕获 obj,调用时执行:
    1. propertyKey 为 ? ToPropertyKey(key)。
    2. 执行 ! CreateDataPropertyOrThrow(obj, propertyKey, value)。
    3. 返回 NormalCompletion(undefined)。
  5. adderCreateBuiltinFunction(closure, 2, "", « »)。
  6. 返回 ? AddEntriesFromIterable(obj, iterable, adder)。
Note
adder 创建的函数不会被 ECMAScript 代码直接获取。

20.1.2.8 Object.getOwnPropertyDescriptor ( O, P )

该函数被调用时执行以下步骤:

  1. obj 为 ? ToObject(O)。
  2. key 为 ? ToPropertyKey(P)。
  3. desc 为 ? obj.[[GetOwnProperty]](key)。
  4. 返回 FromPropertyDescriptor(desc)。

20.1.2.9 Object.getOwnPropertyDescriptors ( O )

该函数被调用时执行以下步骤:

  1. obj 为 ? ToObject(O)。
  2. ownKeys 为 ? obj.[[OwnPropertyKeys]]()
  3. descriptorsOrdinaryObjectCreate(%Object.prototype%)。
  4. ownKeys 中每个元素 key,执行
    1. desc 为 ? obj.[[GetOwnProperty]](key)。
    2. descriptorFromPropertyDescriptor(desc)。
    3. 如果 descriptor 不为 undefined,执行 ! CreateDataPropertyOrThrow(descriptors, key, descriptor)。
  5. 返回 descriptors

20.1.2.10 Object.getOwnPropertyNames ( O )

该函数被调用时执行以下步骤:

  1. 返回 CreateArrayFromList(? GetOwnPropertyKeys(O, string))。

20.1.2.11 Object.getOwnPropertySymbols ( O )

该函数被调用时执行以下步骤:

  1. 返回 CreateArrayFromList(? GetOwnPropertyKeys(O, symbol))。

20.1.2.11.1 GetOwnPropertyKeys ( O, type )

The abstract operation GetOwnPropertyKeys takes arguments O (an ECMAScript language value) and type (string or symbol) and returns 一个包含属性键列表的正常完成或一个 throw completion. It performs the following steps when called:

  1. obj 为 ? ToObject(O)。
  2. keys 为 ? obj.[[OwnPropertyKeys]]()
  3. nameList 为一个新的空列表。
  4. keys 中每个元素 nextKey,执行
    1. 如果 nextKey 是 Symbol 且 typesymbol,或 nextKey 是 String 且 typestring,则
      1. nextKey 追加到 nameList
  5. 返回 nameList

20.1.2.12 Object.getPrototypeOf ( O )

该函数被调用时执行以下步骤:

  1. obj 为 ? ToObject(O)。
  2. 返回 ? obj.[[GetPrototypeOf]]()

20.1.2.13 Object.groupBy ( items, callback )

Note

callback 应为一个接受两个参数的函数。groupBy 按升序对 items 的每个元素调用一次 callback 并构造一个新对象。callback 返回的每个值被强制为属性键。对每个这样的属性键,结果对象都有一个该键的属性,其值是一个数组,包含所有使得 callback 返回值强制为该键的元素。

callback 以两个参数被调用:元素的值以及元素的索引。

groupBy 的返回值是一个不继承自 %Object.prototype% 的对象。

该函数被调用时执行以下步骤:

  1. groups 为 ? GroupBy(items, callback, property)。
  2. objOrdinaryObjectCreate(null)。
  3. groups 中每个记录 { [[Key]], [[Elements]] } g,执行
    1. elementsCreateArrayFromList(g.[[Elements]])。
    2. 执行 ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements)。
  4. 返回 obj

20.1.2.14 Object.hasOwn ( O, P )

该函数被调用时执行以下步骤:

  1. obj 为 ? ToObject(O)。
  2. key 为 ? ToPropertyKey(P)。
  3. 返回 ? HasOwnProperty(obj, key)。

20.1.2.15 Object.is ( value1, value2 )

该函数被调用时执行以下步骤:

  1. 返回 SameValue(value1, value2)。

20.1.2.16 Object.isExtensible ( O )

该函数被调用时执行以下步骤:

  1. 如果 O 不是 Object,返回 false
  2. 返回 ? IsExtensible(O)。

20.1.2.17 Object.isFrozen ( O )

该函数被调用时执行以下步骤:

  1. 如果 O 不是 Object,返回 true
  2. 返回 ? TestIntegrityLevel(O, frozen)。

20.1.2.18 Object.isSealed ( O )

该函数被调用时执行以下步骤:

  1. 如果 O 不是 Object,返回 true
  2. 返回 ? TestIntegrityLevel(O, sealed)。

20.1.2.19 Object.keys ( O )

该函数被调用时执行以下步骤:

  1. obj 为 ? ToObject(O)。
  2. keyList 为 ? EnumerableOwnProperties(obj, key)。
  3. 返回 CreateArrayFromList(keyList)。

20.1.2.20 Object.preventExtensions ( O )

该函数被调用时执行以下步骤:

  1. 如果 O 不是 Object,返回 O
  2. status 为 ? O.[[PreventExtensions]]()
  3. 如果 statusfalse,抛出 TypeError 异常。
  4. 返回 O

20.1.2.21 Object.prototype

Object.prototype 的初始值是 Object 原型对象。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.1.2.22 Object.seal ( O )

该函数被调用时执行以下步骤:

  1. 如果 O 不是 Object,返回 O
  2. status 为 ? SetIntegrityLevel(O, sealed)。
  3. 如果 statusfalse,抛出 TypeError 异常。
  4. 返回 O

20.1.2.23 Object.setPrototypeOf ( O, proto )

该函数被调用时执行以下步骤:

  1. 执行 ? RequireObjectCoercible(O)。
  2. 如果 proto 不是 Objectproto 不是 null,抛出 TypeError 异常。
  3. 如果 O 不是 Object,返回 O
  4. status 为 ? O.[[SetPrototypeOf]](proto)。
  5. 如果 statusfalse,抛出 TypeError 异常。
  6. 返回 O

20.1.2.24 Object.values ( O )

该函数被调用时执行以下步骤:

  1. obj 为 ? ToObject(O)。
  2. valueList 为 ? EnumerableOwnProperties(obj, value)。
  3. 返回 CreateArrayFromList(valueList)。

20.1.3 Object 原型对象的属性 (Properties of the Object Prototype Object)

Object 原型对象

  • %Object.prototype%
  • 具有 [[Extensible]] 内部槽,其值为 true
  • 具有普通对象定义的内部方法,但 [[SetPrototypeOf]] 方法按 10.4.7.1 中定义。(因此它是不可变原型奇异对象。)
  • 具有 [[Prototype]] 内部槽,其值为 null

20.1.3.1 Object.prototype.constructor

Object.prototype.constructor 的初始值是 %Object%

20.1.3.2 Object.prototype.hasOwnProperty ( V )

该方法被调用时执行以下步骤:

  1. P 为 ? ToPropertyKey(V)。
  2. O 为 ? ToObject(this value)。
  3. 返回 ? HasOwnProperty(O, P)。
Note

步骤 12 的顺序确保:即使 this 值为 undefinednull,以前版本规范中应由步骤 1 抛出的异常仍会抛出。

20.1.3.3 Object.prototype.isPrototypeOf ( V )

该方法被调用时执行以下步骤:

  1. 如果 V 不是 Object,返回 false
  2. O 为 ? ToObject(this value)。
  3. 重复,
    1. V 为 ? V.[[GetPrototypeOf]]()
    2. 如果 Vnull,返回 false
    3. 如果 SameValue(O, V) 为 true,返回 true
Note

步骤 12 的顺序保持旧版规范在 V 非对象且 this 值为 undefinednull 时的行为。

20.1.3.4 Object.prototype.propertyIsEnumerable ( V )

该方法被调用时执行以下步骤:

  1. P 为 ? ToPropertyKey(V)。
  2. O 为 ? ToObject(this value)。
  3. desc 为 ? O.[[GetOwnProperty]](P)。
  4. 如果 descundefined,返回 false
  5. 返回 desc.[[Enumerable]]
Note 1

此方法不考虑原型链上的对象。

Note 2

步骤 12 的顺序确保:即使 this 值为 undefinednull,以前版本规范中应由步骤 1 抛出的异常仍会抛出。

20.1.3.5 Object.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 返回 ? Invoke(O, "toString")。

此方法的可选参数未使用,其存在旨在与 ECMA-402 toLocaleString 方法所使用的参数模式一致。不包含 ECMA-402 支持的实现不得将这些参数位置用于其他目的。

Note 1

该方法为没有本地化敏感 toString 行为的对象提供通用 toLocaleString 实现。ArrayNumberDate%TypedArray% 提供它们自己的本地化敏感 toLocaleString 方法。

Note 2

ECMA-402 有意不为此默认实现提供替代方案。

20.1.3.6 Object.prototype.toString ( )

该方法被调用时执行以下步骤:

  1. 如果 this 值为 undefined,返回 "[object Undefined]"
  2. 如果 this 值为 null,返回 "[object Null]"
  3. O 为 ! ToObject(this value)。
  4. isArray 为 ? IsArray(O)。
  5. 如果 isArraytrue,令 builtinTag"Array"
  6. 否则如果 O[[ParameterMap]] 内部槽,令 builtinTag"Arguments"
  7. 否则如果 O 具有 [[Call]] 内部方法,令 builtinTag"Function"
  8. 否则如果 O[[ErrorData]] 内部槽,令 builtinTag"Error"
  9. 否则如果 O[[BooleanData]] 内部槽,令 builtinTag"Boolean"
  10. 否则如果 O[[NumberData]] 内部槽,令 builtinTag"Number"
  11. 否则如果 O[[StringData]] 内部槽,令 builtinTag"String"
  12. 否则如果 O[[DateValue]] 内部槽,令 builtinTag"Date"
  13. 否则如果 O[[RegExpMatcher]] 内部槽,令 builtinTag"RegExp"
  14. 否则,令 builtinTag"Object"
  15. tag 为 ? Get(O, %Symbol.toStringTag%)。
  16. 如果 tag 不是 String,设 tagbuiltinTag
  17. 返回 "[object "tag"]" 的字符串拼接。
Note

历史上,该方法有时用于访问先前版本规范中作为各种内建对象名义类型标签的 [[Class]] 内部槽的 String 值。上述 toString 定义保持使用 toString 测试特定内建对象类型的遗留代码兼容性。它并不为其他内建或程序自定义对象类型提供可靠的类型测试机制。此外,程序可使用 %Symbol.toStringTag% 的方式破坏此类遗留类型测试的可靠性。

20.1.3.7 Object.prototype.valueOf ( )

该方法被调用时执行以下步骤:

  1. 返回 ? ToObject(this value)。
Normative Optional, Legacy

20.1.3.8 Object.prototype.__proto__

Object.prototype.__proto__ 是一个访问器属性,其特性 { [[Enumerable]]: false, [[Configurable]]: true }。其 [[Get]][[Set]] 属性定义如下:

20.1.3.8.1 get Object.prototype.__proto__

[[Get]] 特性的值是一个不需要参数的内建函数。被调用时执行:

  1. O 为 ? ToObject(this value)。
  2. 返回 ? O.[[GetPrototypeOf]]()

20.1.3.8.2 set Object.prototype.__proto__

[[Set]] 特性的值是一个接受参数 proto 的内建函数。被调用时执行:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. 如果 proto 不是 Objectproto 不是 null,返回 undefined
  4. 如果 O 不是 Object,返回 undefined
  5. status 为 ? O.[[SetPrototypeOf]](proto)。
  6. 如果 statusfalse,抛出 TypeError 异常。
  7. 返回 undefined
Normative Optional, Legacy

20.1.3.9 遗留 Object.prototype 访问器方法 (Legacy Object.prototype Accessor Methods)

20.1.3.9.1 Object.prototype.__defineGetter__ ( P, getter )

该方法被调用时执行以下步骤:

  1. O 为 ? ToObject(this value)。
  2. 如果 IsCallable(getter) 为 false,抛出 TypeError 异常。
  3. desc 为 PropertyDescriptor { [[Get]]: getter, [[Enumerable]]: true, [[Configurable]]: true }。
  4. key 为 ? ToPropertyKey(P)。
  5. 执行 ? DefinePropertyOrThrow(O, key, desc)。
  6. 返回 undefined

20.1.3.9.2 Object.prototype.__defineSetter__ ( P, setter )

该方法被调用时执行以下步骤:

  1. O 为 ? ToObject(this value)。
  2. 如果 IsCallable(setter) 为 false,抛出 TypeError 异常。
  3. desc 为 PropertyDescriptor { [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: true }。
  4. key 为 ? ToPropertyKey(P)。
  5. 执行 ? DefinePropertyOrThrow(O, key, desc)。
  6. 返回 undefined

20.1.3.9.3 Object.prototype.__lookupGetter__ ( P )

该方法被调用时执行以下步骤:

  1. O 为 ? ToObject(this value)。
  2. key 为 ? ToPropertyKey(P)。
  3. 重复,
    1. desc 为 ? O.[[GetOwnProperty]](key)。
    2. 如果 desc 不为 undefined,则
      1. 如果 IsAccessorDescriptor(desc) 为 true,返回 desc.[[Get]]
      2. 返回 undefined
    3. O 为 ? O.[[GetPrototypeOf]]()
    4. 如果 Onull,返回 undefined

20.1.3.9.4 Object.prototype.__lookupSetter__ ( P )

该方法被调用时执行以下步骤:

  1. O 为 ? ToObject(this value)。
  2. key 为 ? ToPropertyKey(P)。
  3. 重复,
    1. desc 为 ? O.[[GetOwnProperty]](key)。
    2. 如果 desc 不为 undefined,则
      1. 如果 IsAccessorDescriptor(desc) 为 true,返回 desc.[[Set]]
      2. 返回 undefined
    3. O 为 ? O.[[GetPrototypeOf]]()
    4. 如果 Onull,返回 undefined

20.1.4 Object 实例的属性 (Properties of Object Instances)

Object 实例除继承自 Object 原型对象的属性外没有特殊属性。

20.2 Function 对象 (Function Objects)

20.2.1 Function 构造函数 (The Function Constructor)

Function 构造函数

  • %Function%
  • 是全局对象 "Function" 属性的初始值。
  • 作为函数而非构造函数调用时创建并初始化一个新的函数对象。因此函数调用 Function(…) 等价于使用相同参数的对象创建表达式 new Function(…)
  • 可用作类定义 extends 子句取值。打算继承规定 Function 行为的子类构造函数必须包含对 Function 构造函数super 调用,以创建并初始化一个具有内建函数行为所需内部槽的子类实例。所有 ECMAScript 语法形式定义的函数对象都是 Function 的实例。除内建 GeneratorFunction、AsyncFunction、AsyncGeneratorFunction 子类外,没有语法方式可创建 Function 子类实例。

20.2.1.1 Function ( ...parameterArgs, bodyArg )

最后一个参数(若存在)指定函数体(可执行代码);之前的任何参数指定形式参数。

该函数被调用时执行以下步骤:

  1. C 为活动函数对象
  2. 如果 bodyArg 未传入,设 bodyArg 为空字符串。
  3. 返回 ? CreateDynamicFunction(C, NewTarget, normal, parameterArgs, bodyArg)。
Note

为每个欲指定的形式参数提供一个实参是允许但非必须的。例如,下列三个表达式产生相同结果:

new Function("a", "b", "c", "return a+b+c")
new Function("a, b, c", "return a+b+c")
new Function("a,b", "c", "return a+b+c")

20.2.1.1.1 CreateDynamicFunction ( constructor, newTarget, kind, parameterArgs, bodyArg )

The abstract operation CreateDynamicFunction takes arguments constructor (a constructor), newTarget (a constructor or undefined), kind (normal, generator, async, or async-generator), parameterArgs (a List of ECMAScript language values), and bodyArg (an ECMAScript language value) and returns 一个包含 ECMAScript 函数对象正常完成或一个 throw completion. constructor 是正在执行该操作的构造函数newTarget 是最初由 new 应用于的构造函数parameterArgsbodyArg 反映传递给 constructor 的参数值。 It performs the following steps when called:

  1. 如果 newTargetundefined,设 newTargetconstructor
  2. 如果 kindnormal,则
    1. prefix"function"
    2. exprSym 为语法符号 FunctionExpression
    3. bodySym 为语法符号 FunctionBody[~Yield, ~Await]
    4. parameterSym 为语法符号 FormalParameters[~Yield, ~Await]
    5. fallbackProto"%Function.prototype%"
  3. 否则如果 kindgenerator,则
    1. prefix"function*"
    2. exprSymGeneratorExpression
    3. bodySymGeneratorBody
    4. parameterSymFormalParameters[+Yield, ~Await]
    5. fallbackProto"%GeneratorFunction.prototype%"
  4. 否则如果 kindasync,则
    1. prefix"async function"
    2. exprSymAsyncFunctionExpression
    3. bodySymAsyncFunctionBody
    4. parameterSymFormalParameters[~Yield, +Await]
    5. fallbackProto"%AsyncFunction.prototype%"
  5. 否则,
    1. 断言:kindasync-generator
    2. prefix"async function*"
    3. exprSymAsyncGeneratorExpression
    4. bodySymAsyncGeneratorBody
    5. parameterSymFormalParameters[+Yield, +Await]
    6. fallbackProto"%AsyncGeneratorFunction.prototype%"
  6. argCountparameterArgs 元素个数。
  7. parameterStrings 为一个新的空列表。
  8. parameterArgs 中每个元素 arg,执行
    1. 追加 ? ToString(arg) 到 parameterStrings
  9. bodyString 为 ? ToString(bodyArg)。
  10. currentRealm当前 Realm Record
  11. 执行 ? HostEnsureCanCompileStrings(currentRealm, parameterStrings, bodyString, false)。
  12. P 为空字符串。
  13. 如果 argCount > 0,则
    1. PparameterStrings[0]。
    2. k 为 1。
    3. k < argCount,重复
      1. nextArgStringparameterStrings[k]。
      2. PP","nextArgString 的串联。
      3. kk + 1。
  14. bodyParseString 为 0x000A、bodyString、0x000A 的串联。
  15. sourceStringprefix" anonymous("P、0x000A、") {"bodyParseString"}" 的串联。
  16. sourceText 为 StringToCodePoints(sourceString)。
  17. parameters 为 ParseText(P, parameterSym)。
  18. 如果 parameters 是错误列表,抛出 SyntaxError 异常。
  19. body 为 ParseText(bodyParseString, bodySym)。
  20. 如果 body 是错误列表,抛出 SyntaxError 异常。
  21. 注:参数和主体分开解析以保证各自单独有效。例如,new Function("/*", "*/ ) {") 不会求值为函数。
  22. 注:如果到达此步骤,sourceText 必定具有 exprSym 的语法(但反向不成立)。接下来两步的目的在于强制任何直接适用于 exprSym早期错误规则
  23. expr 为 ParseText(sourceText, exprSym)。
  24. 如果 expr 是错误列表,抛出 SyntaxError 异常。
  25. proto 为 ? GetPrototypeFromConstructor(newTarget, fallbackProto)。
  26. envcurrentRealm.[[GlobalEnv]]
  27. privateEnvnull
  28. FOrdinaryFunctionCreate(proto, sourceText, parameters, body, non-lexical-this, env, privateEnv)。
  29. 执行 SetFunctionName(F, "anonymous")。
  30. 如果 kindgenerator,则
    1. prototypeOrdinaryObjectCreate(%GeneratorPrototype%)。
    2. 执行 ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  31. 否则如果 kindasync-generator,则
    1. prototypeOrdinaryObjectCreate(%AsyncGeneratorPrototype%)。
    2. 执行 ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  32. 否则如果 kindnormal,则
    1. 执行 MakeConstructor(F)。
  33. 注:kindasync 的函数是不可构造的,不具有 [[Construct]] 内部方法或 "prototype" 属性。
  34. 返回 F
Note

CreateDynamicFunction 会在它创建的、kind 不是 async 的任何函数上定义 "prototype" 属性,以便该函数可被用作构造函数

20.2.2 Function 构造函数的属性 (Properties of the Function Constructor)

Function 构造函数

  • 其自身是一个内建函数对象
  • 拥有 [[Prototype]] 内部槽,其值为 %Function.prototype%
  • "length" 属性,其值为 1𝔽
  • 具有以下属性:

20.2.2.1 Function.prototype

Function.prototype 的值是 Function 原型对象

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.2.3 Function 原型对象的属性 (Properties of the Function Prototype Object)

Function 原型对象

  • %Function.prototype%
  • 其自身是一个内建函数对象
  • 接受任意参数并在调用时返回 undefined
  • 没有 [[Construct]] 内部方法;不能被 new 用作构造器。
  • 具有 [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 没有 "prototype" 属性。
  • "length" 属性,其值为 +0𝔽
  • "name" 属性,其值为空字符串。
Note

将 Function 原型对象指定为函数对象以确保与 ECMAScript 2015 之前代码的兼容性。

20.2.3.1 Function.prototype.apply ( thisArg, argArray )

该方法被调用时执行以下步骤:

  1. functhis 值。
  2. 如果 IsCallable(func) 为 false,抛出 TypeError 异常。
  3. 如果 argArrayundefinednull,则
    1. 执行 PrepareForTailCall()。
    2. 返回 ? Call(func, thisArg)。
  4. argList 为 ? CreateListFromArrayLike(argArray)。
  5. 执行 PrepareForTailCall()。
  6. 返回 ? Call(func, thisArg, argList)。
Note 1

thisArg 值未经修改地作为 this 值传递。这与第 3 版不同,后者将 undefinednullthisArg 替换为全局对象并对其他值应用 ToObject,然后传递该结果作为 this。尽管 thisArg 未被修改传递,非严格函数在进入时仍会执行这些转换。

Note 2

如果 func 是箭头函数或绑定函数奇异对象,那么在步骤 6[[Call]] 中会忽略 thisArg

20.2.3.2 Function.prototype.bind ( thisArg, ...args )

该方法被调用时执行以下步骤:

  1. Targetthis 值。
  2. 如果 IsCallable(Target) 为 false,抛出 TypeError 异常。
  3. F 为 ? BoundFunctionCreate(Target, thisArg, args)。
  4. L 为 0。
  5. targetHasLength 为 ? HasOwnProperty(Target, "length")。
  6. 如果 targetHasLengthtrue,则
    1. targetLen 为 ? Get(Target, "length")。
    2. 如果 targetLen 是 Number,则
      1. 如果 targetLen+∞𝔽,则
        1. L 为 +∞。
      2. 否则如果 targetLen-∞𝔽,则
        1. L 为 0。
      3. 否则,
        1. targetLenAsInt 为 ! ToIntegerOrInfinity(targetLen)。
        2. 断言:targetLenAsInt有限值。
        3. argCountargs 中元素数量。
        4. Lmax(targetLenAsInt - argCount, 0)。
  7. 执行 SetFunctionLength(F, L)。
  8. targetName 为 ? Get(Target, "name")。
  9. 如果 targetName 不是 String,设 targetName 为空字符串。
  10. 执行 SetFunctionName(F, targetName, "bound")。
  11. 返回 F
Note 1

使用 Function.prototype.bind 创建的函数对象是奇异对象。它们也没有 "prototype" 属性。

Note 2

如果 Target 是箭头函数或绑定函数奇异对象,则后续对 F 的调用不会使用该方法传入的 thisArg

20.2.3.3 Function.prototype.call ( thisArg, ...args )

该方法被调用时执行以下步骤:

  1. functhis 值。
  2. 如果 IsCallable(func) 为 false,抛出 TypeError 异常。
  3. 执行 PrepareForTailCall()。
  4. 返回 ? Call(func, thisArg, args)。
Note 1

thisArg 值未经修改地作为 this 值传递。这与第 3 版不同(见前述说明)。

Note 2

如果 func 是箭头函数或绑定函数奇异对象,则在步骤 4[[Call]] 中会忽略 thisArg

20.2.3.4 Function.prototype.constructor

Function.prototype.constructor 的初始值是 %Function%

20.2.3.5 Function.prototype.toString ( )

该方法被调用时执行以下步骤:

  1. functhis 值。
  2. 如果 func 是 Object,且 func[[SourceText]] 内部槽,func.[[SourceText]] 是 Unicode 码点序列,且 HostHasSourceTextAvailable(func) 为 true,则
    1. 返回 CodePointsToString(func.[[SourceText]])。
  3. 如果 func 是一个 内建函数对象,返回实现定义的 func 的字符串源码表示。该表示必须具有 NativeFunction 的语法。此外,如果 func[[InitialName]] 内部槽且其为 String,则返回字符串中可被 NativeFunctionAccessoropt PropertyName 匹配的部分必须为 func.[[InitialName]]
  4. 如果 func 是 ObjectIsCallable(func) 为 true,返回实现定义的、具有 NativeFunction 语法的 func 字符串源码表示。
  5. 抛出 TypeError 异常。
NativeFunction : function NativeFunctionAccessoropt PropertyName[~Yield, ~Await]opt ( FormalParameters[~Yield, ~Await] ) { [ native code ] } NativeFunctionAccessor : get set

20.2.3.6 Function.prototype [ %Symbol.hasInstance% ] ( V )

该方法被调用时执行以下步骤:

  1. Fthis 值。
  2. 返回 ? OrdinaryHasInstance(F, V)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

Note

这是大多数函数继承的 %Symbol.hasInstance% 默认实现。%Symbol.hasInstance%instanceof 运算符调用以确定一个值是否是特定构造函数的实例。如下表达式

v instanceof F

求值等价于

F[%Symbol.hasInstance%](v)

构造函数可通过在函数上暴露不同的 %Symbol.hasInstance% 方法来控制哪些对象被 instanceof 识别为其实例。

该属性不可写且不可配置,以防篡改从而可全局暴露绑定函数的目标函数。

此方法的 "name" 属性值为 "[Symbol.hasInstance]"

20.2.4 Function 实例 (Function Instances)

每个 Function 实例都是一个 ECMAScript 函数对象,并具有 Table 28 中列出的内部槽。用 Function.prototype.bind 方法 (20.2.3.2) 创建的函数对象具有 Table 29 中列出的内部槽。

Function 实例具有以下属性:

20.2.4.1 length

"length" 属性的值是一个整数 Number,表示该函数期望的典型参数数量。但语言允许以其他参数数量调用该函数。函数在以不同于其 "length" 属性所指数量的参数被调用时的行为取决于函数本身。该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

20.2.4.2 name

"name" 属性的值是一个对函数具有描述性的 String。该名称无语义意义,通常是 ECMAScript 源文本中在定义点引用该函数的变量或属性名。该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

未被本规范赋予上下文名称的匿名函数对象使用空字符串作为 "name" 属性的值。

20.2.4.3 prototype

可作为构造函数使用的 Function 实例具有 "prototype" 属性。每当此类 Function 实例被创建,会同时创建另一个普通对象作为函数 "prototype" 属性的初始值。除非另有说明,"prototype" 属性的值用于初始化该函数作为构造器被调用时新创建对象的 [[Prototype]] 内部槽。

该属性具有特性 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }。

Note

使用 Function.prototype.bind 创建的函数对象,或对一个 MethodDefinition(且不是 GeneratorMethodAsyncGeneratorMethod)或一个 ArrowFunction 求值得到的函数对象不具有 "prototype" 属性。

20.2.5 HostHasSourceTextAvailable ( func )

The host-defined abstract operation HostHasSourceTextAvailable takes argument func (a function object) and returns a Boolean. 允许宿主环境阻止为 func 提供源文本。

HostHasSourceTextAvailable 的实现必须符合以下要求:

  • 对其参数必须是确定性的。每次以特定 func 调用时必须返回相同结果。

HostHasSourceTextAvailable 的默认实现是返回 true

20.3 Boolean 对象 (Boolean Objects)

20.3.1 Boolean 构造函数 (The Boolean Constructor)

Boolean 构造函数

  • %Boolean%
  • 是全局对象 "Boolean" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 Boolean 对象。
  • 作为函数调用而非构造函数调用时执行类型转换。
  • 可用作类定义 extends 子句的取值。打算继承指定 Boolean 行为的子类构造函数必须包含对 Boolean 构造函数super 调用,以创建并初始化具有 [[BooleanData]] 内部槽的子类实例。

20.3.1.1 Boolean ( value )

该函数被调用时执行以下步骤:

  1. bToBoolean(value)。
  2. 如果 NewTarget 是 undefined,返回 b
  3. O 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Boolean.prototype%", « [[BooleanData]] »)。
  4. O.[[BooleanData]]b
  5. 返回 O

20.3.2 Boolean 构造函数的属性 (Properties of the Boolean Constructor)

Boolean 构造函数

20.3.2.1 Boolean.prototype

Boolean.prototype 的初始值是 Boolean 原型对象

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.3.3 Boolean 原型对象的属性 (Properties of the Boolean Prototype Object)

Boolean 原型对象

  • %Boolean.prototype%
  • 是一个普通对象
  • 其自身是一个 Boolean 对象;拥有 [[BooleanData]] 内部槽,值为 false
  • 具有 [[Prototype]] 内部槽,其值为 %Object.prototype%

20.3.3.1 Boolean.prototype.constructor

Boolean.prototype.constructor 的初始值是 %Boolean%

20.3.3.2 Boolean.prototype.toString ( )

该方法被调用时执行以下步骤:

  1. b 为 ? ThisBooleanValue(this value)。
  2. 如果 btrue,返回 "true";否则返回 "false"

20.3.3.3 Boolean.prototype.valueOf ( )

该方法被调用时执行以下步骤:

  1. 返回 ? ThisBooleanValue(this value)。

20.3.3.3.1 ThisBooleanValue ( value )

The abstract operation ThisBooleanValue takes argument value (an ECMAScript language value) and returns 一个包含 Boolean 的正常完成或一个 throw completion. It performs the following steps when called:

  1. 如果 value 是 Boolean,返回 value
  2. 如果 value 是 Objectvalue[[BooleanData]] 内部槽,则
    1. bvalue.[[BooleanData]]
    2. 断言:b 是 Boolean。
    3. 返回 b
  3. 抛出 TypeError 异常。

20.3.4 Boolean 实例的属性 (Properties of Boolean Instances)

Boolean 实例是继承自 Boolean 原型对象普通对象。Boolean 实例有 [[BooleanData]] 内部槽。[[BooleanData]] 内部槽是该 Boolean 对象所表示的布尔值。

20.4 Symbol 对象 (Symbol Objects)

20.4.1 Symbol 构造函数 (The Symbol Constructor)

Symbol 构造函数

  • %Symbol%
  • 是全局对象 "Symbol" 属性的初始值。
  • 作为函数调用时返回一个新的 Symbol 值。
  • 不打算与 new 运算符一起使用。
  • 不打算被继承(子类化)。
  • 可作为类定义 extends 子句的取值,但对它进行 super 调用会导致异常。

20.4.1.1 Symbol ( [ description ] )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 不为 undefined,抛出 TypeError 异常。
  2. 如果 descriptionundefined,令 descStringundefined
  3. 否则,令 descString 为 ? ToString(description)。
  4. 返回一个新的 Symbol,其 [[Description]]descString

20.4.2 Symbol 构造函数的属性 (Properties of the Symbol Constructor)

Symbol 构造函数

20.4.2.1 Symbol.asyncIterator

Symbol.asyncIterator 的初始值是著名符号 %Symbol.asyncIterator% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.2 Symbol.for ( key )

该函数被调用时执行以下步骤:

  1. stringKey 为 ? ToString(key)。
  2. 对 GlobalSymbolRegistry 列表中每个元素 e,执行
    1. 如果 e.[[Key]]stringKey,返回 e.[[Symbol]]
  3. 断言:GlobalSymbolRegistry 列表当前不包含 stringKey 的条目。
  4. newSymbol 为一个新 Symbol,其 [[Description]]stringKey
  5. 将记录 { [[Key]]: stringKey, [[Symbol]]: newSymbol } 追加到 GlobalSymbolRegistry 列表。
  6. 返回 newSymbol

GlobalSymbolRegistry List 是一个可追加的全局可用列表,所有 realm 共享。在任何 ECMAScript 代码执行前,它初始化为一个新的空列表。GlobalSymbolRegistry List 的元素是 Table 61 中结构的记录。

Table 61: GlobalSymbolRegistry 记录字段 (GlobalSymbolRegistry Record Fields)
Field Name Value Usage
[[Key]] a String 用于全局标识一个 Symbol 的字符串键。
[[Symbol]] a Symbol 可从任意 realm 检索的 symbol。

20.4.2.3 Symbol.hasInstance

Symbol.hasInstance 的初始值是著名符号 %Symbol.hasInstance% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.4 Symbol.isConcatSpreadable

Symbol.isConcatSpreadable 的初始值是著名符号 %Symbol.isConcatSpreadable% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.5 Symbol.iterator

Symbol.iterator 的初始值是著名符号 %Symbol.iterator% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.6 Symbol.keyFor ( sym )

该函数被调用时执行以下步骤:

  1. 如果 sym 不是 Symbol,抛出 TypeError 异常。
  2. 返回 KeyForSymbol(sym)。

20.4.2.7 Symbol.match

Symbol.match 的初始值是著名符号 %Symbol.match% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.8 Symbol.matchAll

Symbol.matchAll 的初始值是著名符号 %Symbol.matchAll% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.9 Symbol.prototype

Symbol.prototype 的初始值是 Symbol 原型对象

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.10 Symbol.replace

Symbol.replace 的初始值是著名符号 %Symbol.replace% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.11 Symbol.search

Symbol.search 的初始值是著名符号 %Symbol.search% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.12 Symbol.species

Symbol.species 的初始值是著名符号 %Symbol.species% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.13 Symbol.split

Symbol.split 的初始值是著名符号 %Symbol.split% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.14 Symbol.toPrimitive

Symbol.toPrimitive 的初始值是著名符号 %Symbol.toPrimitive% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.15 Symbol.toStringTag

Symbol.toStringTag 的初始值是著名符号 %Symbol.toStringTag% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.2.16 Symbol.unscopables

Symbol.unscopables 的初始值是著名符号 %Symbol.unscopables% (Table 1)。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.4.3 Symbol 原型对象的属性 (Properties of the Symbol Prototype Object)

Symbol 原型对象

  • %Symbol.prototype%
  • 是一个普通对象
  • 不是 Symbol 实例且没有 [[SymbolData]] 内部槽。
  • 具有 [[Prototype]] 内部槽,其值为 %Object.prototype%

20.4.3.1 Symbol.prototype.constructor

Symbol.prototype.constructor 的初始值是 %Symbol%

20.4.3.2 get Symbol.prototype.description

Symbol.prototype.description 是一个访问器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. sthis 值。
  2. sym 为 ? ThisSymbolValue(s)。
  3. 返回 sym.[[Description]]

20.4.3.3 Symbol.prototype.toString ( )

该方法被调用时执行以下步骤:

  1. sym 为 ? ThisSymbolValue(this value)。
  2. 返回 SymbolDescriptiveString(sym)。

20.4.3.3.1 SymbolDescriptiveString ( sym )

The abstract operation SymbolDescriptiveString takes argument sym (a Symbol) and returns a String. It performs the following steps when called:

  1. descsym.[[Description]]
  2. 如果 descundefined,设 desc 为空字符串。
  3. 断言:desc 是 String。
  4. 返回 "Symbol("desc")" 的串联。

20.4.3.4 Symbol.prototype.valueOf ( )

该方法被调用时执行以下步骤:

  1. 返回 ? ThisSymbolValue(this value)。

20.4.3.4.1 ThisSymbolValue ( value )

The abstract operation ThisSymbolValue takes argument value (an ECMAScript language value) and returns 一个包含 Symbol 的正常完成或一个 throw completion. It performs the following steps when called:

  1. 如果 value 是 Symbol,返回 value
  2. 如果 value 是 Objectvalue[[SymbolData]] 内部槽,则
    1. svalue.[[SymbolData]]
    2. 断言:s 是 Symbol。
    3. 返回 s
  3. 抛出 TypeError 异常。

20.4.3.5 Symbol.prototype [ %Symbol.toPrimitive% ] ( hint )

该方法被 ECMAScript 语言运算符调用,用于将一个 Symbol 对象转换为原始值。

被调用时执行以下步骤:

  1. 返回 ? ThisSymbolValue(this value)。
Note

参数被忽略。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

此方法的 "name" 属性值为 "[Symbol.toPrimitive]"

20.4.3.6 Symbol.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是 String 值 "Symbol"

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

20.4.4 Symbol 实例的属性 (Properties of Symbol Instances)

Symbol 实例是继承自 Symbol 原型对象普通对象,并具有 [[SymbolData]] 内部槽。[[SymbolData]] 内部槽是该 Symbol 对象所表示的 Symbol 值。

20.4.5 Symbol 的抽象操作 (Abstract Operations for Symbols)

20.4.5.1 KeyForSymbol ( sym )

The abstract operation KeyForSymbol takes argument sym (a Symbol) and returns a String or undefined. 如果 sym 在 GlobalSymbolRegistry 列表中,则返回用于注册 sym 的 String。 It performs the following steps when called:

  1. 对 GlobalSymbolRegistry 列表中每个元素 e,执行
    1. 如果 SameValue(e.[[Symbol]], sym) 为 true,返回 e.[[Key]]
  2. 断言:GlobalSymbolRegistry 列表当前不包含 sym 的条目。
  3. 返回 undefined

20.5 Error 对象 (Error Objects)

Error 对象的实例在运行时错误发生时作为异常被抛出。Error 对象也可作为用户自定义异常类的基类。

当 ECMAScript 实现检测到运行时错误时,它会抛出 20.5.5 中定义的 NativeError 对象之一的新实例,或 20.5.7 中定义的 AggregateError 对象的新实例。

20.5.1 Error 构造函数 (The Error Constructor)

Error 构造函数

  • %Error%
  • 是全局对象 "Error" 属性的初始值。
  • 作为函数而非构造函数调用时创建并初始化一个新的 Error 对象。因此函数调用 Error(…) 等价于使用相同参数的对象创建表达式 new Error(…)
  • 可用作类定义 extends 子句的取值。打算继承指定 Error 行为的子类构造函数必须包含对 Error 构造函数super 调用,以创建并初始化具有 [[ErrorData]] 内部槽的子类实例。

20.5.1.1 Error ( message [ , options ] )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 是 undefined,令 newTarget 为活动函数对象;否则令 newTarget 为 NewTarget。
  2. O 为 ? OrdinaryCreateFromConstructor(newTarget, "%Error.prototype%", « [[ErrorData]] »)。
  3. 如果 message 不是 undefined,则
    1. msg 为 ? ToString(message)。
    2. 执行 CreateNonEnumerableDataPropertyOrThrow(O, "message", msg)。
  4. 执行 ? InstallErrorCause(O, options)。
  5. 返回 O

20.5.2 Error 构造函数的属性 (Properties of the Error Constructor)

Error 构造函数

20.5.2.1 Error.isError ( arg )

该函数被调用时执行以下步骤:

  1. 如果 arg 不是 Object,返回 false
  2. 如果 arg 不具有 [[ErrorData]] 内部槽,返回 false
  3. 返回 true

20.5.2.2 Error.prototype

Error.prototype 的初始值是 Error 原型对象

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.5.3 Error 原型对象的属性 (Properties of the Error Prototype Object)

Error 原型对象

  • %Error.prototype%
  • 是一个普通对象
  • 不是 Error 实例且没有 [[ErrorData]] 内部槽。
  • 具有 [[Prototype]] 内部槽,其值为 %Object.prototype%

20.5.3.1 Error.prototype.constructor

Error.prototype.constructor 的初始值是 %Error%

20.5.3.2 Error.prototype.message

Error.prototype.message 的初始值是空字符串。

20.5.3.3 Error.prototype.name

Error.prototype.name 的初始值是 "Error"

20.5.3.4 Error.prototype.toString ( )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是 Object,抛出 TypeError 异常。
  3. name 为 ? Get(O, "name")。
  4. 如果 nameundefined,设 name"Error";否则设 name 为 ? ToString(name)。
  5. msg 为 ? Get(O, "message")。
  6. 如果 msgundefined,设 msg 为空字符串;否则设 msg 为 ? ToString(msg)。
  7. 如果 name 是空字符串,返回 msg
  8. 如果 msg 是空字符串,返回 name
  9. 返回 name、0x003A (COLON)、0x0020 (SPACE) 与 msg 的字符串拼接。

20.5.4 Error 实例的属性 (Properties of Error Instances)

Error 实例是继承自 Error 原型对象普通对象,并具有值为 undefined[[ErrorData]] 内部槽。[[ErrorData]] 的唯一规定用途是让 Object.prototype.toString (20.1.3.6) 与 Error.isError (20.5.2.1) 用于识别 Error、AggregateError 与 NativeError 实例。

20.5.5 本标准使用的原生错误类型 (Native Error Types Used in This Standard)

检测到运行时错误时,会抛出以下 NativeError 对象之一或 AggregateError 对象的新实例。所有 NativeError 对象共享相同结构,如 20.5.6 所述。

20.5.5.1 EvalError

EvalError 构造函数%EvalError%

该异常当前未在本规范中使用。此对象保留用于与先前版本规范的兼容性。

20.5.5.2 RangeError

RangeError 构造函数%RangeError%

表示一个值不在允许值集合或范围之内。

20.5.5.3 ReferenceError

ReferenceError 构造函数%ReferenceError%

表示检测到无效引用。

20.5.5.4 SyntaxError

SyntaxError 构造函数%SyntaxError%

表示发生了一个解析错误。

20.5.5.5 TypeError

TypeError 构造函数%TypeError%

TypeError 用于指示一次操作失败,且其他 NativeError 对象都不适合作为失败原因的指示。

20.5.5.6 URIError

URIError 构造函数%URIError%

表示一个全局 URI 处理函数被以与其定义不兼容的方式使用。

20.5.6 NativeError 对象结构 (NativeError Object Structure)

这些对象各自具有下面描述的结构,唯一区别在于使用的构造函数名称及其原型对象的 "name" 属性。

对于每个错误对象,定义中对 NativeError 的引用应替换为 20.5.5 中适当的错误对象名称。

20.5.6.1 NativeError 构造函数 (The NativeError Constructors)

每个 NativeError 构造函数

  • 作为函数而非构造函数调用时创建并初始化一个新的 NativeError 对象。以函数形式调用等价于以相同参数作为构造函数调用。因此函数调用 NativeError(…) 等价于对象创建表达式 new NativeError(…)
  • 可用作类定义 extends 子句的取值。子类构造函数若打算继承指定 NativeError 行为,必须包含对 NativeError 构造函数super 调用,以创建并初始化具有 [[ErrorData]] 内部槽的子类实例。

20.5.6.1.1 NativeError ( message [ , options ] )

每个 NativeError 函数被调用时执行以下步骤:

  1. 如果 NewTarget 是 undefined,令 newTarget 为活动函数对象;否则令 newTarget 为 NewTarget。
  2. O 为 ? OrdinaryCreateFromConstructor(newTarget, "%NativeError.prototype%", « [[ErrorData]] »)。
  3. 如果 message 不是 undefined,则
    1. msg 为 ? ToString(message)。
    2. 执行 CreateNonEnumerableDataPropertyOrThrow(O, "message", msg)。
  4. 执行 ? InstallErrorCause(O, options)。
  5. 返回 O

在步骤 2 中传递的字符串的实际值根据具体构造函数分别是 "%EvalError.prototype%""%RangeError.prototype%""%ReferenceError.prototype%""%SyntaxError.prototype%""%TypeError.prototype%""%URIError.prototype%"

20.5.6.2 NativeError 构造函数的属性 (Properties of the NativeError Constructors)

每个 NativeError 构造函数

  • [[Prototype]] 内部槽,其值为 %Error%
  • "name" 属性,其值为 String 值 "NativeError"
  • 具有以下属性:

20.5.6.2.1 NativeError.prototype

NativeError.prototype 的初始值是一个 NativeError 原型对象 (20.5.6.3)。每个 NativeError 构造函数有各自不同的原型对象。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.5.6.3 NativeError 原型对象的属性 (Properties of the NativeError Prototype Objects)

每个 NativeError 原型对象

  • 是一个普通对象
  • 不是 Error 实例且没有 [[ErrorData]] 内部槽。
  • 具有 [[Prototype]] 内部槽,其值为 %Error.prototype%

20.5.6.3.1 NativeError.prototype.constructor

给定 NativeError 构造函数的原型的 "constructor" 属性初始值是构造函数自身。

20.5.6.3.2 NativeError.prototype.message

给定 NativeError 构造函数的原型的 "message" 属性初始值是空字符串。

20.5.6.3.3 NativeError.prototype.name

给定 NativeError 构造函数的原型的 "name" 属性初始值是构造函数名称(替换 NativeError 的名称)的 String 值。

20.5.6.4 NativeError 实例的属性 (Properties of NativeError Instances)

NativeError 实例是继承自其 NativeError 原型对象的普通对象,并具有值为 undefined[[ErrorData]] 内部槽。[[ErrorData]] 的唯一规定用途是由 Object.prototype.toString (20.1.3.6) 和 Error.isError (20.5.2.1) 用于识别 Error、AggregateError 或 NativeError 实例。

20.5.7 AggregateError 对象 (AggregateError Objects)

20.5.7.1 AggregateError 构造函数 (The AggregateError Constructor)

AggregateError 构造函数

  • %AggregateError%
  • 是全局对象 "AggregateError" 属性的初始值。
  • 作为函数而非构造函数调用时创建并初始化一个新的 AggregateError 对象。因此函数调用 AggregateError(…) 等价于使用相同参数的对象创建表达式 new AggregateError(…)
  • 可用作类定义 extends 子句的取值。打算继承指定 AggregateError 行为的子类构造函数必须包含对 AggregateError 构造函数super 调用,以创建并初始化具有 [[ErrorData]] 内部槽的子类实例。

20.5.7.1.1 AggregateError ( errors, message [ , options ] )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 是 undefined,令 newTarget 为活动函数对象;否则令 newTarget 为 NewTarget。
  2. O 为 ? OrdinaryCreateFromConstructor(newTarget, "%AggregateError.prototype%", « [[ErrorData]] »)。
  3. 如果 message 不为 undefined,则
    1. msg 为 ? ToString(message)。
    2. 执行 CreateNonEnumerableDataPropertyOrThrow(O, "message", msg)。
  4. 执行 ? InstallErrorCause(O, options)。
  5. errorsList 为 ? IteratorToList(? GetIterator(errors, sync))。
  6. 执行 ! DefinePropertyOrThrow(O, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errorsList) })。
  7. 返回 O

20.5.7.2 AggregateError 构造函数的属性 (Properties of the AggregateError Constructor)

AggregateError 构造函数

  • 具有 [[Prototype]] 内部槽,其值为 %Error%
  • 具有以下属性:

20.5.7.2.1 AggregateError.prototype

AggregateError.prototype 的初始值是 %AggregateError.prototype%

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

20.5.7.3 AggregateError 原型对象的属性 (Properties of the AggregateError Prototype Object)

AggregateError 原型对象

  • %AggregateError.prototype%
  • 是一个普通对象
  • 不是 Error 实例或 AggregateError 实例且没有 [[ErrorData]] 内部槽。
  • 具有 [[Prototype]] 内部槽,其值为 %Error.prototype%

20.5.7.3.1 AggregateError.prototype.constructor

AggregateError.prototype.constructor 的初始值是 %AggregateError%

20.5.7.3.2 AggregateError.prototype.message

AggregateError.prototype.message 的初始值是空字符串。

20.5.7.3.3 AggregateError.prototype.name

AggregateError.prototype.name 的初始值是 "AggregateError"

20.5.7.4 AggregateError 实例的属性 (Properties of AggregateError Instances)

AggregateError 实例是继承自其 AggregateError 原型对象普通对象,并具有值为 undefined[[ErrorData]] 内部槽。[[ErrorData]] 的唯一规定用途是由 Object.prototype.toString (20.1.3.6) 和 Error.isError (20.5.2.1) 用于识别 Error、AggregateError 或 NativeError 实例。

20.5.8 Error 对象的抽象操作 (Abstract Operations for Error Objects)

20.5.8.1 InstallErrorCause ( O, options )

The abstract operation InstallErrorCause takes arguments O (an Object) and options (an ECMAScript language value) and returns 一个包含 unused正常完成或一个 throw completion. 当 options 上存在 "cause" 属性时用于在 O 上创建 "cause" 属性。 It performs the following steps when called:

  1. 如果 options 是 Object 且 ? HasProperty(options, "cause") 为 true,则
    1. cause 为 ? Get(options, "cause")。
    2. 执行 CreateNonEnumerableDataPropertyOrThrow(O, "cause", cause)。
  2. 返回 unused

21 数字与日期 (Numbers and Dates)

21.1 Number 对象 (Number Objects)

21.1.1 Number 构造函数 (The Number Constructor)

Number 构造函数

  • %Number%
  • 是全局对象 "Number" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 Number 对象。
  • 作为函数而非构造函数调用时执行一次类型转换。
  • 可用作类定义的 extends 子句取值。想要继承指定 Number 行为的子类构造函数必须包含对 Number 构造函数super 调用,以创建并初始化带有 [[NumberData]] 内部槽的子类实例。

21.1.1.1 Number ( value )

该函数被调用时执行以下步骤:

  1. 如果提供了 value,则
    1. prim 为 ? ToNumeric(value)。
    2. 如果 prim 是 BigInt,令 n𝔽((prim))。
    3. 否则,令 nprim
  2. 否则,
    1. n+0𝔽
  3. 如果 NewTarget 是 undefined,返回 n
  4. O 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Number.prototype%", « [[NumberData]] »)。
  5. O.[[NumberData]]n
  6. 返回 O

21.1.2 Number 构造函数的属性 (Properties of the Number Constructor)

Number 构造函数

21.1.2.1 Number.EPSILON

Number.EPSILON 的值是 Number 值 1 与大于 1 的最小可表示 Number 值之间差值的数量级,对应约 2.2204460492503130808472633361816 × 10-16

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.1.2.2 Number.isFinite ( number )

该函数被调用时执行以下步骤:

  1. 如果 number 不是 Number,返回 false
  2. 如果 number 不是有限值,返回 false
  3. 否则,返回 true

21.1.2.3 Number.isInteger ( number )

该函数被调用时执行以下步骤:

  1. 如果 number 是一个整数的 Number,返回 true
  2. 返回 false

21.1.2.4 Number.isNaN ( number )

该函数被调用时执行以下步骤:

  1. 如果 number 不是 Number,返回 false
  2. 如果 numberNaN,返回 true
  3. 否则,返回 false
Note

该函数不同于全局 isNaN 函数 (19.2.3),因为它在判断是否为 NaN 前不会将其参数转换为 Number。

21.1.2.5 Number.isSafeInteger ( number )

Note

整数 n 是“安全整数 (safe integer)”当且仅当 n 的 Number 值不与任何其他整数的 Number 值相同。

该函数被调用时执行以下步骤:

  1. 如果 number 是一个整数的 Number,则
    1. 如果 abs((number)) ≤ 253 - 1,返回 true
  2. 返回 false

21.1.2.6 Number.MAX_SAFE_INTEGER

Note

由于 IEEE 754-2019 精度限制导致的舍入行为,所有大于 Number.MAX_SAFE_INTEGER 的整数的 Number 值至少与另一个整数共享。此类大幅度整数因此不是 安全 的,不能保证精确表示为 Number 值,甚至不能保证彼此可区分。例如,90071992547409929007199254740993 都求值为 Number 值 9007199254740992𝔽

Number.MAX_SAFE_INTEGER 的值是 9007199254740991𝔽 (𝔽(253 - 1))。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.1.2.7 Number.MAX_VALUE

Number.MAX_VALUE 的值是 Number 类型的最大正有限值,约为 1.7976931348623157 × 10308

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.1.2.8 Number.MIN_SAFE_INTEGER

Note

由于 IEEE 754-2019 精度限制导致的舍入行为,所有小于 Number.MIN_SAFE_INTEGER 的整数的 Number 值至少与另一个整数共享。此类大幅度整数因此不是 安全 的,不能保证精确表示为 Number 值,甚至不能保证彼此可区分。例如,-9007199254740992-9007199254740993 都求值为 Number 值 -9007199254740992𝔽

Number.MIN_SAFE_INTEGER 的值是 -9007199254740991𝔽 (𝔽(-(253 - 1)))。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.1.2.9 Number.MIN_VALUE

Number.MIN_VALUE 的值是 Number 类型最小的正值,约为 5 × 10-324

IEEE 754-2019 双精度二进制表示中,最小可能值是一个非规范化数。如果实现不支持非规范化值,则 Number.MIN_VALUE 的值必须是该实现实际可表示的最小非零正值。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.1.2.10 Number.NaN

Number.NaN 的值是 NaN

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.1.2.11 Number.NEGATIVE_INFINITY

Number.NEGATIVE_INFINITY 的值是 -∞𝔽

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.1.2.12 Number.parseFloat ( string )

"parseFloat" 属性的初始值是 %parseFloat%

21.1.2.13 Number.parseInt ( string, radix )

"parseInt" 属性的初始值是 %parseInt%

21.1.2.14 Number.POSITIVE_INFINITY

Number.POSITIVE_INFINITY 的值是 +∞𝔽

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.1.2.15 Number.prototype

Number.prototype 的初始值是 Number 原型对象。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.1.3 Number 原型对象的属性 (Properties of the Number Prototype Object)

Number 原型对象

  • %Number.prototype%
  • 是一个普通对象
  • 其自身是一个 Number 对象;具有值为 +0𝔽[[NumberData]] 内部槽。
  • 具有 [[Prototype]] 内部槽,其值为 %Object.prototype%

除非明确另行说明,下面定义的 Number 原型对象的方法不是通用的;传递给它们的 this 值必须是一个 Number 值,或一个带有已初始化为 Number 值的 [[NumberData]] 内部槽的对象。

在某个方法的规范中,“this Number 值”指调用抽象操作 ThisNumberValue 并以该方法调用的 this 值作为实参所返回的结果。

21.1.3.1 Number.prototype.constructor

Number.prototype.constructor 的初始值是 %Number%

21.1.3.2 Number.prototype.toExponential ( fractionDigits )

该方法返回一个 String,内容为此 Number 值按十进制指数表示法表示,尾数小数点前一位,且小数点后有 fractionDigits 位。如果 fractionDigitsundefined,则包含区分该 Number 所需的尽可能多的尾数字符(类似 ToString,只是此处始终用指数表示法)。

被调用时执行以下步骤:

  1. x 为 ? ThisNumberValue(this value)。
  2. f 为 ? ToIntegerOrInfinity(fractionDigits)。
  3. 断言:若 fractionDigitsundefined,则 f 为 0。
  4. 如果 x 不是有限值,返回 Number::toString(x, 10)。
  5. 如果 f < 0 或 f > 100,抛出 RangeError 异常。
  6. x(x)。
  7. s 为空字符串。
  8. x < 0,则
    1. s"-"
    2. x 为 -x
  9. x = 0,则
    1. m 为包含 f + 1 个代码单元 0x0030 (DIGIT ZERO) 的 String。
    2. e 为 0。
  10. 否则,
    1. fractionDigits 不为 undefined,则
      1. en 为整数,满足 10fn < 10f + 1n × 10e - f - x 尽可能接近 0。若存在两个满足条件的 (e, n),选择使 n × 10e - f 较大的那一组。
    2. 否则,
      1. enff 为整数,满足 ff ≥ 0,10ffn < 10ff + 1𝔽(n × 10e - ff) 为 𝔽(x),且 ff 尽可能小。注意:n 的十进制表示有 ff + 1 位,n 不可被 10 整除,并且 n 的最低有效位不一定唯一确定。
      2. fff
    3. mn 十进制表示的数字(按顺序,无前导零)组成的 String。
  11. f ≠ 0,则
    1. am 的第一个代码单元。
    2. bm 的其余 f 个代码单元。
    3. ma"."b 的串联。
  12. e = 0,则
    1. c"+"
    2. d"0"
  13. 否则,
    1. e > 0,则
      1. c"+"
    2. 否则,
      1. 断言:e < 0。
      2. c"-"
      3. e 为 -e
    3. de 十进制表示数字(按顺序,无前导零)组成的 String。
  14. mm"e"cd 的串联。
  15. 返回 sm 的串联。
Note

对于提供比上述规则更高精度转换的实现,建议使用下列替代版本的步骤 10.b.i 作为指导:

  1. enf 为整数,满足 f ≥ 0,10fn < 10f + 1𝔽(n × 10e - f) 为 𝔽(x),且 f 尽可能小。若 n 存在多个可能值,选择使 𝔽(n × 10e - f) 与 𝔽(x) 最接近的 n;若有两个这样的 n,选择偶数的那个。

21.1.3.3 Number.prototype.toFixed ( fractionDigits )

Note 1

该方法返回一个 String,内容为此 Number 值按十进制定点表示法表示,在小数点后有 fractionDigits 位。如果 fractionDigitsundefined,则假定为 0。

被调用时执行以下步骤:

  1. x 为 ? ThisNumberValue(this value)。
  2. f 为 ? ToIntegerOrInfinity(fractionDigits)。
  3. 断言:若 fractionDigitsundefined,则 f 为 0。
  4. 如果 f 不是有限值,抛出 RangeError 异常。
  5. 如果 f < 0 或 f > 100,抛出 RangeError 异常。
  6. 如果 x 不是有限值,返回 Number::toString(x, 10)。
  7. x(x)。
  8. s 为空字符串。
  9. x < 0,则
    1. s"-"
    2. x 为 -x
  10. x ≥ 1021,则
    1. m 为 ! ToString(𝔽(x))。
  11. 否则,
    1. n 为整数,使得 n / 10f - x 尽可能接近 0。若有两个这样的 n,取较大的。
    2. n = 0,令 m"0";否则令 mn 十进制表示数字(按顺序,无前导零)组成的 String。
    3. f ≠ 0,则
      1. km 的长度。
      2. kf,则
        1. z 为包含 f + 1 - k 个代码单元 0x0030 (DIGIT ZERO) 的 String。
        2. mzm 的串联。
        3. kf + 1。
      3. am 的前 k - f 个代码单元。
      4. bm 其余 f 个代码单元。
      5. ma"."b 的串联。
  12. 返回 sm 的串联。
Note 2

toFixed 的输出在某些值上可能比 toString 更精确,因为 toString 只打印区分该数字与相邻 Number 值所需的有效数字。例如:

(1000000000000000128).toString() 返回 "1000000000000000100",而
(1000000000000000128).toFixed(0) 返回 "1000000000000000128"

21.1.3.4 Number.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按 ECMA-402 规范实现此方法。若实现不包含 ECMA-402 API,则使用下列规范:

此方法生成一个 String,表示此 Number 值,按宿主环境当前语言环境的约定格式化。该方法是实现定义的;允许(但不鼓励)它返回与 toString 相同的结果。

此方法可选参数的意义在 ECMA-402 规范中定义;不包含 ECMA-402 支持的实现不得将这些参数位置用于其他目的。

21.1.3.5 Number.prototype.toPrecision ( precision )

该方法返回一个 String,内容为此 Number 值:要么使用十进制指数表示法(尾数小数点前 1 位,后面有 precision - 1 位),要么使用十进制定点表示法(共 precision 个有效数字)。如果 precisionundefined,则调用 ToString

被调用时执行以下步骤:

  1. x 为 ? ThisNumberValue(this value)。
  2. 如果 precisionundefined,返回 ! ToString(x)。
  3. p 为 ? ToIntegerOrInfinity(precision)。
  4. 如果 x 不是有限值,返回 Number::toString(x, 10)。
  5. 如果 p < 1 或 p > 100,抛出 RangeError 异常。
  6. x(x)。
  7. s 为空字符串。
  8. x < 0,则
    1. s 为代码单元 0x002D (HYPHEN-MINUS)。
    2. x 为 -x
  9. x = 0,则
    1. m 为包含 p 个代码单元 0x0030 (DIGIT ZERO) 的 String。
    2. e 为 0。
  10. 否则,
    1. en 为整数,满足 10p - 1n < 10pn × 10e - p + 1 - x 尽可能接近 0。若存在两个满足条件的 (e, n),选择使 n × 10e - p + 1 较大的那一组。
    2. mn 十进制表示数字(按顺序,无前导零)组成的 String。
    3. e < -6 或 ep,则
      1. 断言:e ≠ 0。
      2. p ≠ 1,则
        1. am 的第一个代码单元。
        2. bm 的其余 p - 1 个代码单元。
        3. ma"."b 的串联。
      3. e > 0,则
        1. c 为代码单元 0x002B (PLUS SIGN)。
      4. 否则,
        1. 断言:e < 0。
        2. c 为代码单元 0x002D (HYPHEN-MINUS)。
        3. e 为 -e
      5. de 十进制表示数字(按顺序,无前导零)组成的 String。
      6. 返回 sm、代码单元 0x0065 (LATIN SMALL LETTER E)、cd 的串联。
  11. e = p - 1,返回 sm 的串联。
  12. e ≥ 0,则
    1. m 为:m 的前 e + 1 个代码单元、代码单元 0x002E (FULL STOP)、以及剩余 p - (e + 1) 个代码单元的串联。
  13. 否则,
    1. m 为:代码单元 0x0030 (DIGIT ZERO)、代码单元 0x002E (FULL STOP)、-(e + 1) 个代码单元 0x0030 (DIGIT ZERO)、以及字符串 m 的串联。
  14. 返回 sm 的串联。

21.1.3.6 Number.prototype.toString ( [ radix ] )

Note

可选的 radix 应是区间 2𝔽36𝔽(含)内的整数 Number。若 radixundefined 则其值取 10𝔽

该方法被调用时执行以下步骤:

  1. x 为 ? ThisNumberValue(this value)。
  2. radixundefined,令 radixMV 为 10。
  3. 否则,令 radixMV 为 ? ToIntegerOrInfinity(radix)。
  4. radixMV 不在 2 到 36 的区间内(含端点),抛出 RangeError 异常。
  5. 返回 Number::toString(x, radixMV)。

该方法不是通用的;如果其 this 值不是一个 Number 或 Number 对象则抛出 TypeError。因此它不能被转移到其他类型对象上作为方法使用。

该方法的 "length" 属性值为 1𝔽

21.1.3.7 Number.prototype.valueOf ( )

  1. 返回 ? ThisNumberValue(this value)。

21.1.3.7.1 ThisNumberValue ( value )

The abstract operation ThisNumberValue takes argument value (an ECMAScript language value) and returns 一个包含 Number 的正常完成或一个 throw completion. It performs the following steps when called:

  1. 如果 value 是 Number,返回 value
  2. 如果 value 是 Objectvalue[[NumberData]] 内部槽,则
    1. nvalue.[[NumberData]]
    2. 断言:n 是 Number
    3. 返回 n
  3. 抛出 TypeError 异常。

21.1.4 Number 实例的属性 (Properties of Number Instances)

Number 实例是继承自 Number 原型对象普通对象。Number 实例还具有 [[NumberData]] 内部槽。[[NumberData]] 内部槽是该 Number 对象所表示的 Number 值。

21.2 BigInt 对象 (BigInt Objects)

21.2.1 BigInt 构造函数 (The BigInt Constructor)

BigInt 构造函数

  • %BigInt%
  • 是全局对象 "BigInt" 属性的初始值。
  • 作为函数而非构造函数调用时执行类型转换。
  • 不打算与 new 运算符一起使用,也不打算被子类化。它可用作类定义 extends 子句的取值,但对 BigInt 构造函数super 调用将导致异常。

21.2.1.1 BigInt ( value )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 不为 undefined,抛出 TypeError 异常。
  2. prim 为 ? ToPrimitive(value, number)。
  3. 如果 prim 是 Number,返回 ? NumberToBigInt(prim)。
  4. 否则,返回 ? ToBigInt(prim)。

21.2.1.1.1 NumberToBigInt ( number )

The abstract operation NumberToBigInt takes argument number (a Number) and returns 要么是包含一个 BigInt 的正常完成,要么是一个 throw completion. It performs the following steps when called:

  1. 如果 number 不是整数的 Number,抛出 RangeError 异常。
  2. 返回 ((number))。

21.2.2 BigInt 构造函数的属性 (Properties of the BigInt Constructor)

BigInt 构造函数

21.2.2.1 BigInt.asIntN ( bits, bigint )

该函数被调用时执行以下步骤:

  1. bits 设为 ? ToIndex(bits)。
  2. bigint 设为 ? ToBigInt(bigint)。
  3. mod(bigint) 对 2bits 取模的结果。
  4. 如果 mod ≥ 2bits - 1,返回 (mod - 2bits);否则返回 (mod)。

21.2.2.2 BigInt.asUintN ( bits, bigint )

该函数被调用时执行以下步骤:

  1. bits 设为 ? ToIndex(bits)。
  2. bigint 设为 ? ToBigInt(bigint)。
  3. 返回 ((bigint) modulo 2bits)。

21.2.2.3 BigInt.prototype

BigInt.prototype 的初始值是 BigInt 原型对象。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.2.3 BigInt 原型对象的属性 (Properties of the BigInt Prototype Object)

BigInt 原型对象

在一个方法的规范中,短语 “this BigInt value” 指调用抽象操作 ThisBigIntValue 并以该方法调用的 this 值为实参所返回的结果。

21.2.3.1 BigInt.prototype.constructor

BigInt.prototype.constructor 的初始值是 %BigInt%

21.2.3.2 BigInt.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按 ECMA-402 规范实现此方法。如果实现不包含 ECMA-402 API,则使用以下规范:

该方法生成一个表示此 BigInt 值的 String,按照宿主环境当前区域设置的惯例格式化。此方法是实现定义的;允许(但不鼓励)其返回与 toString 相同的结果。

此方法可选参数的意义由 ECMA-402 规范定义;不包含 ECMA-402 支持的实现不得将这些参数位置用于其他用途。

21.2.3.3 BigInt.prototype.toString ( [ radix ] )

Note

可选的 radix 应为区间 2𝔽36𝔽(含)内的整数 Number。如果 radixundefined,则使用 10𝔽 作为基数。

该方法被调用时执行以下步骤:

  1. x 为 ? ThisBigIntValue(this value)。
  2. 如果 radixundefined,令 radixMV 为 10。
  3. 否则,令 radixMV 为 ? ToIntegerOrInfinity(radix)。
  4. 如果 radixMV 不在 2 到 36 的闭区间内,抛出 RangeError 异常。
  5. 返回 BigInt::toString(x, radixMV)。

该方法不是通用的;如果其 this不是 BigInt 或 BigInt 对象则抛出 TypeError 异常。因此它不能被转移到其他类型对象上用作方法。

21.2.3.4 BigInt.prototype.valueOf ( )

  1. 返回 ? ThisBigIntValue(this value)。

21.2.3.4.1 ThisBigIntValue ( value )

The abstract operation ThisBigIntValue takes argument value (an ECMAScript language value) and returns 要么是包含一个 BigInt 的正常完成,要么是一个 throw completion. It performs the following steps when called:

  1. 如果 value 是 BigInt,返回 value
  2. 如果 value 是 Objectvalue[[BigIntData]] 内部槽,则
    1. 断言:value.[[BigIntData]] 是 BigInt
    2. 返回 value.[[BigIntData]]
  3. 抛出 TypeError 异常。

21.2.3.5 BigInt.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "BigInt"

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

21.2.4 BigInt 实例的属性 (Properties of BigInt Instances)

BigInt 实例是继承自 BigInt 原型对象普通对象。BigInt 实例还具有 [[BigIntData]] 内部槽。[[BigIntData]] 内部槽是该 BigInt 对象所表示的 BigInt 值

21.3 Math 对象 (The Math Object)

Math 对象:

  • %Math%
  • 是全局对象 "Math" 属性的初始值。
  • 是一个普通对象
  • [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 不是函数对象
  • 没有 [[Construct]] 内部方法;不能与 new 一起作为构造函数使用。
  • 没有 [[Call]] 内部方法;不能作为函数调用。
Note

在本规范中,短语 “the Number value for x” 有在 6.1.6.1 中定义的技术含义。

21.3.1 Math 对象的值属性 (Value Properties of the Math Object)

21.3.1.1 Math.E

自然对数的底 e 的 Number 值,约为 2.7182818284590452354。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.3.1.2 Math.LN10

10 的自然对数的 Number 值,约为 2.302585092994046。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.3.1.3 Math.LN2

2 的自然对数的 Number 值,约为 0.6931471805599453。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.3.1.4 Math.LOG10E

e 的常用对数(以 10 为底)的 Number 值,约为 0.4342944819032518。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

Note

Math.LOG10E 的值约等于 Math.LN10 值的倒数。

21.3.1.5 Math.LOG2E

e 的以 2 为底的对数的 Number 值,约为 1.4426950408889634。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

Note

Math.LOG2E 的值约等于 Math.LN2 值的倒数。

21.3.1.6 Math.PI

圆周率 π 的 Number 值,即圆的周长与直径之比,约为 3.1415926535897932。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.3.1.7 Math.SQRT1_2

1/2 的平方根的 Number 值,约为 0.7071067811865476。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

Note

Math.SQRT1_2 的值约等于 Math.SQRT2 值的倒数。

21.3.1.8 Math.SQRT2

2 的平方根的 Number 值,约为 1.4142135623730951。

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.3.1.9 Math [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "Math"

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

21.3.2 Math 对象的函数属性 (Function Properties of the Math Object)

Note

acosacoshasinasinhatanatanhatan2cbrtcoscoshexpexpm1hypotloglog1plog2log10powrandomsinsinhtantanh 这些函数的行为,在此未被精确规定,除要求在某些表示边界情况的参数值上给出特定结果。对于其它参数值,这些函数旨在计算熟知数学函数的近似值,但在近似算法的选择上允许一定自由。总体意图是:实现者应能在某硬件平台上为 ECMAScript 使用与该平台上 C 程序员可用的同一数学库。

虽然算法选择留给实现,但(非标准要求地)推荐实现使用 Sun Microsystems 的可自由发布数学库 fdlibm(适用于 IEEE 754-2019 算术的近似算法)(http://www.netlib.org/fdlibm)。

21.3.2.1 Math.abs ( x )

返回 x 的绝对值;结果与 x 具有相同数值大小且符号为正。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN,返回 NaN
  3. 如果 n-0𝔽,返回 +0𝔽
  4. 如果 n-∞𝔽,返回 +∞𝔽
  5. 如果 n < -0𝔽,返回 -n
  6. 返回 n

21.3.2.2 Math.acos ( x )

返回 x 的反余弦。结果用弧度表示,位于 +0𝔽𝔽(π) 的闭区间

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN,或 n > 1𝔽,或 n < -1𝔽,返回 NaN
  3. 如果 n1𝔽,返回 +0𝔽
  4. 返回一个实现近似的 Number,表示 (n) 的反余弦。

21.3.2.3 Math.acosh ( x )

返回 x 的反双曲余弦。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+∞𝔽,返回 n
  3. 如果 n1𝔽,返回 +0𝔽
  4. 如果 n < 1𝔽,返回 NaN
  5. 返回一个实现近似的 Number,表示 (n) 的反双曲余弦。

21.3.2.4 Math.asin ( x )

返回 x 的反正弦。结果用弧度表示,位于 𝔽(-π / 2) 到 𝔽(π / 2) 的闭区间

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+0𝔽-0𝔽 之一,返回 n
  3. 如果 n > 1𝔽n < -1𝔽,返回 NaN
  4. 返回一个实现近似的 Number,表示 (n) 的反正弦。

21.3.2.5 Math.asinh ( x )

返回 x 的反双曲正弦。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 n有限n+0𝔽-0𝔽,返回 n
  3. 返回一个实现近似的 Number,表示 (n) 的反双曲正弦。

21.3.2.6 Math.atan ( x )

返回 x 的反正切。结果用弧度表示,位于 𝔽(-π / 2) 到 𝔽(π / 2) 的闭区间

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+0𝔽-0𝔽 之一,返回 n
  3. 如果 n+∞𝔽,返回一个实现近似的 Number,表示 π / 2。
  4. 如果 n-∞𝔽,返回一个实现近似的 Number,表示 -π / 2。
  5. 返回一个实现近似的 Number,表示 (n) 的反正切。

21.3.2.7 Math.atanh ( x )

返回 x 的反双曲正切。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+0𝔽-0𝔽 之一,返回 n
  3. 如果 n > 1𝔽n < -1𝔽,返回 NaN
  4. 如果 n1𝔽,返回 +∞𝔽
  5. 如果 n-1𝔽,返回 -∞𝔽
  6. 返回一个实现近似的 Number,表示 (n) 的反双曲正切。

21.3.2.8 Math.atan2 ( y, x )

返回参数 yx 的商 y / x 的反正切,yx 的符号用于确定结果所在象限。注意按传统约定,两个参数的反正切函数中名为 y 的参数在前,名为 x 的参数在后。结果用弧度表示,位于 -π 到 +π 的闭区间

被调用时执行以下步骤:

  1. ny 为 ? ToNumber(y)。
  2. nx 为 ? ToNumber(x)。
  3. 如果 nyNaNnxNaN,返回 NaN
  4. 如果 ny+∞𝔽,则
    1. 如果 nx+∞𝔽,返回一个实现近似的 Number,表示 π / 4。
    2. 如果 nx-∞𝔽,返回一个实现近似的 Number,表示 3π / 4。
    3. 返回一个实现近似的 Number,表示 π / 2。
  5. 如果 ny-∞𝔽,则
    1. 如果 nx+∞𝔽,返回一个实现近似的 Number,表示 -π / 4。
    2. 如果 nx-∞𝔽,返回一个实现近似的 Number,表示 -3π / 4。
    3. 返回一个实现近似的 Number,表示 -π / 2。
  6. 如果 ny+0𝔽,则
    1. 如果 nx > +0𝔽nx+0𝔽,返回 +0𝔽
    2. 返回一个实现近似的 Number,表示 π。
  7. 如果 ny-0𝔽,则
    1. 如果 nx > +0𝔽nx+0𝔽,返回 -0𝔽
    2. 返回一个实现近似的 Number,表示 -π。
  8. 断言:ny有限,且既不是 +0𝔽 也不是 -0𝔽
  9. 如果 ny > +0𝔽,则
    1. 如果 nx+∞𝔽,返回 +0𝔽
    2. 如果 nx-∞𝔽,返回一个实现近似的 Number,表示 π。
    3. 如果 nx+0𝔽-0𝔽,返回一个实现近似的 Number,表示 π / 2。
  10. 如果 ny < -0𝔽,则
    1. 如果 nx+∞𝔽,返回 -0𝔽
    2. 如果 nx-∞𝔽,返回一个实现近似的 Number,表示 -π。
    3. 如果 nx+0𝔽-0𝔽,返回一个实现近似的 Number,表示 -π / 2。
  11. 断言:nx有限,且既不是 +0𝔽 也不是 -0𝔽
  12. rabs((ny) / (nx)) 的反正切。
  13. 如果 nx < -0𝔽,则
    1. 如果 ny > +0𝔽,设 r = π - r
    2. 否则,设 r = -π + r
  14. 否则,
    1. 如果 ny < -0𝔽,设 r = -r
  15. 返回一个实现近似的 Number,表示 r

21.3.2.9 Math.cbrt ( x )

返回 x 的立方根。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 n有限n+0𝔽-0𝔽,返回 n
  3. 返回一个实现近似的 Number,表示 (n) 的立方根。

21.3.2.10 Math.ceil ( x )

返回不小于 x 的最小(最接近 -∞)整数 Number 值。若 x 已是整数 Number,则结果为 x

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 n有限n+0𝔽-0𝔽,返回 n
  3. 如果 n < -0𝔽n > -1𝔽,返回 -0𝔽
  4. 如果 n 是整数的 Number,返回 n
  5. 返回不小于 n 的最小(最接近 -∞)整数 Number。
Note

Math.ceil(x) 的值与 -Math.floor(-x) 的值相同。

21.3.2.11 Math.clz32 ( x )

该函数被调用时执行以下步骤:

  1. n 为 ? ToUint32(x)。
  2. pn 的无符号 32 位二进制表示的前导零位数。
  3. 返回 𝔽(p)。
Note

如果 n+0𝔽-0𝔽,本方法返回 32𝔽。如果 n 的 32 位最高有效位是 1,本方法返回 +0𝔽

21.3.2.12 Math.cos ( x )

返回 x 的余弦。参数用弧度表示。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 n有限,返回 NaN
  3. 如果 n+0𝔽-0𝔽,返回 1𝔽
  4. 返回一个实现近似的 Number,表示 (n) 的余弦。

21.3.2.13 Math.cosh ( x )

返回 x 的双曲余弦。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN,返回 NaN
  3. 如果 n+∞𝔽-∞𝔽,返回 +∞𝔽
  4. 如果 n+0𝔽-0𝔽,返回 1𝔽
  5. 返回一个实现近似的 Number,表示 (n) 的双曲余弦。
Note

Math.cosh(x) 的值等于 (Math.exp(x) + Math.exp(-x)) / 2

21.3.2.14 Math.exp ( x )

返回指数函数 exe 为自然对数的底)。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+∞𝔽,返回 n
  3. 如果 n+0𝔽-0𝔽,返回 1𝔽
  4. 如果 n-∞𝔽,返回 +0𝔽
  5. 返回一个实现近似的 Number,表示 (n) 的指数函数值。

21.3.2.15 Math.expm1 ( x )

返回指数函数 ex 减 1 的结果(e 为自然对数的底)。即使 x 接近 0 也应保持精确。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+0𝔽、* -0*𝔽+∞𝔽 之一,返回 n
  3. 如果 n-∞𝔽,返回 -1𝔽
  4. exp(n) 的指数函数。
  5. 返回一个实现近似的 Number,表示 exp - 1。

21.3.2.16 Math.floor ( x )

返回不大于 x 的最大(最接近 +∞)整数 Number 值。若 x 已是整数 Number,则结果为 x

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 n有限n+0𝔽-0𝔽,返回 n
  3. 如果 n < 1𝔽n > +0𝔽,返回 +0𝔽
  4. 如果 n 是整数的 Number,返回 n
  5. 返回不大于 n 的最大(最接近 +∞)整数 Number。
Note

Math.floor(x) 的值与 -Math.ceil(-x) 的值相同。

21.3.2.17 Math.fround ( x )

该函数被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN,返回 NaN
  3. 如果 n+0𝔽、* -0*𝔽+∞𝔽-∞𝔽 之一,返回 n
  4. n32 为将 n 按 roundTiesToEven 模式转换为 IEEE 754-2019 binary32 格式的结果。
  5. n64 为将 n32 转换为 IEEE 754-2019 binary64 格式的结果。
  6. 返回与 n64 对应的 ECMAScript Number 值。

21.3.2.18 Math.f16round ( x )

该函数被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN,返回 NaN
  3. 如果 n+0𝔽、* -0*𝔽+∞𝔽-∞𝔽 之一,返回 n
  4. n16 为将 n 按 roundTiesToEven 模式转换为 IEEE 754-2019 binary16 格式的结果。
  5. n64 为将 n16 转换为 IEEE 754-2019 binary64 格式的结果。
  6. 返回与 n64 对应的 ECMAScript Number 值。
Note

此操作不同于先转换为 binary32 再转换为 binary16,因为可能出现双重舍入:例如 k = 1.00048828125000022204𝔽,Math.f16round(k) 为 1.0009765625𝔽,但 Math.f16round(Math.fround(k)) 为 1𝔽

并非所有平台都提供从 binary64 转换到 binary16 的原生支持。有多种库可提供此功能,包括 MIT 许可的 half 库。或者,可以先在 roundTiesToEven 下从 binary64 转换到 binary32,然后检查结果是否可能导致错误的双重舍入。可能导致的情况可以通过调整 binary32 尾数,使其等同于在 roundTiesToOdd 下的初始转换结果来显式处理。随后在 roundTiesToEven 下将调整后的值转换为 binary16 即可得到正确值。

21.3.2.19 Math.hypot ( ...args )

给定零个或多个参数,返回各参数平方和的平方根。

被调用时执行以下步骤:

  1. coerced 为一个新的空列表。
  2. args 中每个元素 arg,执行
    1. n 为 ? ToNumber(arg)。
    2. 追加 ncoerced
  3. coerced 中每个元素 number,执行
    1. 如果 number+∞𝔽-∞𝔽,返回 +∞𝔽
  4. onlyZerotrue
  5. coerced 中每个元素 number,执行
    1. 如果 numberNaN,返回 NaN
    2. 如果 number 既不是 +0𝔽 也不是 -0𝔽,设 onlyZerofalse
  6. 如果 onlyZerotrue,返回 +0𝔽
  7. 返回一个实现近似的 Number,表示 coerced 各元素数学值平方和的平方根。

此函数的 "length" 属性值为 2𝔽

Note

实现应注意避免在具有两个或更多参数时出现朴素实现易触发的溢出与下溢导致的精度丢失。

21.3.2.20 Math.imul ( x, y )

该函数被调用时执行以下步骤:

  1. a(? ToUint32(x))。
  2. b(? ToUint32(y))。
  3. product 为 (a × b) 对 232 取模的结果。
  4. 如果 product ≥ 231,返回 𝔽(product - 232);否则返回 𝔽(product)。

21.3.2.21 Math.log ( x )

返回 x 的自然对数。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+∞𝔽,返回 n
  3. 如果 n1𝔽,返回 +0𝔽
  4. 如果 n+0𝔽-0𝔽,返回 -∞𝔽
  5. 如果 n < -0𝔽,返回 NaN
  6. 返回一个实现近似的 Number,表示 (n) 的自然对数。

21.3.2.22 Math.log1p ( x )

返回 1 + x 的自然对数;即使 x 接近 0 也要求精确。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+0𝔽、* -0*𝔽+∞𝔽 之一,返回 n
  3. 如果 n-1𝔽,返回 -∞𝔽
  4. 如果 n < -1𝔽,返回 NaN
  5. 返回一个实现近似的 Number,表示 1 + (n) 的自然对数。

21.3.2.23 Math.log10 ( x )

返回 x 的以 10 为底的对数。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+∞𝔽,返回 n
  3. 如果 n1𝔽,返回 +0𝔽
  4. 如果 n+0𝔽-0𝔽,返回 -∞𝔽
  5. 如果 n < -0𝔽,返回 NaN
  6. 返回一个实现近似的 Number,表示 (n) 的以 10 为底的对数。

21.3.2.24 Math.log2 ( x )

返回 x 的以 2 为底的对数。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+∞𝔽,返回 n
  3. 如果 n1𝔽,返回 +0𝔽
  4. 如果 n+0𝔽-0𝔽,返回 -∞𝔽
  5. 如果 n < -0𝔽,返回 NaN
  6. 返回一个实现近似的 Number,表示 (n) 的以 2 为底的对数。

21.3.2.25 Math.max ( ...args )

给定零个或多个参数,对每个参数执行 ToNumber,并返回结果值中的最大值。

被调用时执行以下步骤:

  1. coerced 为一个新的空列表。
  2. args 中每个元素 arg,执行
    1. n 为 ? ToNumber(arg)。
    2. 追加 ncoerced
  3. highest-∞𝔽
  4. coerced 中每个元素 number,执行
    1. 如果 numberNaN,返回 NaN
    2. 如果 number+0𝔽highest-0𝔽,设 highest+0𝔽
    3. 如果 number > highest,设 highestnumber
  5. 返回 highest
Note

确定最大值的比较使用 IsLessThan 算法,但 +0𝔽 被认为大于 -0𝔽

此函数的 "length" 属性值为 2𝔽

21.3.2.26 Math.min ( ...args )

给定零个或多个参数,对每个参数执行 ToNumber,并返回结果值中的最小值。

被调用时执行以下步骤:

  1. coerced 为一个新的空列表。
  2. args 中每个元素 arg,执行
    1. n 为 ? ToNumber(arg)。
    2. 追加 ncoerced
  3. lowest+∞𝔽
  4. coerced 中每个元素 number,执行
    1. 如果 numberNaN,返回 NaN
    2. 如果 number-0𝔽lowest+0𝔽,设 lowest-0𝔽
    3. 如果 number < lowest,设 lowestnumber
  5. 返回 lowest
Note

确定最大值的比较使用 IsLessThan 算法,但 +0𝔽 被认为大于 -0𝔽

此函数的 "length" 属性值为 2𝔽

21.3.2.27 Math.pow ( base, exponent )

该函数被调用时执行以下步骤:

  1. base 设为 ? ToNumber(base)。
  2. exponent 设为 ? ToNumber(exponent)。
  3. 返回 Number::exponentiate(base, exponent)。

21.3.2.28 Math.random ( )

返回一个具有正号的 Number,值 ≥ +0𝔽 且 < 1𝔽,在该范围内以近似均匀分布随机或伪随机选择,使用实现定义的算法或策略。

为不同 realm 创建的每个 Math.random 函数必须产生与其它 realm 不同的值序列。

21.3.2.29 Math.round ( x )

返回最接近 x 的整数 Number 值;若有两个整数同样接近 x,结果为更靠近 +∞ 的那个。若 x 已是整数,则结果为 x

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 n有限n 是整数 Number,返回 n
  3. 如果 n < 0.5𝔽n > +0𝔽,返回 +0𝔽
  4. 如果 n < -0𝔽n-0.5𝔽,返回 -0𝔽
  5. 返回最接近 n 的整数 Number;若存在平局,取更靠近 +∞ 的那个。
Note 1

Math.round(3.5) 返回 4,而 Math.round(-3.5) 返回 -3。

Note 2

Math.round(x) 的值不总是等于 Math.floor(x + 0.5)。当 x-0𝔽x < -0𝔽 且 ≥ -0.5𝔽 时,Math.round(x) 返回 -0𝔽,但 Math.floor(x + 0.5) 返回 +0𝔽。计算 x + 0.5 时的内部舍入也可能使结果不同。

21.3.2.30 Math.sign ( x )

返回 x 的符号,指示 x 是正、负或零。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+0𝔽-0𝔽 之一,返回 n
  3. 如果 n < -0𝔽,返回 -1𝔽
  4. 返回 1𝔽

21.3.2.31 Math.sin ( x )

返回 x 的正弦。参数用弧度表示。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+0𝔽-0𝔽 之一,返回 n
  3. 如果 n+∞𝔽-∞𝔽,返回 NaN
  4. 返回一个实现近似的 Number,表示 (n) 的正弦。

21.3.2.32 Math.sinh ( x )

返回 x 的双曲正弦。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 n有限n+0𝔽-0𝔽,返回 n
  3. 返回一个实现近似的 Number,表示 (n) 的双曲正弦。
Note

Math.sinh(x) 的值等于 (Math.exp(x) - Math.exp(-x)) / 2

21.3.2.33 Math.sqrt ( x )

返回 x 的平方根。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+0𝔽、* -0*𝔽+∞𝔽 之一,返回 n
  3. 如果 n < -0𝔽,返回 NaN
  4. 返回 𝔽((n) 的平方根)。

21.3.2.34 Math.sumPrecise ( items )

给定一个由 Number 组成的可迭代对象,对其中每个值求和并返回和。如果任一值不是 Number 则抛出 TypeError 异常。

被调用时执行以下步骤:

  1. 执行 ? RequireObjectCoercible(items)。
  2. iteratorRecord 为 ? GetIterator(items, sync)。
  3. stateminus-zero
  4. sum 为 0。
  5. count 为 0。
  6. nextnot-started
  7. next 不为 done 时重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 next 不为 done,则
      1. 如果 count ≥ 253 - 1,则
        1. 注:理论上不期望到达此步骤,仅用于允许实现依赖“合理大小”的输入而不违背规范。
        2. errorThrowCompletion(一个新建的 RangeError 对象)。
        3. 返回 ? IteratorClose(iteratorRecord, error)。
      2. 如果 next 不是 Number,则
        1. errorThrowCompletion(一个新建的 TypeError 对象)。
        2. 返回 ? IteratorClose(iteratorRecord, error)。
      3. nnext
      4. 如果 state 不为 not-a-number,则
        1. 如果 nNaN,则
          1. statenot-a-number
        2. 否则如果 n+∞𝔽,则
          1. 如果 stateminus-infinity,设 statenot-a-number
          2. 否则设 stateplus-infinity
        3. 否则如果 n-∞𝔽,则
          1. 如果 stateplus-infinity,设 statenot-a-number
          2. 否则设 stateminus-infinity
        4. 否则如果 n 不是 -0𝔽stateminus-zerofinite,则
          1. statefinite
          2. sumsum + (n)。
      5. countcount + 1。
  8. 如果 statenot-a-number,返回 NaN
  9. 如果 stateplus-infinity,返回 +∞𝔽
  10. 如果 stateminus-infinity,返回 -∞𝔽
  11. 如果 stateminus-zero,返回 -0𝔽
  12. 返回 𝔽(sum)。
Note

sum 的值可通过多种算法在无需任意精度算术的情况下计算。其中之一是 Jonathan Richard Shewchuk 在《Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates》中给出的 “Grow-Expansion” 算法。一个更新的算法见 “Fast exact summation using small and large superaccumulators”,其代码位于 https://gitlab.com/radfordneal/xsum

21.3.2.35 Math.tan ( x )

返回 x 的正切。参数用弧度表示。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+0𝔽-0𝔽 之一,返回 n
  3. 如果 n+∞𝔽-∞𝔽,返回 NaN
  4. 返回一个实现近似的 Number,表示 (n) 的正切。

21.3.2.36 Math.tanh ( x )

返回 x 的双曲正切。

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 nNaN+0𝔽-0𝔽 之一,返回 n
  3. 如果 n+∞𝔽,返回 1𝔽
  4. 如果 n-∞𝔽,返回 -1𝔽
  5. 返回一个实现近似的 Number,表示 (n) 的双曲正切。
Note

Math.tanh(x) 的值等于 (Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x))

21.3.2.37 Math.trunc ( x )

返回数字 x 的整数部分,去除任何小数部分。若 x 已是整数,结果为 x

被调用时执行以下步骤:

  1. n 为 ? ToNumber(x)。
  2. 如果 n有限n+0𝔽-0𝔽,返回 n
  3. 如果 n < 1𝔽n > +0𝔽,返回 +0𝔽
  4. 如果 n < -0𝔽n > -1𝔽,返回 -0𝔽
  5. 返回朝向 +0𝔽 方向最接近 n 的整数 Number。

21.4 Date 对象

21.4.1 Date 对象概述及抽象操作定义

以下抽象操作作用于时间值(定义见 21.4.1.1)。注意,在所有情况下,如果这些函数的任何参数为 NaN,则结果为 NaN

21.4.1.1 时间值与时间范围

ECMAScript 的时间度量与 POSIX 的时间度量类似,特别是在使用前推的公历、以 1970 年 1 月 1 日 UTC 零点为 纪元,以及每一天精确包含 86,400 秒(每秒为 1000 毫秒)的定义上。

ECMAScript 的 时间值 是一个 Number,要么是表示某一时刻的有限整数 Number(精确到毫秒),要么是 NaN 表示没有具体时刻。一个是 24 × 60 × 60 × 1000 = 86,400,000 的倍数(即对于某个整数 d,为 86,400,000 × d)的时间值,表示自纪元起经过 d 个完整 UTC 日的 UTC 日起始时刻(负 d 表示纪元之前)。其他有限时间值 t 则以紧邻其之前最大倍数的时间值 s 为基准,表示与 s 同一天内,距离 s 之后 (t - s) 毫秒的时刻。

时间值不考虑 UTC 闰秒——没有表示正闰秒内时刻的时间值,也有表示因负闰秒从 UTC 时间线移除的时刻的时间值。但时间值的定义仍然与 UTC 分段对齐,只有在闰秒边界处有不连续,非闰秒时为零差异。

Number 能精确表示从 -9,007,199,254,740,992 到 9,007,199,254,740,992 的所有整数(见 21.1.2.821.1.2.6)。而时间值支持稍小的范围 -8,640,000,000,000,000 到 8,640,000,000,000,000 毫秒。这对应于自 1970 年 1 月 1 日 UTC 零点起精确的 -100,000,000 天到 100,000,000 天的时间值范围。

1970 年 1 月 1 日 UTC 零点的精确时刻由时间值 +0𝔽 表示。

Note

在前推的公历中,闰年是能被 4 整除且(能被 400 整除或不能被 100 整除)的年份。

前推的公历 400 年周期包含 97 个闰年,平均每年为 365.2425 天,即 31,556,952,000 毫秒。因此用毫秒精度 Number 可精确表示的最大范围约为距 1970 年前后 -285,426 到 285,426 年。按本节时间值的更小支持范围约为距 1970 年前后 -273,790 到 273,790 年。

21.4.1.2 时间相关常量

这些常量会被后续章节中的算法引用。

HoursPerDay = 24
MinutesPerHour = 60
SecondsPerMinute = 60
msPerSecond = 1000𝔽
msPerMinute = 60000𝔽 = msPerSecond × 𝔽(SecondsPerMinute)
msPerHour = 3600000𝔽 = msPerMinute × 𝔽(MinutesPerHour)
msPerDay = 86400000𝔽 = msPerHour × 𝔽(HoursPerDay)

21.4.1.3 Day ( t )

The abstract operation Day takes argument t (有限时间值) and returns 整数 Number. It performs the following steps when called:

  1. 返回 𝔽(floor((t / msPerDay)))。

21.4.1.4 TimeWithinDay ( t )

The abstract operation TimeWithinDay takes argument t (有限时间值) and returns 区间 +0𝔽(含)至 msPerDay(不含)内的整数 Number. It performs the following steps when called:

  1. 返回 𝔽((t) 模 (msPerDay))。

21.4.1.5 DaysInYear ( y )

The abstract operation DaysInYear takes argument y (整数 Number) and returns 365𝔽366𝔽. It performs the following steps when called:

  1. ry(y)。
  2. 若 (ry 模 400) = 0,返回 366𝔽
  3. 若 (ry 模 100) = 0,返回 365𝔽
  4. 若 (ry 模 4) = 0,返回 366𝔽
  5. 返回 365𝔽

21.4.1.6 DayFromYear ( y )

The abstract operation DayFromYear takes argument y (整数 Number) and returns 整数 Number. It performs the following steps when called:

  1. ry(y)。
  2. 注:下列步骤中,numYears1numYears4numYears100numYears400 表示自纪元y 年首之间能被 1、4、100、400 整除的年份数。若 y纪元之前则为负数。
  3. numYears1 为 (ry - 1970)。
  4. numYears4floor((ry - 1969) / 4)。
  5. numYears100floor((ry - 1901) / 100)。
  6. numYears400floor((ry - 1601) / 400)。
  7. 返回 𝔽(365 × numYears1 + numYears4 - numYears100 + numYears400)。

21.4.1.7 TimeFromYear ( y )

The abstract operation TimeFromYear takes argument y (整数 Number) and returns 时间值. It performs the following steps when called:

  1. 返回 msPerDay × DayFromYear(y)。

21.4.1.8 YearFromTime ( t )

The abstract operation YearFromTime takes argument t (有限时间值) and returns 整数 Number. It performs the following steps when called:

  1. 返回满足 TimeFromYear(y) ≤ t 的最大整数 Number y(最接近 +∞)。

21.4.1.9 DayWithinYear ( t )

The abstract operation DayWithinYear takes argument t (有限时间值) and returns 区间 +0𝔽365𝔽(含)的整数 Number. It performs the following steps when called:

  1. 返回 Day(t) - DayFromYear(YearFromTime(t))。

21.4.1.10 InLeapYear ( t )

The abstract operation InLeapYear takes argument t (有限时间值) and returns +0𝔽1𝔽. It performs the following steps when called:

  1. DaysInYear(YearFromTime(t)) 为 366𝔽,则返回 1𝔽;否则返回 +0𝔽

21.4.1.11 MonthFromTime ( t )

The abstract operation MonthFromTime takes argument t (有限时间值) and returns 区间 +0𝔽11𝔽(含)的整数 Number. It performs the following steps when called:

  1. inLeapYearInLeapYear(t)。
  2. dayWithinYearDayWithinYear(t)。
  3. dayWithinYear < 31𝔽,返回 +0𝔽
  4. dayWithinYear < 59𝔽 + inLeapYear,返回 1𝔽
  5. dayWithinYear < 90𝔽 + inLeapYear,返回 2𝔽
  6. dayWithinYear < 120𝔽 + inLeapYear,返回 3𝔽
  7. dayWithinYear < 151𝔽 + inLeapYear,返回 4𝔽
  8. dayWithinYear < 181𝔽 + inLeapYear,返回 5𝔽
  9. dayWithinYear < 212𝔽 + inLeapYear,返回 6𝔽
  10. dayWithinYear < 243𝔽 + inLeapYear,返回 7𝔽
  11. dayWithinYear < 273𝔽 + inLeapYear,返回 8𝔽
  12. dayWithinYear < 304𝔽 + inLeapYear,返回 9𝔽
  13. dayWithinYear < 334𝔽 + inLeapYear,返回 10𝔽
  14. 断言:dayWithinYear < 365𝔽 + inLeapYear
  15. 返回 11𝔽

21.4.1.12 DateFromTime ( t )

The abstract operation DateFromTime takes argument t (有限时间值) and returns 区间 1𝔽31𝔽(含)的整数 Number. It performs the following steps when called:

  1. inLeapYearInLeapYear(t)。
  2. dayWithinYearDayWithinYear(t)。
  3. monthMonthFromTime(t)。
  4. month+0𝔽,返回 dayWithinYear + 1𝔽
  5. month1𝔽,返回 dayWithinYear - 30𝔽
  6. month2𝔽,返回 dayWithinYear - 58𝔽 - inLeapYear
  7. month3𝔽,返回 dayWithinYear - 89𝔽 - inLeapYear
  8. month4𝔽,返回 dayWithinYear - 119𝔽 - inLeapYear
  9. month5𝔽,返回 dayWithinYear - 150𝔽 - inLeapYear
  10. month6𝔽,返回 dayWithinYear - 180𝔽 - inLeapYear
  11. month7𝔽,返回 dayWithinYear - 211𝔽 - inLeapYear
  12. month8𝔽,返回 dayWithinYear - 242𝔽 - inLeapYear
  13. month9𝔽,返回 dayWithinYear - 272𝔽 - inLeapYear
  14. month10𝔽,返回 dayWithinYear - 303𝔽 - inLeapYear
  15. 断言:month11𝔽
  16. 返回 dayWithinYear - 333𝔽 - inLeapYear

21.4.1.13 WeekDay ( t )

The abstract operation WeekDay takes argument t (有限时间值) and returns 区间 +0𝔽6𝔽(含)的整数 Number. It performs the following steps when called:

  1. 返回 𝔽((Day(t) + 4𝔽) 模 7)。

21.4.1.14 HourFromTime ( t )

The abstract operation HourFromTime takes argument t (有限时间值) and returns 区间 +0𝔽23𝔽(含)的整数 Number. It performs the following steps when called:

  1. 返回 𝔽(floor((t / msPerHour)) 模 HoursPerDay)。

21.4.1.15 MinFromTime ( t )

The abstract operation MinFromTime takes argument t (有限时间值) and returns 区间 +0𝔽59𝔽(含)的整数 Number. It performs the following steps when called:

  1. 返回 𝔽(floor((t / msPerMinute)) 模 MinutesPerHour)。

21.4.1.16 SecFromTime ( t )

The abstract operation SecFromTime takes argument t (有限时间值) and returns 区间 +0𝔽59𝔽(含)的整数 Number. It performs the following steps when called:

  1. 返回 𝔽(floor((t / msPerSecond)) 模 SecondsPerMinute)。

21.4.1.17 msFromTime ( t )

The abstract operation msFromTime takes argument t (有限时间值) and returns 区间 +0𝔽999𝔽(含)的整数 Number. It performs the following steps when called:

  1. 返回 𝔽((t) 模 (msPerSecond))。

21.4.1.18 GetUTCEpochNanoseconds ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond )

The abstract operation GetUTCEpochNanoseconds takes arguments year (整数), month (区间 1 到 12 内的整数), day (区间 1 到 31 内的整数), hour (区间 0 到 23 内的整数), minute (区间 0 到 59 内的整数), second (区间 0 到 59 内的整数), millisecond (区间 0 到 999 内的整数), microsecond (区间 0 到 999 内的整数), and nanosecond (区间 0 到 999 内的整数) and returns BigInt. It performs the following steps when called:

  1. dateMakeDay(𝔽(year), 𝔽(month - 1), 𝔽(day))。
  2. timeMakeTime(𝔽(hour), 𝔽(minute), 𝔽(second), 𝔽(millisecond))。
  3. msMakeDate(date, time)。
  4. 断言:ms 是整数 Number。
  5. 返回 ((ms) × 106 + microsecond × 103 + nanosecond)。

21.4.1.19 时区标识符

ECMAScript 中的时区由 时区标识符 表示,是完全由码元在 0x0000 到 0x007F 区间组成的字符串。 ECMAScript 支持的时区可以是 可用命名时区,其由 AvailableNamedTimeZoneIdentifiers 返回的时区标识符记录[[Identifier]] 字段表示,或是 偏移时区,其由 IsTimeZoneOffsetString 返回 true 的字符串表示。

主时区标识符是可用命名时区的首选标识符。 非主时区标识符是可用命名时区的非主标识符。 可用命名时区标识符是主时区标识符或非主时区标识符中的一种。 每个可用命名时区标识符只关联一个可用命名时区。 每个可用命名时区只关联一个主时区标识符和零个或多个非主时区标识符。

ECMAScript 实现必须支持标识符为 "UTC" 的可用命名时区,并且该标识符必须是 UTC 时区的主时区标识符。 此外,实现可以支持任意数量的其他可用命名时区。

遵循 ECMA-402 国际化 API 规范描述的时区要求的实现称为 具备时区感知。 具备时区感知的实现必须支持与 IANA 时区数据库的 Zone 和 Link 名称相对应的可用命名时区,并且仅支持这些名称。 在具备时区感知的实现中,主时区标识符是 Zone 名称,非主时区标识符是 Link 名称(除非被 ECMA-402 规范中的 AvailableNamedTimeZoneIdentifiers 特别覆盖)。 不支持完整 IANA 时区数据库的实现仍建议使用 IANA 时区数据库名称作为时区标识符。

21.4.1.20 GetNamedTimeZoneEpochNanoseconds ( timeZoneIdentifier, year, month, day, hour, minute, second, millisecond, microsecond, nanosecond )

The implementation-defined abstract operation GetNamedTimeZoneEpochNanoseconds takes arguments timeZoneIdentifier (字符串), year (整数), month (区间 1 到 12 内的整数), day (区间 1 到 31 内的整数), hour (区间 0 到 23 内的整数), minute (区间 0 到 59 内的整数), second (区间 0 到 59 内的整数), millisecond (区间 0 到 999 内的整数), microsecond (区间 0 到 999 内的整数), and nanosecond (区间 0 到 999 内的整数) and returns BigInt 列表.

当输入表示由于负时区变更(如夏令时结束或时区规则调整导致偏移减少)而某本地时间出现多次时,返回的列表会有多个元素,并按数值升序排序。 当输入表示由于正时区变更(如夏令时开始或时区规则调整导致偏移增加)而某本地时间被跳过时,返回的列表为空。 否则返回的列表只有一个元素。

未包含任何时区本地规则的 ECMAScript 实现的默认实现步骤如下:

  1. 断言:timeZoneIdentifier"UTC"
  2. epochNanosecondsGetUTCEpochNanoseconds(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond)。
  3. 返回 « epochNanoseconds »。
Note

时区感知实现(也推荐所有实现)需使用 IANA 时区数据库 https://www.iana.org/time-zones/ 的时区信息。

2017 年 11 月 5 日 1:30 AM 在 America/New_York 出现两次,因此 GetNamedTimeZoneEpochNanoseconds("America/New_York", 2017, 11, 5, 1, 30, 0, 0, 0, 0) 会返回一个长度为 2 的列表,第一项表示 05:30 UTC(对应美国东部夏令时 UTC-04:00),第二项表示 06:30 UTC(对应美国东部标准时 UTC-05:00)。

2017 年 3 月 12 日 2:30 AM 在 America/New_York 不存在,因此 GetNamedTimeZoneEpochNanoseconds("America/New_York", 2017, 3, 12, 2, 30, 0, 0, 0, 0) 会返回空列表。

21.4.1.21 GetNamedTimeZoneOffsetNanoseconds ( timeZoneIdentifier, epochNanoseconds )

The implementation-defined abstract operation GetNamedTimeZoneOffsetNanoseconds takes arguments timeZoneIdentifier (字符串) and epochNanoseconds (BigInt) and returns 整数.

返回的整数表示由 timeZoneIdentifier 标识的命名时区,在与 epochNanoseconds 相对应的时刻相对纪元的 UTC 偏移(单位为纳秒)。

未包含任何时区本地规则的 ECMAScript 实现的默认实现步骤如下:

  1. 断言:timeZoneIdentifier"UTC"
  2. 返回 0。
Note

时区偏移值可能为正或负。

21.4.1.22 时区标识符记录

时区标识符记录是用于描述可用命名时区标识符及其对应主时区标识符的记录。

时区标识符记录具有 Table 62 中列出的字段。

Table 62: 时区标识符记录字段
字段名 含义
[[Identifier]] 字符串 实现支持的可用命名时区标识符
[[PrimaryIdentifier]] 字符串 [[Identifier]] 解析到的主时区标识符
Note

[[Identifier]]主时区标识符,则 [[Identifier]][[PrimaryIdentifier]]

21.4.1.23 AvailableNamedTimeZoneIdentifiers ( )

The implementation-defined abstract operation AvailableNamedTimeZoneIdentifiers takes no arguments and returns 时区标识符记录列表.

具备时区感知的实现(包括所有实现 ECMA-402 国际化 API 的实现)必须按 ECMA-402 规范实现 AvailableNamedTimeZoneIdentifiers 抽象操作。 对于不具备时区感知的实现,AvailableNamedTimeZoneIdentifiers 的默认步骤如下:

  1. 如果实现未包含任何时区本地规则,
    1. 返回 « 时区标识符记录 { [[Identifier]]: "UTC", [[PrimaryIdentifier]]: "UTC" } »。
  2. identifiers 为唯一可用命名时区标识符列表,按字典码元顺序排序。
  3. result 为新空列表。
  4. 对每个 identifier 元素,
    1. primaryidentifier
    2. 如果 identifier 是此实现的非主时区标识符且不是 "UTC"
      1. primary 设为与 identifier 关联的主时区标识符
      2. 注:实现可能需迭代解析 identifier 以获得主时区标识符
    3. record时区标识符记录 { [[Identifier]]: identifier, [[PrimaryIdentifier]]: primary }。
    4. record 添加到 result
  5. 断言:result 包含时区标识符记录 r,使得 r.[[Identifier]]"UTC"r.[[PrimaryIdentifier]]"UTC"
  6. 返回 result

21.4.1.24 SystemTimeZoneIdentifier ( )

The implementation-defined abstract operation SystemTimeZoneIdentifier takes no arguments and returns 字符串. It performs the following steps when called:

  1. 如果实现仅支持 UTC 时区,返回 "UTC"
  2. systemTimeZoneString 为代表宿主环境当前时区的字符串(主时区标识符偏移时区标识符)。
  3. 返回 systemTimeZoneString
Note

为确保实现常见 Date 对象方法的功能,建议 SystemTimeZoneIdentifier 返回宿主环境时区设置对应的 IANA 时区名(如存在)。 GetNamedTimeZoneEpochNanosecondsGetNamedTimeZoneOffsetNanoseconds 必须反映该时区标准时间和夏令时的本地政治规则(如有)。

例如,若宿主环境为设置为美国东部时间的浏览器,则 SystemTimeZoneIdentifier 返回 "America/New_York"

21.4.1.25 LocalTime ( t )

The abstract operation LocalTime takes argument t (有限时间值) and returns 整数 Number. It performs the following steps when called:

  1. systemTimeZoneIdentifierSystemTimeZoneIdentifier()。
  2. 如果 IsTimeZoneOffsetString(systemTimeZoneIdentifier) 为 true
    1. offsetNsParseTimeZoneOffsetString(systemTimeZoneIdentifier)。
  3. 否则,
    1. offsetNsGetNamedTimeZoneOffsetNanoseconds(systemTimeZoneIdentifier, ((t) × 106))。
  4. offsetMstruncate(offsetNs / 106)。
  5. 返回 t + 𝔽(offsetMs)。
Note 1

若实现无法获得本地时间 t 的政治规则,则结果为 t,因为 SystemTimeZoneIdentifier 返回 "UTC"GetNamedTimeZoneOffsetNanoseconds 返回 0。

Note 2

时区感知实现(也推荐所有实现)需使用 IANA 时区数据库 https://www.iana.org/time-zones/ 的时区信息。

Note 3

在负时区变更(如夏令时结束或时区调整减小时)发生重复时间时,两个不同输入时间值 tUTC 会被转换为同一本地时间 tlocalLocalTime(UTC(tlocal)) 不一定等于 tlocal,同理 UTC(LocalTime(tUTC)) 也不一定等于 tUTC

21.4.1.26 UTC ( t )

The abstract operation UTC takes argument t (Number) and returns 时间值. It performs the following steps when called:

  1. t有限,返回 NaN
  2. systemTimeZoneIdentifierSystemTimeZoneIdentifier()。
  3. 如果 IsTimeZoneOffsetString(systemTimeZoneIdentifier) 为 true
    1. offsetNsParseTimeZoneOffsetString(systemTimeZoneIdentifier)。
  4. 否则,
    1. possibleInstantsGetNamedTimeZoneEpochNanoseconds(systemTimeZoneIdentifier, (YearFromTime(t)), (MonthFromTime(t)) + 1, (DateFromTime(t)), (HourFromTime(t)), (MinFromTime(t)), (SecFromTime(t)), (msFromTime(t)), 0, 0)。
    2. 注:下列步骤确保 t 表示在负时区变更(如夏令时结束或时区调整减小时)中重复出现的本地时间或在正时区变更(如夏令时开始或时区调整增大时)中被跳过的本地时间时,t 按变更前的时区偏移解读。
    3. possibleInstants 非空,
      1. disambiguatedInstantpossibleInstants[0]。
    4. 否则,
      1. 注:t 表示在正时区变更时被跳过的本地时间(如夏令时开始或时区调整增大)。
      2. possibleInstantsBeforeGetNamedTimeZoneEpochNanoseconds(systemTimeZoneIdentifier, (YearFromTime(tBefore)), (MonthFromTime(tBefore)) + 1, (DateFromTime(tBefore)), (HourFromTime(tBefore)), (MinFromTime(tBefore)), (SecFromTime(tBefore)), (msFromTime(tBefore)), 0, 0),其中 tBefore 为小于 t 的最大整数 Number,且 possibleInstantsBefore 非空(即 tBefore 为变更前的最后本地时间)。
      3. disambiguatedInstantpossibleInstantsBefore 的最后一项。
    5. offsetNsGetNamedTimeZoneOffsetNanoseconds(systemTimeZoneIdentifier, disambiguatedInstant)。
  5. offsetMstruncate(offsetNs / 106)。
  6. 返回 t - 𝔽(offsetMs)。

输入 t 名义上为时间值,但可为任意 Number。 算法不得限制 t时间值范围,使得无论本地 UTC 偏移如何,都可支持对应时间值范围边界的输入。 例如,最大时间值为 8.64 × 1015,对应 "+275760-09-13T00:00:00Z"。 若本地时区偏移在该时刻为 UTC+1 小时,则对应更大的输入 8.64 × 1015 + 3.6 × 106,即 "+275760-09-13T01:00:00+01:00"

若实现无法获得本地时间 t 的政治规则,则结果为 t,因为 SystemTimeZoneIdentifier 返回 "UTC"GetNamedTimeZoneOffsetNanoseconds 返回 0。

Note 1

时区感知实现(也推荐所有实现)需使用 IANA 时区数据库 https://www.iana.org/time-zones/ 的时区信息。

2017 年 11 月 5 日 1:30 AM 在 America/New_York 出现两次(回拨),但应按 UTC-04 而不是 UTC-05 解释。 在 UTC(TimeClip(MakeDate(MakeDay(2017, 10, 5), MakeTime(1, 30, 0, 0)))) 中,offsetMs 的值为 -4 × msPerHour

2017 年 3 月 12 日 2:30 AM 在 America/New_York 不存在,但应按 UTC-05(等价于 UTC-04 的 3:30 AM)解释。 在 UTC(TimeClip(MakeDate(MakeDay(2017, 2, 12), MakeTime(2, 30, 0, 0)))) 中,offsetMs 的值为 -5 × msPerHour

Note 2

UTC(LocalTime(tUTC)) 不一定等于 tUTC,同理 LocalTime(UTC(tlocal)) 也不一定等于 tlocal

21.4.1.27 MakeTime ( hour, min, sec, ms )

The abstract operation MakeTime takes arguments hour (Number), min (Number), sec (Number), and ms (Number) and returns Number. It performs the following steps when called:

  1. hourminsecms 任一非有限,返回 NaN
  2. h𝔽(! ToIntegerOrInfinity(hour))。
  3. m𝔽(! ToIntegerOrInfinity(min))。
  4. s𝔽(! ToIntegerOrInfinity(sec))。
  5. milli𝔽(! ToIntegerOrInfinity(ms))。
  6. 返回 ((h × msPerHour + m × msPerMinute) + s × msPerSecond) + milli
Note

MakeTime 的算术为浮点运算,非结合律,须按正确顺序执行。

21.4.1.28 MakeDay ( year, month, date )

The abstract operation MakeDay takes arguments year (Number), month (Number), and date (Number) and returns Number. It performs the following steps when called:

  1. yearmonthdate 任一非有限,返回 NaN
  2. y𝔽(! ToIntegerOrInfinity(year))。
  3. m𝔽(! ToIntegerOrInfinity(month))。
  4. dt𝔽(! ToIntegerOrInfinity(date))。
  5. ymy + 𝔽(floor((m) / 12))。
  6. ym有限,返回 NaN
  7. mn𝔽((m) 模 12)。
  8. 找到 YearFromTime(t) 为 ymMonthFromTime(t) 为 mnDateFromTime(t) 为 1𝔽有限时间值 t;若不可行(如参数越界),返回 NaN
  9. 返回 Day(t) + dt - 1𝔽

21.4.1.29 MakeDate ( day, time )

The abstract operation MakeDate takes arguments day (Number) and time (Number) and returns Number. It performs the following steps when called:

  1. daytime有限,返回 NaN
  2. tvday × msPerDay + time
  3. tv有限,返回 NaN
  4. 返回 tv

21.4.1.30 MakeFullYear ( year )

The abstract operation MakeFullYear takes argument year (Number) and returns 整数 Number 或 NaN. It performs the following steps when called:

  1. yearNaN,返回 NaN
  2. truncated 为 ! ToIntegerOrInfinity(year)。
  3. truncated 在 0 到 99 区间,返回 1900𝔽 + 𝔽(truncated)。
  4. 返回 𝔽(truncated)。

21.4.1.31 TimeClip ( time )

The abstract operation TimeClip takes argument time (Number) and returns Number. It performs the following steps when called:

  1. time有限,返回 NaN
  2. abs((time)) > 8.64 × 1015,返回 NaN
  3. 返回 𝔽(! ToIntegerOrInfinity(time))。

21.4.1.32 日期时间字符串格式

ECMAScript 定义了一种基于 ISO 8601 日历日期扩展格式的日期时间字符串交换格式。格式如下:YYYY-MM-DDTHH:mm:ss.sssZ

各元素说明如下:

YYYY 公历年份,四位十进制数字,范围 0000 到 9999,或 扩展年份,即 "+""-" 加六位数字。
- "-"(连字符)在字符串中出现两次。
MM 月份,两位十进制数字,01(1月)到 12(12月)。
DD 日期,两位十进制数字,01 到 31。
T "T" 字面出现,表示时间部分开始。
HH 自零点起经过的完整小时数,两位十进制数字,00 到 24。
: ":"(冒号)在字符串中出现两次。
mm 小时开始起经过的完整分钟数,两位十进制数字,00 到 59。
ss 分钟开始起经过的完整秒数,两位十进制数字,00 到 59。
. "."(点)字面出现。
sss 秒开始起经过的完整毫秒数,三位十进制数字。
Z UTC 偏移表示,"Z"(无偏移的 UTC),或 "+""-" 加时间表达式 HH:mm(用于表示本地时间领先或落后 UTC,属于 时区偏移字符串格式 的子集)。

该格式还包括仅日期形式:

YYYY
YYYY-MM
YYYY-MM-DD
        

也包括“日期-时间”形式,即上述日期形式紧接以下时间形式之一并可选加偏移:

THH:mm
THH:mm:ss
THH:mm:ss.sss
        

包含越界或不符合规范元素的字符串不是本格式的有效实例。

Note 1

由于每一天既有开始也有结束的零点,00:0024:00 两种记法都可用于区分同一天的两个零点。比如 1995-02-04T24:001995-02-05T00:00 表示同一时刻。这种将后者解释为“日终”与 ISO 8601 一致,尽管该规范仅用于时间区间,不用于单一时刻。

Note 2

国际上不存在民用时区缩写(如 CET、EST 等)的标准,有时同一缩写可表示不同时区。因此,ISO 8601 及本格式均采用数字型偏移表示时区。

21.4.1.32.1 扩展年份

覆盖约 273,790 年前后(自 1970 年 1 月 1 日起,见 21.4.1.1)的完整时间值范围需表示 0 年之前或 9999 年之后的年份。ISO 8601 允许年份扩展,但仅限信息交换双方协商采用。简化的 ECMAScript 格式规定扩展年份为 6 位数字,前缀为 + 或 -。年份 0 视为正数,必须加 + 前缀。-000000 形式无效。超出时间值范围的扩展年份字符串被 Date.parse 视为不可识别,返回 NaN,不会退回实现特定行为或启发式处理。

Note

扩展年份示例:

-271821-04-20T00:00:00Z 公元前 271822 年
-000001-01-01T00:00:00Z 公元前 2 年
+000000-01-01T00:00:00Z 公元前 1 年
+000001-01-01T00:00:00Z 公元 1 年
+001970-01-01T00:00:00Z 公元 1970 年
+002009-12-15T00:00:00Z 公元 2009 年
+275760-09-13T00:00:00Z 公元 275760 年

21.4.1.33 时区偏移字符串格式

ECMAScript 定义了用于 UTC 偏移的字符串交换格式,源自 ISO 8601。 格式描述如下语法。

语法

UTCOffset ::: ASCIISign Hour ASCIISign Hour HourSubcomponents[+Extended] ASCIISign Hour HourSubcomponents[~Extended] ASCIISign ::: one of + - Hour ::: 0 DecimalDigit 1 DecimalDigit 20 21 22 23 HourSubcomponents[Extended] ::: TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TemporalDecimalFractionopt TimeSeparator[Extended] ::: [+Extended] : [~Extended] [empty] MinuteSecond ::: 0 DecimalDigit 1 DecimalDigit 2 DecimalDigit 3 DecimalDigit 4 DecimalDigit 5 DecimalDigit TemporalDecimalFraction ::: TemporalDecimalSeparator DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator ::: one of . ,

21.4.1.33.1 IsTimeZoneOffsetString ( offsetString )

The abstract operation IsTimeZoneOffsetString takes argument offsetString (字符串) and returns 布尔值. It performs the following steps when called:

  1. parseResult 为 ParseText(offsetString, UTCOffset)。
  2. parseResult 为错误列表,返回 false
  3. 返回 true

21.4.1.33.2 ParseTimeZoneOffsetString ( offsetString )

The abstract operation ParseTimeZoneOffsetString takes argument offsetString (字符串) and returns 整数. It performs the following steps when called:

  1. parseResult 为 ParseText(offsetString, UTCOffset)。
  2. 断言:parseResult 非错误列表。
  3. 断言:parseResult 包含 ASCIISign 解析节点
  4. parsedSignparseResultASCIISign 解析节点匹配的源文本。
  5. parsedSign 为 U+002D(连字符),
    1. sign 为 -1。
  6. 否则,
    1. sign 为 1。
  7. 注:下列 StringToNumber 应用不会丢精度,因为每个解析值均为短数字字符串。
  8. 断言:parseResult 包含 Hour 解析节点
  9. parsedHoursparseResultHour 解析节点匹配的源文本。
  10. hours(StringToNumber(CodePointsToString(parsedHours)))。
  11. parseResult 不含 MinuteSecond 解析节点
    1. minutes 为 0。
  12. 否则,
    1. parsedMinutesparseResult 内第一个 MinuteSecond 解析节点匹配的源文本。
    2. minutes(StringToNumber(CodePointsToString(parsedMinutes)))。
  13. parseResult 不含两个 MinuteSecond 解析节点
    1. seconds 为 0。
  14. 否则,
    1. parsedSecondsparseResult 内第二个 MinuteSecond 解析节点匹配的源文本。
    2. seconds(StringToNumber(CodePointsToString(parsedSeconds)))。
  15. parseResult 不含 TemporalDecimalFraction 解析节点
    1. nanoseconds 为 0。
  16. 否则,
    1. parsedFractionparseResultTemporalDecimalFraction 解析节点匹配的源文本。
    2. fraction 为 CodePointsToString(parsedFraction) 与 "000000000" 的字符串拼接。
    3. nanosecondsStringfraction 的第 1 到第 10 位子串。
    4. nanoseconds(StringToNumber(nanosecondsString))。
  17. 返回 sign × (((hours × 60 + minutes) × 60 + seconds) × 109 + nanoseconds)。

21.4.2 Date 构造函数

Date 构造函数

  • %Date%
  • 是全局对象的 "Date" 属性的初始值。
  • 作为构造函数调用时,会创建并初始化一个新的 Date。
  • 作为函数而不是构造函数调用时,返回一个表示当前时间(UTC)的字符串。
  • 是一个行为根据参数数量和类型不同而不同的函数。
  • 可用作类定义的 extends 子句的值。打算继承指定 Date 行为的子类构造函数必须包含对 Date 构造函数super 调用,以创建并用 [[DateValue]] 内部槽初始化子类实例。

21.4.2.1 Date ( ...values )

当调用此函数时,执行以下步骤:

  1. 如果 NewTarget 是 undefined
    1. now 为标识当前时间的时间值(UTC)。
    2. 返回 ToDateString(now)。
  2. numberOfArgsvalues 中元素的数量。
  3. 如果 numberOfArgs = 0,
    1. dv 为标识当前时间的时间值(UTC)。
  4. 否则如果 numberOfArgs = 1,
    1. valuevalues[0]。
    2. 如果 value 是对象且有 [[DateValue]] 内部槽,
      1. tvvalue.[[DateValue]]
    3. 否则,
      1. v 为 ? ToPrimitive(value)。
      2. 如果 v 是字符串,
        1. 断言:下一步不会出现突然完成,因为 v 是字符串。
        2. tv 为按与 parse 方法完全相同的方式解析 v 作为日期的结果(21.4.3.2)。
      3. 否则,
        1. tv 为 ? ToNumber(v)。
    4. dvTimeClip(tv)。
  5. 否则,
    1. 断言:numberOfArgs ≥ 2。
    2. y 为 ? ToNumber(values[0])。
    3. m 为 ? ToNumber(values[1])。
    4. 如果 numberOfArgs > 2,令 dt 为 ? ToNumber(values[2]);否则令 dt1𝔽
    5. 如果 numberOfArgs > 3,令 h 为 ? ToNumber(values[3]);否则令 h+0𝔽
    6. 如果 numberOfArgs > 4,令 min 为 ? ToNumber(values[4]);否则令 min+0𝔽
    7. 如果 numberOfArgs > 5,令 s 为 ? ToNumber(values[5]);否则令 s+0𝔽
    8. 如果 numberOfArgs > 6,令 milli 为 ? ToNumber(values[6]);否则令 milli+0𝔽
    9. yrMakeFullYear(y)。
    10. finalDateMakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))。
    11. dvTimeClip(UTC(finalDate))。
  6. O 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Date.prototype%", « [[DateValue]] »)。
  7. 设置 O.[[DateValue]]dv
  8. 返回 O

21.4.3 Date 构造函数的属性

Date 构造函数

  • 拥有一个 [[Prototype]] 内部槽,其值为 %Function.prototype%
  • 拥有一个 "length" 属性,其值为 7𝔽
  • 拥有以下属性:

21.4.3.1 Date.now ( )

此函数返回调用时发生的 UTC 日期和时间的时间值

21.4.3.2 Date.parse ( string )

此函数对其参数应用 ToString 操作符。如果 ToString 结果为突然完成,则立即返回完成记录。否则,此函数将结果字符串解释为日期和时间;它返回一个数字,即对应于该日期和时间的 UTC 时间值。字符串可能会被解释为本地时间、UTC 时间或其他时区的时间,具体取决于字符串内容。该函数首先尝试按照 Date Time String Format(21.4.1.32)中描述的格式解析字符串,包括扩展年份。如果字符串不符合该格式,则函数可以回退到任何实现相关的启发式或实现相关的日期格式。不可识别或包含越界格式元素值的字符串会导致此函数返回 NaN

如果字符串符合 Date Time String Format,则使用替代值填补缺失的格式元素。当缺少 MMDD 元素时,使用 "01";当缺少 HHmmss 元素时,使用 "00";当缺少 sss 元素时,使用 "000"。当缺少 UTC 偏移表示时,仅日期形式按 UTC 时间解释,日期时间形式按本地时间解释。

如果 x 是在某个 ECMAScript 实现中的毫秒部分为零的 Date,则以下所有表达式在该实现中应产生相同的数值,只要所有引用的属性都为初始值:

x.valueOf()
Date.parse(x.toString())
Date.parse(x.toUTCString())
Date.parse(x.toISOString())

然而,以下表达式

Date.parse(x.toLocaleString())

不要求与前三个表达式产生相同的数值,并且通常当此函数接收到任何不符合 Date Time String Format(21.4.1.32)且无法通过该实现的 toStringtoUTCString 方法产生的字符串值时,其产生的数值是实现定义的。

21.4.3.3 Date.prototype

Date.prototype 的初始值为 Date 原型对象

该属性具有属性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

21.4.3.4 Date.UTC ( year [ , month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ] )

调用此函数时,执行以下步骤:

  1. y 为 ? ToNumber(year)。
  2. 如果 month 存在,令 m 为 ? ToNumber(month);否则令 m+0𝔽
  3. 如果 date 存在,令 dt 为 ? ToNumber(date);否则令 dt1𝔽
  4. 如果 hours 存在,令 h 为 ? ToNumber(hours);否则令 h+0𝔽
  5. 如果 minutes 存在,令 min 为 ? ToNumber(minutes);否则令 min+0𝔽
  6. 如果 seconds 存在,令 s 为 ? ToNumber(seconds);否则令 s+0𝔽
  7. 如果 ms 存在,令 milli 为 ? ToNumber(ms);否则令 milli+0𝔽
  8. yrMakeFullYear(y)。
  9. 返回 TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)))。

此函数的 "length" 属性为 7𝔽

Note

此函数与 Date 构造函数有两个区别:它返回一个数字类型的时间值,而不是创建一个 Date,并且它以 UTC 解释参数而不是本地时间。

21.4.4 Date 原型对象的属性

Date 原型对象

  • %Date.prototype%
  • 自身是一个普通对象
  • 不是 Date 实例,也没有 [[DateValue]] 内部槽。
  • 有一个 [[Prototype]] 内部槽,其值为 %Object.prototype%

除非另有明确定义,下面定义的 Date 原型对象的方法不是泛型的,传递给它们的 this 值必须是具有并已初始化为时间值[[DateValue]] 内部槽的对象。

21.4.4.1 Date.prototype.constructor

Date.prototype.constructor 的初始值为 %Date%

21.4.4.2 Date.prototype.getDate ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 DateFromTime(LocalTime(t))。

21.4.4.3 Date.prototype.getDay ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 WeekDay(LocalTime(t))。

21.4.4.4 Date.prototype.getFullYear ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 YearFromTime(LocalTime(t))。

21.4.4.5 Date.prototype.getHours ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 HourFromTime(LocalTime(t))。

21.4.4.6 Date.prototype.getMilliseconds ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 msFromTime(LocalTime(t))。

21.4.4.7 Date.prototype.getMinutes ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 MinFromTime(LocalTime(t))。

21.4.4.8 Date.prototype.getMonth ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 MonthFromTime(LocalTime(t))。

21.4.4.9 Date.prototype.getSeconds ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 SecFromTime(LocalTime(t))。

21.4.4.10 Date.prototype.getTime ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. 返回 dateObject.[[DateValue]]

21.4.4.11 Date.prototype.getTimezoneOffset ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 (t - LocalTime(t)) / msPerMinute

21.4.4.12 Date.prototype.getUTCDate ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 DateFromTime(t)。

21.4.4.13 Date.prototype.getUTCDay ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 WeekDay(t)。

21.4.4.14 Date.prototype.getUTCFullYear ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 YearFromTime(t)。

21.4.4.15 Date.prototype.getUTCHours ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 HourFromTime(t)。

21.4.4.16 Date.prototype.getUTCMilliseconds ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 msFromTime(t)。

21.4.4.17 Date.prototype.getUTCMinutes ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 MinFromTime(t)。

21.4.4.18 Date.prototype.getUTCMonth ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 MonthFromTime(t)。

21.4.4.19 Date.prototype.getUTCSeconds ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,返回 NaN
  5. 返回 SecFromTime(t)。

21.4.4.20 Date.prototype.setDate ( date )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. dt 为 ? ToNumber(date)。
  5. 如果 tNaN,返回 NaN
  6. 设置 tLocalTime(t)。
  7. newDateMakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t))。
  8. uTimeClip(UTC(newDate))。
  9. 设置 dateObject.[[DateValue]]u
  10. 返回 u

21.4.4.21 Date.prototype.setFullYear ( year [ , month [ , date ] ] )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. y 为 ? ToNumber(year)。
  5. 如果 tNaN,设置 t+0𝔽;否则设置 tLocalTime(t)。
  6. 如果 month 未传入,令 mMonthFromTime(t);否则令 m 为 ? ToNumber(month)。
  7. 如果 date 未传入,令 dtDateFromTime(t);否则令 dt 为 ? ToNumber(date)。
  8. newDateMakeDate(MakeDay(y, m, dt), TimeWithinDay(t))。
  9. uTimeClip(UTC(newDate))。
  10. 设置 dateObject.[[DateValue]]u
  11. 返回 u

该方法的 "length" 属性为 3𝔽

Note

如果未传入 month,该方法表现为 monthgetMonth() 的值。如果未传入 date,则表现为 dategetDate() 的值。

21.4.4.22 Date.prototype.setHours ( hour [ , min [ , sec [ , ms ] ] ] )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. h 为 ? ToNumber(hour)。
  5. 如果传入 min,令 m 为 ? ToNumber(min)。
  6. 如果传入 sec,令 s 为 ? ToNumber(sec)。
  7. 如果传入 ms,令 milli 为 ? ToNumber(ms)。
  8. 如果 tNaN,返回 NaN
  9. 设置 tLocalTime(t)。
  10. 如果 min 未传入,令 mMinFromTime(t)。
  11. 如果 sec 未传入,令 sSecFromTime(t)。
  12. 如果 ms 未传入,令 millimsFromTime(t)。
  13. dateMakeDate(Day(t), MakeTime(h, m, s, milli))。
  14. uTimeClip(UTC(date))。
  15. 设置 dateObject.[[DateValue]]u
  16. 返回 u

该方法的 "length" 属性为 4𝔽

Note

如果未传入 min,该方法表现为 mingetMinutes() 的值。如果未传入 sec,表现为 secgetSeconds() 的值。如果未传入 ms,表现为 msgetMilliseconds() 的值。

21.4.4.23 Date.prototype.setMilliseconds ( ms )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 设置 ms 为 ? ToNumber(ms)。
  5. 如果 tNaN,返回 NaN
  6. 设置 tLocalTime(t)。
  7. timeMakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)。
  8. uTimeClip(UTC(MakeDate(Day(t), time)))。
  9. 设置 dateObject.[[DateValue]]u
  10. 返回 u

21.4.4.24 Date.prototype.setMinutes ( min [ , sec [ , ms ] ] )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. m 为 ? ToNumber(min)。
  5. 如果传入 sec,令 s 为 ? ToNumber(sec)。
  6. 如果传入 ms,令 milli 为 ? ToNumber(ms)。
  7. 如果 tNaN,返回 NaN
  8. 设置 tLocalTime(t)。
  9. 如果 sec 未传入,令 sSecFromTime(t)。
  10. 如果 ms 未传入,令 millimsFromTime(t)。
  11. dateMakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli))。
  12. uTimeClip(UTC(date))。
  13. 设置 dateObject.[[DateValue]]u
  14. 返回 u

该方法的 "length" 属性为 3𝔽

Note

如果未传入 sec,该方法表现为 secgetSeconds() 的值。如果未传入 ms,表现为 msgetMilliseconds() 的值。

21.4.4.25 Date.prototype.setMonth ( month [ , date ] )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. m 为 ? ToNumber(month)。
  5. 如果传入 date,令 dt 为 ? ToNumber(date)。
  6. 如果 tNaN,返回 NaN
  7. 设置 tLocalTime(t)。
  8. 如果 date 未传入,令 dtDateFromTime(t)。
  9. newDateMakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t))。
  10. uTimeClip(UTC(newDate))。
  11. 设置 dateObject.[[DateValue]]u
  12. 返回 u

该方法的 "length" 属性为 2𝔽

Note

如果未传入 date,该方法表现为 dategetDate() 的值。

21.4.4.26 Date.prototype.setSeconds ( sec [ , ms ] )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. s 为 ? ToNumber(sec)。
  5. 如果传入 ms,令 milli 为 ? ToNumber(ms)。
  6. 如果 tNaN,返回 NaN
  7. 设置 tLocalTime(t)。
  8. 如果 ms 未传入,令 millimsFromTime(t)。
  9. dateMakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli))。
  10. uTimeClip(UTC(date))。
  11. 设置 dateObject.[[DateValue]]u
  12. 返回 u

该方法的 "length" 属性为 2𝔽

Note

如果未传入 ms,该方法表现为 msgetMilliseconds() 的值。

21.4.4.27 Date.prototype.setTime ( time )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. t 为 ? ToNumber(time)。
  4. vTimeClip(t)。
  5. 设置 dateObject.[[DateValue]]v
  6. 返回 v

21.4.4.28 Date.prototype.setUTCDate ( date )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. dt 为 ? ToNumber(date)。
  5. 如果 tNaN,返回 NaN
  6. newDateMakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t))。
  7. vTimeClip(newDate)。
  8. 设置 dateObject.[[DateValue]]v
  9. 返回 v

21.4.4.29 Date.prototype.setUTCFullYear ( year [ , month [ , date ] ] )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 如果 tNaN,设置 t+0𝔽
  5. y 为 ? ToNumber(year)。
  6. 如果 month 未传入,令 mMonthFromTime(t);否则令 m 为 ? ToNumber(month)。
  7. 如果 date 未传入,令 dtDateFromTime(t);否则令 dt 为 ? ToNumber(date)。
  8. newDateMakeDate(MakeDay(y, m, dt), TimeWithinDay(t))。
  9. vTimeClip(newDate)。
  10. 设置 dateObject.[[DateValue]]v
  11. 返回 v

该方法的 "length" 属性为 3𝔽

Note

如果未传入 month,该方法表现为 monthgetUTCMonth() 的值。如果未传入 date,则表现为 dategetUTCDate() 的值。

21.4.4.30 Date.prototype.setUTCHours ( hour [ , min [ , sec [ , ms ] ] ] )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. h 为 ? ToNumber(hour)。
  5. 如果传入 min,令 m 为 ? ToNumber(min)。
  6. 如果传入 sec,令 s 为 ? ToNumber(sec)。
  7. 如果传入 ms,令 milli 为 ? ToNumber(ms)。
  8. 如果 tNaN,返回 NaN
  9. 如果 min 未传入,令 mMinFromTime(t)。
  10. 如果 sec 未传入,令 sSecFromTime(t)。
  11. 如果 ms 未传入,令 millimsFromTime(t)。
  12. dateMakeDate(Day(t), MakeTime(h, m, s, milli))。
  13. vTimeClip(date)。
  14. 设置 dateObject.[[DateValue]]v
  15. 返回 v

该方法的 "length" 属性为 4𝔽

Note

如果未传入 min,该方法表现为 mingetUTCMinutes() 的值。如果未传入 sec,表现为 secgetUTCSeconds() 的值。如果未传入 ms,表现为 msgetUTCMilliseconds() 的值。

21.4.4.31 Date.prototype.setUTCMilliseconds ( ms )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. 设置 ms 为 ? ToNumber(ms)。
  5. 如果 tNaN,返回 NaN
  6. timeMakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)。
  7. vTimeClip(MakeDate(Day(t), time))。
  8. 设置 dateObject.[[DateValue]]v
  9. 返回 v

21.4.4.32 Date.prototype.setUTCMinutes ( min [ , sec [ , ms ] ] )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. m 为 ? ToNumber(min)。
  5. 如果传入 sec,令 s 为 ? ToNumber(sec)。
  6. 如果传入 ms,令 milli 为 ? ToNumber(ms)。
  7. 如果 tNaN,返回 NaN
  8. 如果 sec 未传入,令 sSecFromTime(t)。
  9. 如果 ms 未传入,令 millimsFromTime(t)。
  10. dateMakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli))。
  11. vTimeClip(date)。
  12. 设置 dateObject.[[DateValue]]v
  13. 返回 v

该方法的 "length" 属性为 3𝔽

Note

如果未传入 sec,该方法表现为 secgetUTCSeconds() 的值。如果未传入 ms,表现为 msgetUTCMilliseconds() 的值。

21.4.4.33 Date.prototype.setUTCMonth ( month [ , date ] )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. m 为 ? ToNumber(month)。
  5. 如果传入 date,令 dt 为 ? ToNumber(date)。
  6. 如果 tNaN,返回 NaN
  7. 如果 date 未传入,令 dtDateFromTime(t)。
  8. newDateMakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t))。
  9. vTimeClip(newDate)。
  10. 设置 dateObject.[[DateValue]]v
  11. 返回 v

该方法的 "length" 属性为 2𝔽

Note

如果未传入 date,该方法表现为 dategetUTCDate() 的值。

21.4.4.34 Date.prototype.setUTCSeconds ( sec [ , ms ] )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. s 为 ? ToNumber(sec)。
  5. 如果传入 ms,令 milli 为 ? ToNumber(ms)。
  6. 如果 tNaN,返回 NaN
  7. 如果 ms 未传入,令 millimsFromTime(t)。
  8. dateMakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli))。
  9. vTimeClip(date)。
  10. 设置 dateObject.[[DateValue]]v
  11. 返回 v

该方法的 "length" 属性为 2𝔽

Note

如果未传入 ms,该方法表现为 msgetUTCMilliseconds() 的值。

21.4.4.35 Date.prototype.toDateString ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tvdateObject.[[DateValue]]
  4. 如果 tvNaN,返回 "Invalid Date"
  5. tLocalTime(tv)。
  6. 返回 DateString(t)。

21.4.4.36 Date.prototype.toISOString ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tvdateObject.[[DateValue]]
  4. 如果 tvNaN,抛出 RangeError 异常。
  5. 断言:tv 是整数类型的数字。
  6. 如果 tv 对应的年份无法在 Date Time String Format 中表示,抛出 RangeError 异常。
  7. 返回 tv 在 UTC 时间轴上的 Date Time String Format 字符串表示,包括所有格式元素和 UTC 偏移表示 "Z"

21.4.4.37 Date.prototype.toJSON ( key )

此方法为 JSON.stringify (25.5.2) 提供 Date 的字符串表示。

调用此方法时,执行以下步骤:

  1. O 为 ? ToObject(this 值)。
  2. tv 为 ? ToPrimitive(O, number)。
  3. 如果 tv 是数字且不是有限值,返回 null
  4. 返回 ? Invoke(O, "toISOString")。
Note 1

参数会被忽略。

Note 2

此方法有意设计为泛型;它不要求其 this 值为 Date。因此,它可以被转移到其他类型的对象上作为方法使用。但要求该对象有 toISOString 方法。

21.4.4.38 Date.prototype.toLocaleDateString ( [ reserved1 [ , reserved2 ] ] )

包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按照 ECMA-402 规范实现此方法。如果 ECMAScript 实现不包含 ECMA-402 API,则使用以下规范:

此方法返回一个字符串值。字符串内容由实现定义,但旨在以主机环境当前区域设置的习惯用法,以便捷、易读的方式表示当前时区中的 Date 的“日期”部分。

此方法的可选参数含义在 ECMA-402 规范中定义;不支持 ECMA-402 的实现不得在这些参数位置使用其他含义。

21.4.4.39 Date.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按照 ECMA-402 规范实现此方法。如果 ECMAScript 实现不包含 ECMA-402 API,则使用以下规范:

此方法返回一个字符串值。字符串内容由实现定义,但旨在以主机环境当前区域设置的习惯用法,以便捷、易读的方式表示当前时区中的 Date。

此方法的可选参数含义在 ECMA-402 规范中定义;不支持 ECMA-402 的实现不得在这些参数位置使用其他含义。

21.4.4.40 Date.prototype.toLocaleTimeString ( [ reserved1 [ , reserved2 ] ] )

包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按照 ECMA-402 规范实现此方法。如果 ECMAScript 实现不包含 ECMA-402 API,则使用以下规范:

此方法返回一个字符串值。字符串内容由实现定义,但旨在以主机环境当前区域设置的习惯用法,以便捷、易读的方式表示当前时区中的 Date 的“时间”部分。

此方法的可选参数含义在 ECMA-402 规范中定义;不支持 ECMA-402 的实现不得在这些参数位置使用其他含义。

21.4.4.41 Date.prototype.toString ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tvdateObject.[[DateValue]]
  4. 返回 ToDateString(tv)。
Note 1

对于任何 Date d,只要 d.[[DateValue]] 能被 1000 整除,则 Date.parse(d.toString()) = d.valueOf(),详见 21.4.3.2

Note 2

此方法不是泛型的;如果 this 值不是 Date,则抛出 TypeError 异常。因此,不能将其作为方法转移到其他类型对象。

21.4.4.41.1 TimeString ( tv )

The abstract operation TimeString takes argument tv (一个数字,但不是 NaN) and returns 一个字符串. It performs the following steps when called:

  1. hourToZeroPaddedDecimalString((HourFromTime(tv)), 2)。
  2. minuteToZeroPaddedDecimalString((MinFromTime(tv)), 2)。
  3. secondToZeroPaddedDecimalString((SecFromTime(tv)), 2)。
  4. 返回 hour":"minute":"second、码元 0x0020(空格)、"GMT" 的字符串拼接结果。

21.4.4.41.2 DateString ( tv )

The abstract operation DateString takes argument tv (一个数字,但不是 NaN) and returns 一个字符串. It performs the following steps when called:

  1. weekdayTable 63WeekDay(tv) 的 Name。
  2. monthTable 64MonthFromTime(tv) 的 Name。
  3. dayToZeroPaddedDecimalString((DateFromTime(tv)), 2)。
  4. yvYearFromTime(tv)。
  5. 如果 yv+0𝔽yv > +0𝔽,令 yearSign 为空字符串;否则令 yearSign"-"
  6. paddedYearToZeroPaddedDecimalString(abs((yv)), 4)。
  7. 返回 weekday、码元 0x0020(空格)、month、码元 0x0020(空格)、day、码元 0x0020(空格)、yearSignpaddedYear 的字符串拼接结果。
Table 63: 一周中各天的名称
Number Name
+0𝔽 "Sun"
1𝔽 "Mon"
2𝔽 "Tue"
3𝔽 "Wed"
4𝔽 "Thu"
5𝔽 "Fri"
6𝔽 "Sat"
Table 64: 一年中各月的名称
Number Name
+0𝔽 "Jan"
1𝔽 "Feb"
2𝔽 "Mar"
3𝔽 "Apr"
4𝔽 "May"
5𝔽 "Jun"
6𝔽 "Jul"
7𝔽 "Aug"
8𝔽 "Sep"
9𝔽 "Oct"
10𝔽 "Nov"
11𝔽 "Dec"

21.4.4.41.3 TimeZoneString ( tv )

The abstract operation TimeZoneString takes argument tv (一个整数类型的数字) and returns 一个字符串. It performs the following steps when called:

  1. systemTimeZoneIdentifierSystemTimeZoneIdentifier()。
  2. 如果 IsTimeZoneOffsetString(systemTimeZoneIdentifier) 是 true
    1. offsetNsParseTimeZoneOffsetString(systemTimeZoneIdentifier)。
  3. 否则,
    1. offsetNsGetNamedTimeZoneOffsetNanoseconds(systemTimeZoneIdentifier, ((tv) × 106))。
  4. offset𝔽(truncate(offsetNs / 106))。
  5. 如果 offset+0𝔽offset > +0𝔽
    1. offsetSign"+"
    2. absOffsetoffset
  6. 否则,
    1. offsetSign"-"
    2. absOffset 为 -offset
  7. offsetMinToZeroPaddedDecimalString((MinFromTime(absOffset)), 2)。
  8. offsetHourToZeroPaddedDecimalString((HourFromTime(absOffset)), 2)。
  9. tzName 为实现定义的字符串,可以为空字符串,也可以是码元 0x0020(空格)、码元 0x0028(左括号)、实现定义的时区名称和码元 0x0029(右括号)拼接的字符串。
  10. 返回 offsetSignoffsetHouroffsetMintzName 的字符串拼接结果。

21.4.4.41.4 ToDateString ( tv )

The abstract operation ToDateString takes argument tv (一个整数类型的数字或 NaN) and returns 一个字符串. It performs the following steps when called:

  1. 如果 tvNaN,返回 "Invalid Date"
  2. tLocalTime(tv)。
  3. 返回 DateString(t)、码元 0x0020(空格)、TimeString(t)、TimeZoneString(tv) 的字符串拼接结果。

21.4.4.42 Date.prototype.toTimeString ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tvdateObject.[[DateValue]]
  4. 如果 tvNaN,返回 "Invalid Date"
  5. tLocalTime(tv)。
  6. 返回 TimeString(t) 和 TimeZoneString(tv) 的字符串拼接结果。

21.4.4.43 Date.prototype.toUTCString ( )

此方法返回一个字符串值,表示与 this 值对应的时间点。字符串格式基于 RFC 7231 的 "HTTP-date",并加以泛化以支持 ECMAScript Date 支持的完整时间范围。

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tvdateObject.[[DateValue]]
  4. 如果 tvNaN,返回 "Invalid Date"
  5. weekdayTable 63WeekDay(tv) 的 Name。
  6. monthTable 64MonthFromTime(tv) 的 Name。
  7. dayToZeroPaddedDecimalString((DateFromTime(tv)), 2)。
  8. yvYearFromTime(tv)。
  9. 如果 yv+0𝔽yv > +0𝔽,令 yearSign 为空字符串;否则令 yearSign"-"
  10. paddedYearToZeroPaddedDecimalString(abs((yv)), 4)。
  11. 返回 weekday","、码元 0x0020(空格)、day、码元 0x0020(空格)、month、码元 0x0020(空格)、yearSignpaddedYear、码元 0x0020(空格)、TimeString(tv) 的字符串拼接结果。

21.4.4.44 Date.prototype.valueOf ( )

调用此方法时,执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. 返回 dateObject.[[DateValue]]

21.4.4.45 Date.prototype [ %Symbol.toPrimitive% ] ( hint )

此方法由 ECMAScript 语言运算符调用,用于将 Date 转换为原始值。hint 的允许值为 "default""number""string"。Date 在所有内建 ECMAScript 对象中是独特的,因为它将 "default" 视为等同于 "string",而其他内建对象则将 "default" 视为等同于 "number"

调用此方法时,执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是对象,抛出 TypeError 异常。
  3. 如果 hint"string""default"
    1. tryFirststring
  4. 否则如果 hint"number"
    1. tryFirstnumber
  5. 否则,
    1. 抛出 TypeError 异常。
  6. 返回 ? OrdinaryToPrimitive(O, tryFirst)。

此属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } 属性。

该方法的 "name" 属性值为 "[Symbol.toPrimitive]"

21.4.5 Date 实例的属性

Date 实例是普通对象,继承自 Date 原型对象的属性。Date 实例还拥有 [[DateValue]] 内部槽。[[DateValue]] 内部槽是该 Date 所表示的时间值

22 文本处理

22.1 String 对象

22.1.1 String 构造函数

String 构造函数

  • %String%
  • 是全局对象 "String" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 String 对象。
  • 作为函数而非构造函数调用时执行类型转换。
  • 可用作类定义中 extends 子句的值。打算继承指定 String 行为的子类构造函数必须包含对 String 构造函数super 调用,以使用 [[StringData]] 内部槽创建并初始化子类实例。

22.1.1.1 String ( value )

调用该函数时执行以下步骤:

  1. 如果未传入 value,则
    1. s 为空字符串。
  2. 否则,
    1. 如果 NewTarget 为 undefinedvalue 是一个 Symbol,返回 SymbolDescriptiveString(value)。
    2. s 为 ? ToString(value)。
  3. 如果 NewTarget 为 undefined,返回 s
  4. 返回 StringCreate(s, ? GetPrototypeFromConstructor(NewTarget, "%String.prototype%"))。

22.1.2 String 构造函数的属性

String 构造函数

22.1.2.1 String.fromCharCode ( ...codeUnits )

此函数可用任意数量的参数调用,这些参数组成剩余参数 codeUnits

调用时执行以下步骤:

  1. result 为空字符串。
  2. 对于 codeUnits 中的每个元素 next,执行
    1. nextCU 为数值为 (? ToUint16(next)) 的代码单元。
    2. result 设为 resultnextCU 的字符串拼接。
  3. 返回 result

该函数的 "length" 属性为 1𝔽

22.1.2.2 String.fromCodePoint ( ...codePoints )

此函数可用任意数量的参数调用,这些参数组成剩余参数 codePoints

调用时执行以下步骤:

  1. result 为空字符串。
  2. 对于 codePoints 中的每个元素 next,执行
    1. nextCP 为 ? ToNumber(next)。
    2. 如果 nextCP 不是整数数值,抛出 RangeError 异常。
    3. 如果 (nextCP) < 0 或 (nextCP) > 0x10FFFF,抛出 RangeError 异常。
    4. result 设为 result 与 UTF16EncodeCodePoint((nextCP)) 的字符串拼接。
  3. 断言:若 codePoints 为空,则 result 为空字符串。
  4. 返回 result

该函数的 "length" 属性为 1𝔽

22.1.2.3 String.prototype

String.prototype 的初始值是 String 原型对象

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

22.1.2.4 String.raw ( template, ...substitutions )

此函数可用可变数量参数调用。第一个参数为 template,其余参数构成列表 substitutions

调用时执行以下步骤:

  1. substitutionCountsubstitutions 中元素数量。
  2. cooked 为 ? ToObject(template)。
  3. literals 为 ? ToObject(? Get(cooked, "raw"))。
  4. literalCount 为 ? LengthOfArrayLike(literals)。
  5. literalCount ≤ 0,返回空字符串。
  6. R 为空字符串。
  7. nextIndex 为 0。
  8. 重复,
    1. nextLiteralVal 为 ? Get(literals, ! ToString(𝔽(nextIndex)))。
    2. nextLiteral 为 ? ToString(nextLiteralVal)。
    3. R 设为 RnextLiteral 的字符串拼接。
    4. nextIndex + 1 = literalCount,返回 R
    5. nextIndex < substitutionCount,则
      1. nextSubValsubstitutions[nextIndex]。
      2. nextSub 为 ? ToString(nextSubVal)。
      3. R 设为 RnextSub 的字符串拼接。
    6. nextIndex 设为 nextIndex + 1。
Note

此函数旨在作为标记模板(13.3.11)的标签函数使用。如此调用时,第一个参数将是格式正确的模板对象,剩余参数包含替换值。

22.1.3 String 原型对象的属性

String 原型对象

  • %String.prototype%
  • 是一个 String 特异(exotic)对象,并具有为此类对象指定的内部方法。
  • 有一个 [[StringData]] 内部槽,其值为空字符串。
  • 有一个 "length" 属性,其初始值为 +0𝔽,属性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。
  • 有一个 [[Prototype]] 内部槽,其值为 %Object.prototype%

除非另有明确说明,下面定义的 String 原型对象的方法不是泛型的,传入的 this 值必须是一个 String 值或者具有已初始化为某个 String 值的 [[StringData]] 内部槽的对象。

22.1.3.1 String.prototype.at ( index )

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. lenS 的长度。
  5. relativeIndex 为 ? ToIntegerOrInfinity(index)。
  6. 如果 relativeIndex ≥ 0,则
    1. krelativeIndex
  7. 否则,
    1. klen + relativeIndex
  8. k < 0 或 klen,返回 undefined
  9. 返回 S 中从 kk + 1 的子串。

22.1.3.2 String.prototype.charAt ( pos )

Note 1

该方法返回一个包含在将此对象转换为 String 后所得字符串中索引 pos 处代码单元的单元素字符串。如果该索引处无元素,则结果为空字符串。结果是 String 值,而非 String 对象。

如果 pos 是整数数值,则 x.charAt(pos) 的结果等价于 x.substring(pos, pos + 1) 的结果。

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. position 为 ? ToIntegerOrInfinity(pos)。
  5. sizeS 的长度。
  6. position < 0 或 positionsize,返回空字符串。
  7. 返回 S 中从 positionposition + 1 的子串。
Note 2

该方法特意设计为泛型;其 this 值不要求为 String 对象。因此可转移到其他对象类型上作为方法使用。

22.1.3.3 String.prototype.charCodeAt ( pos )

Note 1

该方法返回一个 Number(非负整数且小于 216),表示在将此对象转换为 String 后得到的字符串中索引 pos 处代码单元的数值。如果该索引处无元素,结果为 NaN

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. position 为 ? ToIntegerOrInfinity(pos)。
  5. sizeS 的长度。
  6. position < 0 或 positionsize,返回 NaN
  7. 返回在字符串 S 中索引 position 处代码单元的数值对应的 Number 值。
Note 2

该方法特意设计为泛型;其 this 值不要求为 String 对象。因此可转移到其他对象类型上作为方法使用。

22.1.3.4 String.prototype.codePointAt ( pos )

Note 1

该方法返回一个非负整数 Number(≤ 0x10FFFF𝔽),表示在将此对象转换为 String 后得到的字符串中索引 pos 处起始的 UTF-16 编码代码点(6.1.4)的数值。如果该索引处没有元素,返回 undefined。如果在 pos 处没有以有效 UTF-16 代理对开始,则结果为 pos 处的代码单元。

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. position 为 ? ToIntegerOrInfinity(pos)。
  5. sizeS 的长度。
  6. position < 0 或 positionsize,返回 undefined
  7. cp 为 CodePointAt(S, position)。
  8. 返回 𝔽(cp.[[CodePoint]])。
Note 2

该方法特意设计为泛型;其 this 值不要求为 String 对象。因此可转移到其他对象类型上作为方法使用。

22.1.3.5 String.prototype.concat ( ...args )

Note 1

调用此方法时,它返回一个由 this 值(转换为字符串)的代码单元后接每个参数(各自转换为字符串)的代码单元组成的字符串值。结果是一个 String 值,而非 String 对象。

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. RS
  5. 对于 args 中的每个元素 next,执行
    1. nextString 为 ? ToString(next)。
    2. R 设为 RnextString 的字符串拼接。
  6. 返回 R

该方法的 "length" 属性为 1𝔽

Note 2

该方法特意设计为泛型;其 this 值不要求为 String 对象。因此可转移到其他对象类型上作为方法使用。

22.1.3.6 String.prototype.constructor

String.prototype.constructor 的初始值是 %String%

22.1.3.7 String.prototype.endsWith ( searchString [ , endPosition ] )

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. isRegExp 为 ? IsRegExp(searchString)。
  5. isRegExptrue,抛出 TypeError 异常。
  6. searchStr 为 ? ToString(searchString)。
  7. lenS 的长度。
  8. endPositionundefined,令 poslen;否则令 pos 为 ? ToIntegerOrInfinity(endPosition)。
  9. end 为将 pos 钳制在 0 和 len 之间的结果。
  10. searchLengthsearchStr 的长度。
  11. searchLength = 0,返回 true
  12. startend - searchLength
  13. start < 0,返回 false
  14. substringS 中从 startend 的子串。
  15. substringsearchStr,返回 true
  16. 返回 false
Note 1

searchString(转为 String) 的代码单元序列与该对象(转为 String)在 endPosition - length(this) 处开始的对应代码单元相同,则此方法返回 true;否则返回 false

Note 2

当第一个参数是 RegExp 时抛出异常是为了允许未来版本定义允许此类参数值的扩展。

Note 3

该方法特意设计为泛型;其 this 值不要求为 String 对象。因此可转移到其他对象类型上作为方法使用。

22.1.3.8 String.prototype.includes ( searchString [ , position ] )

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. isRegExp 为 ? IsRegExp(searchString)。
  5. isRegExptrue,抛出 TypeError 异常。
  6. searchStr 为 ? ToString(searchString)。
  7. pos 为 ? ToIntegerOrInfinity(position)。
  8. 断言:如果 positionundefined,则 pos 为 0。
  9. lenS 的长度。
  10. start 为将 pos 钳制在 0 和 len 之间的结果。
  11. indexStringIndexOf(S, searchStr, start)。
  12. indexnot-found,返回 false
  13. 返回 true
Note 1

如果 searchString 作为 substring 出现在将该对象转换为 String 的结果中,并且其至少一个出现位置索引 ≥ position,则该函数返回 true;否则返回 false。若 positionundefined,则视为 0,因此搜索全部字符串。

Note 2

当第一个参数是 RegExp 时抛出异常是为了允许未来版本定义允许此类参数值的扩展。

Note 3

该方法特意设计为泛型;其 this 值不要求为 String 对象。因此可转移到其他对象类型上作为方法使用。

22.1.3.9 String.prototype.indexOf ( searchString [ , position ] )

Note 1

如果 searchString 作为 substring 出现在将该对象转换为 String 的结果中,并且至少一个出现位置索引 ≥ position,则返回最小的此类索引;否则返回 -1𝔽。若 positionundefined,则视为 +0𝔽,以便搜索整个字符串。

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. searchStr 为 ? ToString(searchString)。
  5. pos 为 ? ToIntegerOrInfinity(position)。
  6. 断言:如果 positionundefined,则 pos 为 0。
  7. lenS 的长度。
  8. start 为将 pos 钳制在 0 和 len 之间的结果。
  9. resultStringIndexOf(S, searchStr, start)。
  10. resultnot-found,返回 -1𝔽
  11. 返回 𝔽(result)。
Note 2

该方法特意设计为泛型;其 this 值不要求为 String 对象。因此可转移到其他对象类型上作为方法使用。

22.1.3.10 String.prototype.isWellFormed ( )

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. 返回 IsStringWellFormedUnicode(S)。

22.1.3.11 String.prototype.lastIndexOf ( searchString [ , position ] )

Note 1

如果 searchString 作为 substring 出现在将该对象转换为 String 的结果中,且出现位置索引 ≤ position,则返回最大的此类索引;否则返回 -1𝔽。若 positionundefined,则视为该字符串长度,以便搜索整个字符串。

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. searchStr 为 ? ToString(searchString)。
  5. numPos 为 ? ToNumber(position)。
  6. 断言:若 positionundefined,则 numPosNaN
  7. numPosNaN,令 pos 为 +∞;否则令 pos 为 ! ToIntegerOrInfinity(numPos)。
  8. lenS 的长度。
  9. searchLensearchStr 的长度。
  10. start 为将 pos 钳制在 0 和 len - searchLen 之间的结果。
  11. resultStringLastIndexOf(S, searchStr, start)。
  12. resultnot-found,返回 -1𝔽
  13. 返回 𝔽(result)。
Note 2

该方法特意设计为泛型;其 this 值不要求为 String 对象,因此可转移到其他对象类型上作为方法使用。

22.1.3.12 String.prototype.localeCompare ( that [ , reserved1 [ , reserved2 ] ] )

包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按 ECMA-402 的规范实现此方法。若不包含,则使用下述规范:

此方法返回一个非 NaN 的 Number,表示将 this 值(转换为字符串 S)与 that(转换为字符串 thatValue)进行实现定义的、对区域敏感的字符串比较的结果。该结果意图与宿主环境当前区域设置的字符串排序规则一致:当 S 排在 thatValue 之前时为负,排在之后时为正,其他情况为零(表示 SthatValue 之间无相对次序)。

在执行比较前,此方法进行以下准备步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. thatValue 为 ? ToString(that)。

第二与第三可选参数的含义在 ECMA-402 规范中定义;不包含 ECMA-402 支持的实现不得为这些参数位置赋予其他含义。

实际返回值是实现定义的,以允许编码附加信息;但是当该方法视作二元比较器使用时,必须定义所有字符串集合上的一个总排序。该方法还必须识别并遵循 Unicode 标准中的规范等价(canonical equivalence),包括在比较可区分但规范等价的字符串时返回 +0𝔽

Note 1

该方法本身不适合作为 Array.prototype.sort 的参数,因为后者需要一个二元函数。

Note 2

该方法可依赖宿主环境提供的语言或区域敏感比较功能,并意图依据宿主环境当前区域设置的习惯比较。然而,无论比较能力如何,该方法必须识别并遵循 Unicode 标准的规范等价——例如以下比较都必须返回 +0𝔽

// Å ANGSTROM SIGN vs.
// Å LATIN CAPITAL LETTER A + COMBINING RING ABOVE
"\u212B".localeCompare("A\u030A")

// Ω OHM SIGN vs.
// Ω GREEK CAPITAL LETTER OMEGA
"\u2126".localeCompare("\u03A9")

// ṩ LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE vs.
// ṩ LATIN SMALL LETTER S + COMBINING DOT ABOVE + COMBINING DOT BELOW
"\u1E69".localeCompare("s\u0307\u0323")

// ḍ̇ LATIN SMALL LETTER D WITH DOT ABOVE + COMBINING DOT BELOW vs.
// ḍ̇ LATIN SMALL LETTER D WITH DOT BELOW + COMBINING DOT ABOVE
"\u1E0B\u0323".localeCompare("\u1E0D\u0307")

// 가 HANGUL CHOSEONG KIYEOK + HANGUL JUNGSEONG A vs.
// 가 HANGUL SYLLABLE GA
"\u1100\u1161".localeCompare("\uAC00")

关于规范等价的定义与讨论,参见 Unicode 标准第 2、3 章,以及 Unicode Standard Annex #15, Unicode Normalization FormsUnicode Technical Note #5, Canonical Equivalence in Applications。另参见 Unicode Technical Standard #10, Unicode Collation Algorithm

建议该方法不应遵循 Unicode 标准第 3 章第 3.7 节中定义的兼容等价或兼容分解。

Note 3

该方法特意设计为泛型;其 this 值不要求为 String 对象。因此可转移到其他对象类型上作为方法使用。

22.1.3.13 String.prototype.match ( regexp )

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. regexp 既不是 undefined 也不是 null,则
    1. matcher 为 ? GetMethod(regexp, %Symbol.match%)。
    2. matcher 不为 undefined,则
      1. 返回 ? Call(matcher, regexp, « O »)。
  4. S 为 ? ToString(O)。
  5. rx 为 ? RegExpCreate(regexp, undefined)。
  6. 返回 ? Invoke(rx, %Symbol.match%, « S »)。
Note

该方法特意设计为泛型;其 this 值不要求为 String 对象。因此可转移到其他对象类型上作为方法使用。

22.1.3.14 String.prototype.matchAll ( regexp )

该方法对表示 this 值的字符串执行正则表达式匹配并返回一个产出匹配结果的迭代器。每个匹配结果是一个数组,其首元素为匹配的子串,后续元素为任意捕获组匹配的部分。若正则表达式从未匹配,则返回的迭代器不产出任何匹配结果。

调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. regexp 既不是 undefined 也不是 null,则
    1. isRegExp 为 ? IsRegExp(regexp)。
    2. isRegExptrue,则
      1. flags 为 ? Get(regexp, "flags")。
      2. 执行 ? RequireObjectCoercible(flags)。
      3. 若 ? ToString(flags) 不包含 "g",抛出 TypeError 异常。
    3. matcher 为 ? GetMethod(regexp, %Symbol.matchAll%)。
    4. matcher 不为 undefined,则
      1. 返回 ? Call(matcher, regexp, « O »)。
  4. S 为 ? ToString(O)。
  5. rx 为 ? RegExpCreate(regexp, "g")。
  6. 返回 ? Invoke(rx, %Symbol.matchAll%, « S »)。
Note 1
该方法特意设计为泛型,不要求其 this 值为 String 对象。因此可转移到其他对象类型上使用。
Note 2
String.prototype.split 相似,String.prototype.matchAll 被设计为通常不修改其输入。

22.1.3.15 String.prototype.normalize ( [ form ] )

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. formundefined,令 f"NFC"
  5. 否则,令 f 为 ? ToString(form)。
  6. f 不在 "NFC""NFD""NFKC""NFKD" 之一中,抛出 RangeError 异常。
  7. ns 为将 S 归一化为由 f 命名的标准化形式所得的字符串值(参见 最新 Unicode 标准 - 归一化形式)。
  8. 返回 ns
Note

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可以转移到其他对象类型使用。

22.1.3.16 String.prototype.padEnd ( maxLength [ , fillString ] )

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. 返回 ? StringPaddingBuiltinsImpl(O, maxLength, fillString, end)。

22.1.3.17 String.prototype.padStart ( maxLength [ , fillString ] )

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. 返回 ? StringPaddingBuiltinsImpl(O, maxLength, fillString, start)。

22.1.3.17.1 StringPaddingBuiltinsImpl ( O, maxLength, fillString, placement )

The abstract operation StringPaddingBuiltinsImpl takes arguments O (一个 ECMAScript 语言值), maxLength (一个 ECMAScript 语言值), fillString (一个 ECMAScript 语言值), and placement (startend) and returns 返回包含一个字符串的普通完成或抛出完成. It performs the following steps when called:

  1. S 为 ? ToString(O)。
  2. intMaxLength(? ToLength(maxLength))。
  3. stringLengthS 的长度。
  4. intMaxLengthstringLength,返回 S
  5. fillStringundefined,将 fillString 设为仅包含代码单元 0x0020 (SPACE) 的字符串。
  6. 否则,将 fillString 设为 ? ToString(fillString)。
  7. 返回 StringPad(S, intMaxLength, fillString, placement)。

22.1.3.17.2 StringPad ( S, maxLength, fillString, placement )

The abstract operation StringPad takes arguments S (一个字符串), maxLength (非负整数), fillString (一个字符串), and placement (startend) and returns 一个字符串. It performs the following steps when called:

  1. stringLengthS 的长度。
  2. maxLengthstringLength,返回 S
  3. fillString 为空字符串,返回 S
  4. fillLenmaxLength - stringLength
  5. truncatedStringFiller 为由重复拼接 fillString 直至截断到长度 fillLen 得到的字符串。
  6. placementstart,返回 truncatedStringFillerS 的字符串拼接。
  7. 否则,返回 StruncatedStringFiller 的字符串拼接。
Note 1

参数 maxLength 会被钳制,使其不小于 S 的长度。

Note 2

参数 fillString 的默认值为 " "(仅包含代码单元 0x0020 SPACE 的字符串)。

22.1.3.17.3 ToZeroPaddedDecimalString ( n, minLength )

The abstract operation ToZeroPaddedDecimalString takes arguments n (非负整数) and minLength (非负整数) and returns 一个字符串. It performs the following steps when called:

  1. Sn 的十进制格式字符串表示。
  2. 返回 StringPad(S, minLength, "0", start)。

22.1.3.18 String.prototype.repeat ( count )

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. n 为 ? ToIntegerOrInfinity(count)。
  5. n < 0 或 n = +∞,抛出 RangeError 异常。
  6. n = 0,返回空字符串。
  7. 返回由 nS 依次拼接而成的字符串值。
Note 1

此方法创建一个字符串值,其内容为 this 值(转换为字符串)重复 count 次。

Note 2

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移至其他对象类型使用。

22.1.3.19 String.prototype.replace ( searchValue, replaceValue )

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. searchValue 既非 undefined 也非 null,则
    1. replacer 为 ? GetMethod(searchValue, %Symbol.replace%)。
    2. replacer 不为 undefined,则
      1. 返回 ? Call(replacer, searchValue, « O, replaceValue »)。
  4. string 为 ? ToString(O)。
  5. searchString 为 ? ToString(searchValue)。
  6. functionalReplaceIsCallable(replaceValue)。
  7. functionalReplacefalse,则
    1. replaceValue 设为 ? ToString(replaceValue)。
  8. searchLengthsearchString 的长度。
  9. positionStringIndexOf(string, searchString, 0)。
  10. positionnot-found,返回 string
  11. precedingstring 中从 0 到 position 的子串。
  12. followingstring 中从 position + searchLength 起的子串。
  13. functionalReplacetrue,则
    1. replacement 为 ? ToString(? Call(replaceValue, undefined, « searchString, 𝔽(position), string »))。
  14. 否则,
    1. 断言:replaceValue 为字符串。
    2. captures 为一个新的空列表。
    3. replacement 为 ! GetSubstitution(searchString, string, position, captures, undefined, replaceValue)。
  15. 返回 precedingreplacementfollowing 的字符串拼接。
Note

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移到其他对象类型作为方法使用。

22.1.3.19.1 GetSubstitution ( matched, str, position, captures, namedCaptures, replacementTemplate )

The abstract operation GetSubstitution takes arguments matched (字符串), str (字符串), position (非负整数), captures (由字符串或 undefined 组成的列表), namedCaptures (对象或 undefined), and replacementTemplate (字符串) and returns 返回包含一个字符串的普通完成或抛出完成. 在此抽象操作中,十进制数字 指代码单元范围 0x0030 (DIGIT ZERO) 至 0x0039 (DIGIT NINE) 内的任一代码单元。 It performs the following steps when called:

  1. stringLengthstr 的长度。
  2. 断言:positionstringLength
  3. result 为空字符串。
  4. templateRemainderreplacementTemplate
  5. templateRemainder 非空字符串时重复,
    1. 注:下列步骤提取 reftemplateRemainder 的前缀)、确定 refReplacement(其替换),然后将替换附加到 result
    2. templateRemainder"$$" 开头,则
      1. ref"$$"
      2. refReplacement"$"
    3. 否则若以 "$`" 开头,则
      1. ref"$`"
      2. refReplacementstr 中从 0 到 position 的子串。
    4. 否则若以 "$&" 开头,则
      1. ref"$&"
      2. refReplacementmatched
    5. 否则若以 "$'"(0x0024 (DOLLAR SIGN) 后接 0x0027 (APOSTROPHE))开头,则
      1. ref"$'"
      2. matchLengthmatched 的长度。
      3. tailPosposition + matchLength
      4. refReplacementstr 中从 min(tailPos, stringLength) 起的子串。
      5. 注:tailPos 仅当此抽象操作%RegExp.prototype% 的本征 %Symbol.replace% 方法被一个 "exec" 属性非其本征 %RegExp.prototype.exec% 的对象调用时才可能超过 stringLength
    6. 否则若以 "$" 后接 1 个或多个十进制数字开头,则
      1. 若以 "$" 后接至少 2 个十进制数字开头,令 digitCount 为 2;否则令 digitCount 为 1。
      2. digitstemplateRemainder 中从 1 到 1 + digitCount 的子串。
      3. index(StringToNumber(digits))。
      4. 断言:0 ≤ index ≤ 99。
      5. captureLencaptures 的元素数量。
      6. index > captureLendigitCount = 2,则
        1. 注:当两位数字替换模式指定的索引超过捕获组数量时,它被视为一位数字替换模式后随一个字面数字。
        2. digitCount 设为 1。
        3. digits 设为 digits 中从 0 到 1 的子串。
        4. index 设为 (StringToNumber(digits))。
      7. reftemplateRemainder 中从 0 到 1 + digitCount 的子串。
      8. 若 1 ≤ indexcaptureLen,则
        1. capturecaptures[index - 1]。
        2. captureundefined,则
          1. refReplacement 为空字符串。
        3. 否则,
          1. refReplacementcapture
      9. 否则,
        1. refReplacementref
    7. 否则若以 "$<" 开头,则
      1. gtPosStringIndexOf(templateRemainder, ">", 0)。
      2. gtPosnot-foundnamedCapturesundefined,则
        1. ref"$<"
        2. refReplacementref
      3. 否则,
        1. reftemplateRemainder 中从 0 到 gtPos + 1 的子串。
        2. groupNametemplateRemainder 中从 2 到 gtPos 的子串。
        3. 断言:namedCaptures 是一个对象。
        4. capture 为 ? Get(namedCaptures, groupName)。
        5. captureundefined,则
          1. refReplacement 为空字符串。
        6. 否则,
          1. refReplacement 为 ? ToString(capture)。
    8. 否则,
      1. reftemplateRemainder 中从 0 到 1 的子串。
      2. refReplacementref
    9. refLengthref 的长度。
    10. templateRemainder 设为其从 refLength 起的子串。
    11. result 设为 resultrefReplacement 的字符串拼接。
  6. 返回 result

22.1.3.20 String.prototype.replaceAll ( searchValue, replaceValue )

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. searchValue 既非 undefined 也非 null,则
    1. isRegExp 为 ? IsRegExp(searchValue)。
    2. isRegExptrue,则
      1. flags 为 ? Get(searchValue, "flags")。
      2. 执行 ? RequireObjectCoercible(flags)。
      3. 若 ? ToString(flags) 不包含 "g",抛出 TypeError 异常。
    3. replacer 为 ? GetMethod(searchValue, %Symbol.replace%)。
    4. replacer 不为 undefined,则
      1. 返回 ? Call(replacer, searchValue, « O, replaceValue »)。
  4. string 为 ? ToString(O)。
  5. searchString 为 ? ToString(searchValue)。
  6. functionalReplaceIsCallable(replaceValue)。
  7. functionalReplacefalse,则
    1. replaceValue 设为 ? ToString(replaceValue)。
  8. searchLengthsearchString 长度。
  9. advanceBymax(1, searchLength)。
  10. matchPositions 为新的空列表。
  11. positionStringIndexOf(string, searchString, 0)。
  12. positionnot-found 时重复,
    1. position 附加到 matchPositions
    2. position 设为 StringIndexOf(string, searchString, position + advanceBy)。
  13. endOfLastMatch 为 0。
  14. result 为空字符串。
  15. 对于 matchPositions 中的每个元素 p,执行
    1. preservedstring 中从 endOfLastMatchp 的子串。
    2. functionalReplacetrue,则
      1. replacement 为 ? ToString(? Call(replaceValue, undefined, « searchString, 𝔽(p), string »))。
    3. 否则,
      1. 断言:replaceValue 为字符串。
      2. captures 为新的空列表。
      3. replacement 为 ! GetSubstitution(searchString, string, p, captures, undefined, replaceValue)。
    4. result 设为 resultpreservedreplacement 的字符串拼接。
    5. endOfLastMatch 设为 p + searchLength
  16. endOfLastMatch < string 的长度,则
    1. result 设为 resultstring 中从 endOfLastMatch 起的子串的字符串拼接。
  17. 返回 result

22.1.3.21 String.prototype.search ( regexp )

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. regexp 既非 undefined 也非 null,则
    1. searcher 为 ? GetMethod(regexp, %Symbol.search%)。
    2. searcher 不为 undefined,则
      1. 返回 ? Call(searcher, regexp, « O »)。
  4. string 为 ? ToString(O)。
  5. rx 为 ? RegExpCreate(regexp, undefined)。
  6. 返回 ? Invoke(rx, %Symbol.search%, « string »)。
Note

该方法特意设计为泛型;其 this 不要求为 String 对象。因此可转移到其他对象类型作为方法使用。

22.1.3.22 String.prototype.slice ( start, end )

该方法返回将此对象转换为字符串后的 substring,起始于索引 start,结束于但不包括索引 end(若 endundefined 则到字符串末尾)。若 start 为负,则视为 sourceLength + start,其中 sourceLength 为字符串长度。若 end 为负,则视为 sourceLength + end。结果是一个字符串值而非 String 对象。

调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. lenS 的长度。
  5. intStart 为 ? ToIntegerOrInfinity(start)。
  6. intStart = -∞,令 from 为 0。
  7. 否则若 intStart < 0,令 frommax(len + intStart, 0)。
  8. 否则,令 frommin(intStart, len)。
  9. endundefined,令 intEndlen;否则令 intEnd 为 ? ToIntegerOrInfinity(end)。
  10. intEnd = -∞,令 to 为 0。
  11. 否则若 intEnd < 0,令 tomax(len + intEnd, 0)。
  12. 否则,令 tomin(intEnd, len)。
  13. fromto,返回空字符串。
  14. 返回 S 中从 fromto 的子串。
Note

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移到其他对象类型使用。

22.1.3.23 String.prototype.split ( separator, limit )

该方法返回一个数组,其中存放了将此对象转换为字符串后的子串。子串通过自左向右查找 separator 的出现确定;这些出现本身不包含在结果数组的任一字符串中,而是用来分割字符串值。separator 的值可以是任意长度的字符串,也可以是一个对象(如具有 %Symbol.split% 方法的 RegExp)。

调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. separator 既非 undefined 也非 null,则
    1. splitter 为 ? GetMethod(separator, %Symbol.split%)。
    2. splitter 不为 undefined,则
      1. 返回 ? Call(splitter, separator, « O, limit »)。
  4. S 为 ? ToString(O)。
  5. limitundefined,令 lim 为 232 - 1;否则令 lim(? ToUint32(limit))。
  6. R 为 ? ToString(separator)。
  7. lim = 0,则
    1. 返回 CreateArrayFromList(« »)。
  8. separatorundefined,则
    1. 返回 CreateArrayFromListS »)。
  9. separatorLengthR 的长度。
  10. separatorLength = 0,则
    1. strLenS 的长度。
    2. outLen 为将 lim 钳制在 0 与 strLen 之间的结果。
    3. headS 中从 0 到 outLen 的子串。
    4. codeUnitshead 代码单元序列组成的列表。
    5. 返回 CreateArrayFromList(codeUnits)。
  11. S 为空字符串,返回 CreateArrayFromListS »)。
  12. substrings 为新的空列表。
  13. i 为 0。
  14. jStringIndexOf(S, R, 0)。
  15. jnot-found 时重复,
    1. TS 中从 ij 的子串。
    2. T 添加至 substrings
    3. substrings 的元素个数为 lim,返回 CreateArrayFromList(substrings)。
    4. i 设为 j + separatorLength
    5. j 设为 StringIndexOf(S, R, i)。
  16. TS 中自 i 起的子串。
  17. T 添加至 substrings
  18. 返回 CreateArrayFromList(substrings)。
Note 1

separator 的值可以为空字符串。在此情况下,separator 不匹配输入字符串开始或末尾的空 substring,也不匹配前一个分隔符匹配末尾的空 substring。如果 separator 为空字符串,则字符串被拆分为单个代码单元元素;结果数组长度等于字符串长度,每个 substring 含一个代码单元。

如果 this 值(或其转换结果)为空字符串,则结果取决于 separator 是否能匹配空字符串:若能,则结果数组为空;否则数组包含一个元素,即空字符串。

separatorundefined,结果数组只包含一个字符串,即 this 值(转换为 String)。若 limitundefined,输出数组会被截断为不超过 limit 个元素。

Note 2

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移到其他对象类型使用。

22.1.3.24 String.prototype.startsWith ( searchString [ , position ] )

调用该方法时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. isRegExp 为 ? IsRegExp(searchString)。
  5. isRegExptrue,抛出 TypeError 异常。
  6. searchStr 为 ? ToString(searchString)。
  7. lenS 的长度。
  8. positionundefined,令 pos 为 0;否则令 pos 为 ? ToIntegerOrInfinity(position)。
  9. start 为将 pos 钳制在 0 与 len 之间的结果。
  10. searchLengthsearchStr 的长度。
  11. searchLength = 0,返回 true
  12. endstart + searchLength
  13. end > len,返回 false
  14. substringS 中从 startend 的子串。
  15. substringsearchStr,返回 true
  16. 返回 false
Note 1

searchString(转换为 String)的代码单元序列与该对象(转换为 String)从索引 position 开始的对应代码单元相同,则该方法返回 true;否则返回 false

Note 2

当第一个参数是 RegExp 时抛出异常是为了允许未来版本扩展允许此类参数值。

Note 3

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移到其他对象类型使用。

22.1.3.25 String.prototype.substring ( start, end )

该方法返回将此对象转换为字符串后,从索引 start 开始到(但不包含)索引 end(或 endundefined 时到字符串末尾)的 substring。结果为字符串值,不是 String 对象。

若任一参数为 NaN 或为负,则替换为 0;若任一参数严格大于字符串长度,则替换为字符串长度。

start 严格大于 end,则交换它们。

调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. lenS 的长度。
  5. intStart 为 ? ToIntegerOrInfinity(start)。
  6. endundefined,令 intEndlen;否则令 intEnd 为 ? ToIntegerOrInfinity(end)。
  7. finalStart 为将 intStart 钳制在 0 与 len 之间的结果。
  8. finalEnd 为将 intEnd 钳制在 0 与 len 之间的结果。
  9. frommin(finalStart, finalEnd)。
  10. tomax(finalStart, finalEnd)。
  11. 返回 S 中从 fromto 的子串。
Note

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移到其他对象类型使用。

22.1.3.26 String.prototype.toLocaleLowerCase ( [ reserved1 [ , reserved2 ] ] )

包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按 ECMA-402 规范实现此方法。若不包含,则使用以下规范:

此方法将一个字符串值视为 UTF-16 编码代码点序列,参见 6.1.4

其行为与 toLowerCase 相同,但意在生成与宿主环境当前区域设置约定相符的对区域敏感结果。只有在少数(如土耳其语)与 Unicode 常规大小写映射冲突的语言情况下,结果才会不同。

该方法可选参数的含义在 ECMA-402 中定义;未包含 ECMA-402 支持的实现不得对这些参数位置赋予其他含义。

Note

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移到其他对象类型使用。

22.1.3.27 String.prototype.toLocaleUpperCase ( [ reserved1 [ , reserved2 ] ] )

包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按 ECMA-402 规范实现此方法。若不包含,则使用以下规范:

此方法将字符串值视为 UTF-16 编码代码点序列(参见 6.1.4)。

其行为与 toUpperCase 相同,但意在生成与宿主环境当前区域设置约定相符的对区域敏感结果。仅在少数如土耳其语的情形中,语言规则与常规 Unicode 大小写映射冲突时才会不同。

该方法可选参数含义由 ECMA-402 规范定义;未包含 ECMA-402 支持的实现不得赋予其他含义。

Note

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移到其他对象类型使用。

22.1.3.28 String.prototype.toLowerCase ( )

此方法将字符串值视为 UTF-16 编码代码点序列(参见 6.1.4)。

调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. sText 为 StringToCodePoints(S)。
  5. lowerText 为依据 Unicode 默认大小写转换算法对 sText 执行 toLowercase 的结果。
  6. L 为 CodePointsToString(lowerText)。
  7. 返回 L

结果必须依据 Unicode 字符数据库中的与区域无关的大小写映射获得(明确包括 UnicodeData.txt 文件以及伴随的 SpecialCasing.txt 中所有与区域无关的映射)。

Note 1

某些代码点的大小写映射会产生多个代码点。在此情况下结果字符串长度可能不同于源字符串。由于 toUpperCasetoLowerCase 均具有上下文相关行为,这两个方法并不对称;即 s.toUpperCase().toLowerCase() 不一定等于 s.toLowerCase()

Note 2

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移到其他对象类型使用。

22.1.3.29 String.prototype.toString ( )

调用该方法时执行以下步骤:

  1. 返回 ? ThisStringValue(this value)。
Note

对于 String 对象,该方法恰好与 valueOf 方法返回相同的值。

22.1.3.30 String.prototype.toUpperCase ( )

此方法将字符串值视为 UTF-16 编码代码点序列(参见 6.1.4)。

其行为与 String.prototype.toLowerCase 相同,只是字符串使用 Unicode 默认大小写转换中的 toUppercase 算法映射。

Note

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移到其他对象类型使用。

22.1.3.31 String.prototype.toWellFormed ( )

该方法返回此对象的字符串表示,其中所有不成对的前导或后导代理项被替换为 U+FFFD(REPLACEMENT CHARACTER)。

调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. strLenS 的长度。
  5. k 为 0。
  6. result 为空字符串。
  7. k < strLen 时重复,
    1. cp 为 CodePointAt(S, k)。
    2. cp.[[IsUnpairedSurrogate]]true,则
      1. result 设为 result 与 0xFFFD (REPLACEMENT CHARACTER) 的字符串拼接。
    3. 否则,
      1. result 设为 result 与 UTF16EncodeCodePoint(cp.[[CodePoint]]) 的字符串拼接。
    4. k 设为 k + cp.[[CodeUnitCount]]
  8. 返回 result

22.1.3.32 String.prototype.trim ( )

该方法将字符串值视为 UTF-16 编码代码点序列(参见 6.1.4)。

调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? TrimString(S, start+end)。
Note

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移到其他对象类型使用。

22.1.3.32.1 TrimString ( string, where )

The abstract operation TrimString takes arguments string (一个 ECMAScript 语言值) and where (start, end, 或 start+end) and returns 返回包含一个字符串的普通完成或抛出完成. 它将 string 视为 UTF-16 编码代码点序列,参见 6.1.4。 It performs the following steps when called:

  1. 执行 ? RequireObjectCoercible(string)。
  2. S 为 ? ToString(string)。
  3. wherestart,则
    1. T 为移除前导空白后的 S 副本。
  4. 否则若 whereend,则
    1. T 为移除尾随空白后的 S 副本。
  5. 否则,
    1. 断言:wherestart+end
    2. T 为移除前后空白后的 S 副本。
  6. 返回 T

空白的定义为 WhiteSpaceLineTerminator 的并集。判断某 Unicode 代码点是否属于 Unicode 通用类别 “Space_Separator”(“Zs”) 时,代码单元序列按 6.1.4 指定的 UTF-16 编码代码点序列解释。

22.1.3.33 String.prototype.trimEnd ( )

该方法将字符串值视为 UTF-16 编码代码点序列(参见 6.1.4)。

调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? TrimString(S, end)。
Note

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移到其他对象类型使用。

22.1.3.34 String.prototype.trimStart ( )

该方法将字符串值视为 UTF-16 编码代码点序列(参见 6.1.4)。

调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? TrimString(S, start)。
Note

该方法特意设计为泛型;其 this 不要求为 String 对象,因此可转移到其他对象类型使用。

22.1.3.35 String.prototype.valueOf ( )

调用该方法时执行以下步骤:

  1. 返回 ? ThisStringValue(this value)。

22.1.3.35.1 ThisStringValue ( value )

The abstract operation ThisStringValue takes argument value (一个 ECMAScript 语言值) and returns 返回包含一个字符串的普通完成或抛出完成. It performs the following steps when called:

  1. value 是字符串,返回 value
  2. value 是对象且具有 [[StringData]] 内部槽,则
    1. svalue.[[StringData]]
    2. 断言:s 为字符串。
    3. 返回 s
  3. 抛出 TypeError 异常。

22.1.3.36 String.prototype [ %Symbol.iterator% ] ( )

该方法返回一个迭代器对象,该对象按字符串值的代码点进行迭代,并将每个代码点作为字符串值返回。

调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. s 为 ? ToString(O)。
  4. closure 为一个不带参数的新抽象闭包,捕获 s,调用时执行:
    1. lens 的长度。
    2. position 为 0。
    3. position < len 时重复,
      1. cp 为 CodePointAt(s, position)。
      2. nextIndexposition + cp.[[CodeUnitCount]]
      3. resultStrings 中从 positionnextIndex 的子串。
      4. position 设为 nextIndex
      5. 执行 ? GeneratorYield(CreateIteratorResultObject(resultString, false))。
    4. 返回 NormalCompletion(unused)。
  5. 返回 CreateIteratorFromClosure(closure, "%StringIteratorPrototype%", %StringIteratorPrototype%)。

该方法的 "name" 属性值为 "[Symbol.iterator]"

22.1.4 String 实例的属性

String 实例是 String 特异对象,并具有为此类对象指定的内部方法。String 实例从 String 原型对象继承属性。String 实例还具有 [[StringData]] 内部槽。[[StringData]] 内部槽是该 String 对象表示的字符串值。

String 实例有一个 "length" 属性,以及一组按整数索引命名的可枚举属性。

22.1.4.1 length

该 String 对象表示的字符串值中的元素数量。

一旦 String 对象初始化,该属性不再变化。其属性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

22.1.5 String 迭代器对象

String Iterator 是表示某个特定 String 实例对象上的一次特定迭代的对象。String Iterator 对象没有命名构造函数;相反,它们由调用某些 String 实例对象的方法创建。

22.1.5.1 %StringIteratorPrototype% 对象

%StringIteratorPrototype% 对象:

22.1.5.1.1 %StringIteratorPrototype%.next ( )

  1. 返回 ? GeneratorResume(this value, empty, "%StringIteratorPrototype%")。

22.1.5.1.2 %StringIteratorPrototype% [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串值 "String Iterator"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

22.2 RegExp(正则表达式)对象

RegExp 对象包含一个正则表达式以及其相关的标志(flags)。

Note

正则表达式的形式和功能参考 Perl 5 编程语言中的正则表达式机制。

22.2.1 模式(Patterns)

RegExp 构造函数对输入的模式字符串应用以下语法。如果该语法无法将该字符串解释为 Pattern 的展开,则会产生错误。

语法(Syntax)

Pattern[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Disjunction[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] | Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Alternative[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: [empty] Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Term[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Term[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Assertion[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Atom[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Atom[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Quantifier Assertion[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: ^ $ \b \B (?= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) Quantifier :: QuantifierPrefix QuantifierPrefix ? QuantifierPrefix :: * + ? { DecimalDigits[~Sep] } { DecimalDigits[~Sep] ,} { DecimalDigits[~Sep] , DecimalDigits[~Sep] } Atom[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: PatternCharacter . \ AtomEscape[?UnicodeMode, ?NamedCaptureGroups] CharacterClass[?UnicodeMode, ?UnicodeSetsMode] ( GroupSpecifier[?UnicodeMode]opt Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers : Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers - RegularExpressionModifiers : Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) RegularExpressionModifiers :: [empty] RegularExpressionModifiers RegularExpressionModifier RegularExpressionModifier :: one of i m s SyntaxCharacter :: one of ^ $ \ . * + ? ( ) [ ] { } | PatternCharacter :: SourceCharacter but not SyntaxCharacter AtomEscape[UnicodeMode, NamedCaptureGroups] :: DecimalEscape CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode] [+NamedCaptureGroups] k GroupName[?UnicodeMode] CharacterEscape[UnicodeMode] :: ControlEscape c AsciiLetter 0 [lookahead ∉ DecimalDigit] HexEscapeSequence RegExpUnicodeEscapeSequence[?UnicodeMode] IdentityEscape[?UnicodeMode] ControlEscape :: one of f n r t v GroupSpecifier[UnicodeMode] :: ? GroupName[?UnicodeMode] GroupName[UnicodeMode] :: < RegExpIdentifierName[?UnicodeMode] > RegExpIdentifierName[UnicodeMode] :: RegExpIdentifierStart[?UnicodeMode] RegExpIdentifierName[?UnicodeMode] RegExpIdentifierPart[?UnicodeMode] RegExpIdentifierStart[UnicodeMode] :: IdentifierStartChar \ RegExpUnicodeEscapeSequence[+UnicodeMode] [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpIdentifierPart[UnicodeMode] :: IdentifierPartChar \ RegExpUnicodeEscapeSequence[+UnicodeMode] [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpUnicodeEscapeSequence[UnicodeMode] :: [+UnicodeMode] u HexLeadSurrogate \u HexTrailSurrogate [+UnicodeMode] u HexLeadSurrogate [+UnicodeMode] u HexTrailSurrogate [+UnicodeMode] u HexNonSurrogate [~UnicodeMode] u Hex4Digits [+UnicodeMode] u{ CodePoint } UnicodeLeadSurrogate :: any Unicode code point in the inclusive interval from U+D800 to U+DBFF UnicodeTrailSurrogate :: any Unicode code point in the inclusive interval from U+DC00 to U+DFFF

对于每个 \u HexTrailSurrogate,若其关联的 u HexLeadSurrogate 的选择存在歧义,则应与最近的、否则将没有对应 \u HexTrailSurrogateu HexLeadSurrogate 关联。

HexLeadSurrogate :: Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xD800 to 0xDBFF HexTrailSurrogate :: Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xDC00 to 0xDFFF HexNonSurrogate :: Hex4Digits but only if the MV of Hex4Digits is not in the inclusive interval from 0xD800 to 0xDFFF IdentityEscape[UnicodeMode] :: [+UnicodeMode] SyntaxCharacter [+UnicodeMode] / [~UnicodeMode] SourceCharacter but not UnicodeIDContinue DecimalEscape :: NonZeroDigit DecimalDigits[~Sep]opt [lookahead ∉ DecimalDigit] CharacterClassEscape[UnicodeMode] :: d D s S w W [+UnicodeMode] p{ UnicodePropertyValueExpression } [+UnicodeMode] P{ UnicodePropertyValueExpression } UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue LoneUnicodePropertyNameOrValue UnicodePropertyName :: UnicodePropertyNameCharacters UnicodePropertyNameCharacters :: UnicodePropertyNameCharacter UnicodePropertyNameCharactersopt UnicodePropertyValue :: UnicodePropertyValueCharacters LoneUnicodePropertyNameOrValue :: UnicodePropertyValueCharacters UnicodePropertyValueCharacters :: UnicodePropertyValueCharacter UnicodePropertyValueCharactersopt UnicodePropertyValueCharacter :: UnicodePropertyNameCharacter DecimalDigit UnicodePropertyNameCharacter :: AsciiLetter _ CharacterClass[UnicodeMode, UnicodeSetsMode] :: [ [lookahead ≠ ^] ClassContents[?UnicodeMode, ?UnicodeSetsMode] ] [^ ClassContents[?UnicodeMode, ?UnicodeSetsMode] ] ClassContents[UnicodeMode, UnicodeSetsMode] :: [empty] [~UnicodeSetsMode] NonemptyClassRanges[?UnicodeMode] [+UnicodeSetsMode] ClassSetExpression NonemptyClassRanges[UnicodeMode] :: ClassAtom[?UnicodeMode] ClassAtom[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode] ClassAtom[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode] NonemptyClassRangesNoDash[UnicodeMode] :: ClassAtom[?UnicodeMode] ClassAtomNoDash[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode] ClassAtomNoDash[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode] ClassAtom[UnicodeMode] :: - ClassAtomNoDash[?UnicodeMode] ClassAtomNoDash[UnicodeMode] :: SourceCharacter but not one of \ or ] or - \ ClassEscape[?UnicodeMode] ClassEscape[UnicodeMode] :: b [+UnicodeMode] - CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode] ClassSetExpression :: ClassUnion ClassIntersection ClassSubtraction ClassUnion :: ClassSetRange ClassUnionopt ClassSetOperand ClassUnionopt ClassIntersection :: ClassSetOperand && [lookahead ≠ &] ClassSetOperand ClassIntersection && [lookahead ≠ &] ClassSetOperand ClassSubtraction :: ClassSetOperand -- ClassSetOperand ClassSubtraction -- ClassSetOperand ClassSetRange :: ClassSetCharacter - ClassSetCharacter ClassSetOperand :: NestedClass ClassStringDisjunction ClassSetCharacter NestedClass :: [ [lookahead ≠ ^] ClassContents[+UnicodeMode, +UnicodeSetsMode] ] [^ ClassContents[+UnicodeMode, +UnicodeSetsMode] ] \ CharacterClassEscape[+UnicodeMode] Note 1

此处前两行等价于 CharacterClass。

ClassStringDisjunction :: \q{ ClassStringDisjunctionContents } ClassStringDisjunctionContents :: ClassString ClassString | ClassStringDisjunctionContents ClassString :: [empty] NonEmptyClassString NonEmptyClassString :: ClassSetCharacter NonEmptyClassStringopt ClassSetCharacter :: [lookahead ∉ ClassSetReservedDoublePunctuator] SourceCharacter but not ClassSetSyntaxCharacter \ CharacterEscape[+UnicodeMode] \ ClassSetReservedPunctuator \b ClassSetReservedDoublePunctuator :: one of && !! ## $$ %% ** ++ ,, .. :: ;; << == >> ?? @@ ^^ `` ~~ ClassSetSyntaxCharacter :: one of ( ) [ ] { } / - \ | ClassSetReservedPunctuator :: one of & - ! # % , : ; < = > @ ` ~ Note 2

本节中的若干产生式在 B.1.2 中给出了替代定义。

22.2.1.1 静态语义:早期错误(Early Errors)

Note

本节在 B.1.2.1 中有补充。

Pattern :: Disjunction
  • 若 CountLeftCapturingParensWithin(Pattern) ≥ 232 - 1,则为语法错误(Syntax Error)。
  • Pattern 含有两个不同的 GroupSpecifier xy,使得 x 的 CapturingGroupName 与 y 的 CapturingGroupName 相同,且 MightBothParticipate(x, y) 为 true,则为语法错误。
QuantifierPrefix :: { DecimalDigits , DecimalDigits } Atom :: (? RegularExpressionModifiers : Disjunction ) Atom :: (? RegularExpressionModifiers - RegularExpressionModifiers : Disjunction ) AtomEscape :: k GroupName
  • 若 GroupSpecifiersThatMatch(GroupName) 为空,则为语法错误。
AtomEscape :: DecimalEscape
  • DecimalEscape 的 CapturingGroupNumber 严格大于包含该 AtomEscapePattern 中 CountLeftCapturingParensWithin 的结果,则为语法错误。
NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents
  • 若第一个 ClassAtom 的 IsCharacterClass 为 true 或第二个 ClassAtom 的 IsCharacterClass 为 true,则为语法错误。
  • 若两者 IsCharacterClass 均为 false 且第一个 ClassAtom 的 CharacterValue 严格大于第二个 ClassAtom 的 CharacterValue,则为语法错误。
NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents
  • ClassAtomNoDash 的 IsCharacterClass 为 trueClassAtom 的 IsCharacterClass 为 true,则为语法错误。
  • 若二者 IsCharacterClass 均为 falseClassAtomNoDash 的 CharacterValue 严格大于 ClassAtom 的 CharacterValue,则为语法错误。
RegExpIdentifierStart :: \ RegExpUnicodeEscapeSequence RegExpIdentifierStart :: UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpIdentifierPart :: \ RegExpUnicodeEscapeSequence RegExpIdentifierPart :: UnicodeLeadSurrogate UnicodeTrailSurrogate UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue UnicodePropertyValueExpression :: LoneUnicodePropertyNameOrValue CharacterClassEscape :: P{ UnicodePropertyValueExpression } CharacterClass :: [^ ClassContents ]
  • 若该 ClassContents 的 MayContainStrings 为 true,则为语法错误。
NestedClass :: [^ ClassContents ]
  • 若该 ClassContents 的 MayContainStrings 为 true,则为语法错误。
ClassSetRange :: ClassSetCharacter - ClassSetCharacter

22.2.1.2 静态语义:CountLeftCapturingParensWithin ( node )

The abstract operation 静态语义:CountLeftCapturingParensWithin takes argument node (一个解析节点) and returns 非负整数. 返回 node 中左捕获括号(左捕获括号)的数量。左捕获括号是由产生式 Atom :: ( GroupSpecifieropt Disjunction ) 中的 ( 终结符匹配的任意 ( 模式字符。

Note

本节在 B.1.2.2 中有补充。

It performs the following steps when called:

  1. 断言:nodeRegExp 模式语法 中某个产生式实例。
  2. 返回 node 内包含的 Atom :: ( GroupSpecifieropt Disjunction ) 解析节点的数量。

22.2.1.3 静态语义:CountLeftCapturingParensBefore ( node )

The abstract operation 静态语义:CountLeftCapturingParensBefore takes argument node (一个解析节点) and returns 非负整数. 返回封闭模式中出现在 node 左侧的左捕获括号数量。

Note

本节在 B.1.2.2 中有补充。

It performs the following steps when called:

  1. 断言:nodeRegExp 模式语法 中某个产生式实例。
  2. pattern 为包含 nodePattern
  3. 返回 pattern 中所有 Atom :: ( GroupSpecifieropt Disjunction ) 解析节点里,出现在 node 之前或包含 node 的那些的数量。

22.2.1.4 静态语义:MightBothParticipate ( x, y )

The abstract operation 静态语义:MightBothParticipate takes arguments x (一个解析节点) and y (一个解析节点) and returns 布尔值. It performs the following steps when called:

  1. 断言:xy 具有相同的封闭 Pattern
  2. 若封闭 Pattern 中存在一个 Disjunction :: Alternative | Disjunction 解析节点,使得 x 位于该 Alternative 内而 y 位于其派生的 Disjunction 内,或 x 位于派生的 Disjunctiony 位于该 Alternative 内,则返回 false
  3. 返回 true

22.2.1.5 静态语义:CapturingGroupNumber

The syntax-directed operation 静态语义:CapturingGroupNumber takes no arguments and returns 正整数.

Note

本节在 B.1.2.1 中有补充。

It is defined piecewise over the following productions:

DecimalEscape :: NonZeroDigit
  1. 返回 NonZeroDigit 的 MV。
DecimalEscape :: NonZeroDigit DecimalDigits
  1. nDecimalDigits 中代码点数量。
  2. 返回 (NonZeroDigit 的 MV × 10n 加上 DecimalDigits 的 MV)。

NonZeroDigit 的 MV” 与 “DecimalDigits 的 MV” 的定义见 12.9.3

22.2.1.6 静态语义:IsCharacterClass

The syntax-directed operation 静态语义:IsCharacterClass takes no arguments and returns 布尔值.

Note

本节在 B.1.2.3 中有补充。

It is defined piecewise over the following productions:

ClassAtom :: - ClassAtomNoDash :: SourceCharacter but not one of \ or ] or - ClassEscape :: b - CharacterEscape
  1. 返回 false
ClassEscape :: CharacterClassEscape
  1. 返回 true

22.2.1.7 静态语义:CharacterValue

The syntax-directed operation 静态语义:CharacterValue takes no arguments and returns 非负整数.

Note 1

本节在 B.1.2.4 中有补充。

It is defined piecewise over the following productions:

ClassAtom :: -
  1. 返回 U+002D(连字号 HYPHEN-MINUS)的数值。
ClassAtomNoDash :: SourceCharacter but not one of \ or ] or -
  1. chSourceCharacter 匹配的代码点。
  2. 返回 ch 的数值。
ClassEscape :: b
  1. 返回 U+0008(BACKSPACE)的数值。
ClassEscape :: -
  1. 返回 U+002D(连字号 HYPHEN-MINUS)的数值。
CharacterEscape :: ControlEscape
  1. Table 65 返回对应数值。
Table 65: ControlEscape 代码点数值
ControlEscape 数值 代码点 Unicode 名称 符号
t 9 U+0009 CHARACTER TABULATION <HT>
n 10 U+000A LINE FEED (LF) <LF>
v 11 U+000B LINE TABULATION <VT>
f 12 U+000C FORM FEED (FF) <FF>
r 13 U+000D CARRIAGE RETURN (CR) <CR>
CharacterEscape :: c AsciiLetter
  1. chAsciiLetter 匹配的代码点。
  2. ich 的数值。
  3. 返回 i 除以 32 的余数。
CharacterEscape :: 0 [lookahead ∉ DecimalDigit]
  1. 返回 U+0000(NULL)的数值。
Note 2

\0 表示 <NUL> 字符,且后面不能跟十进制数字。

CharacterEscape :: HexEscapeSequence
  1. 返回 HexEscapeSequence 的 MV。
RegExpUnicodeEscapeSequence :: u HexLeadSurrogate \u HexTrailSurrogate
  1. leadHexLeadSurrogate 的 CharacterValue。
  2. trailHexTrailSurrogate 的 CharacterValue。
  3. cp 为 UTF16SurrogatePairToCodePoint(lead, trail)。
  4. 返回 cp 的数值。
RegExpUnicodeEscapeSequence :: u Hex4Digits
  1. 返回 Hex4Digits 的 MV。
RegExpUnicodeEscapeSequence :: u{ CodePoint }
  1. 返回 CodePoint 的 MV。
HexLeadSurrogate :: Hex4Digits HexTrailSurrogate :: Hex4Digits HexNonSurrogate :: Hex4Digits
  1. 返回 Hex4Digits 的 MV。
CharacterEscape :: IdentityEscape
  1. chIdentityEscape 匹配的代码点。
  2. 返回 ch 的数值。
ClassSetCharacter :: SourceCharacter but not ClassSetSyntaxCharacter
  1. chSourceCharacter 匹配的代码点。
  2. 返回 ch 的数值。
ClassSetCharacter :: \ ClassSetReservedPunctuator
  1. chClassSetReservedPunctuator 匹配的代码点。
  2. 返回 ch 的数值。
ClassSetCharacter :: \b
  1. 返回 U+0008(BACKSPACE)的数值。

22.2.1.8 静态语义:MayContainStrings

The syntax-directed operation 静态语义:MayContainStrings takes no arguments and returns 布尔值. It is defined piecewise over the following productions:

CharacterClassEscape :: d D s S w W P{ UnicodePropertyValueExpression } UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue NestedClass :: [^ ClassContents ] ClassContents :: [empty] NonemptyClassRanges ClassSetOperand :: ClassSetCharacter
  1. 返回 false
UnicodePropertyValueExpression :: LoneUnicodePropertyNameOrValue
  1. LoneUnicodePropertyNameOrValue 匹配的源文本是 Table 69 “Property name” 列中列出的字符串二进制属性,则返回 true
  2. 返回 false
ClassUnion :: ClassSetRange ClassUnionopt
  1. ClassUnion 存在,返回该 ClassUnion 的 MayContainStrings。
  2. 返回 false
ClassUnion :: ClassSetOperand ClassUnionopt
  1. 若该 ClassSetOperand 的 MayContainStrings 为 true,返回 true
  2. ClassUnion 存在,返回该 ClassUnion 的 MayContainStrings。
  3. 返回 false
ClassIntersection :: ClassSetOperand && ClassSetOperand
  1. 若第一个 ClassSetOperand 的 MayContainStrings 为 false,返回 false
  2. 若第二个 ClassSetOperand 的 MayContainStrings 为 false,返回 false
  3. 返回 true
ClassIntersection :: ClassIntersection && ClassSetOperand
  1. 若该 ClassIntersection 的 MayContainStrings 为 false,返回 false
  2. 若该 ClassSetOperand 的 MayContainStrings 为 false,返回 false
  3. 返回 true
ClassSubtraction :: ClassSetOperand -- ClassSetOperand
  1. 返回第一个 ClassSetOperand 的 MayContainStrings。
ClassSubtraction :: ClassSubtraction -- ClassSetOperand
  1. 返回该 ClassSubtraction 的 MayContainStrings。
ClassStringDisjunctionContents :: ClassString | ClassStringDisjunctionContents
  1. 若该 ClassString 的 MayContainStrings 为 true,返回 true
  2. 返回该 ClassStringDisjunctionContents 的 MayContainStrings。
ClassString :: [empty]
  1. 返回 true
ClassString :: NonEmptyClassString
  1. 返回该 NonEmptyClassString 的 MayContainStrings。
NonEmptyClassString :: ClassSetCharacter NonEmptyClassStringopt
  1. NonEmptyClassString 存在,返回 true
  2. 返回 false

22.2.1.9 静态语义:GroupSpecifiersThatMatch ( thisGroupName )

The abstract operation 静态语义:GroupSpecifiersThatMatch takes argument thisGroupName (一个 GroupName 解析节点) and returns GroupSpecifier 解析节点的列表. It performs the following steps when called:

  1. namethisGroupName 的 CapturingGroupName。
  2. pattern 为包含 thisGroupNamePattern
  3. result 为新的空列表。
  4. pattern 中的每个 GroupSpecifier gs,执行
    1. gs 的 CapturingGroupName 为 name,则
      1. gs 追加至 result
  5. 返回 result

22.2.1.10 静态语义:CapturingGroupName

The syntax-directed operation 静态语义:CapturingGroupName takes no arguments and returns 字符串. It is defined piecewise over the following productions:

GroupName :: < RegExpIdentifierName >
  1. idTextUnescapedRegExpIdentifierName 的 RegExpIdentifierCodePoints。
  2. 返回 CodePointsToString(idTextUnescaped)。

22.2.1.11 静态语义:RegExpIdentifierCodePoints

The syntax-directed operation 静态语义:RegExpIdentifierCodePoints takes no arguments and returns 代码点列表. It is defined piecewise over the following productions:

RegExpIdentifierName :: RegExpIdentifierStart
  1. cpRegExpIdentifierStart 的 RegExpIdentifierCodePoint。
  2. 返回 « cp »。
RegExpIdentifierName :: RegExpIdentifierName RegExpIdentifierPart
  1. cps 为派生的 RegExpIdentifierName 的 RegExpIdentifierCodePoints。
  2. cpRegExpIdentifierPart 的 RegExpIdentifierCodePoint。
  3. 返回 cps 与 « cp » 的列表拼接

22.2.1.12 静态语义:RegExpIdentifierCodePoint

The syntax-directed operation 静态语义:RegExpIdentifierCodePoint takes no arguments and returns 代码点. It is defined piecewise over the following productions:

RegExpIdentifierStart :: IdentifierStartChar
  1. 返回 IdentifierStartChar 匹配的代码点。
RegExpIdentifierPart :: IdentifierPartChar
  1. 返回 IdentifierPartChar 匹配的代码点。
RegExpIdentifierStart :: \ RegExpUnicodeEscapeSequence RegExpIdentifierPart :: \ RegExpUnicodeEscapeSequence
  1. 返回其数值为 RegExpUnicodeEscapeSequence 的 CharacterValue 的代码点。
RegExpIdentifierStart :: UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpIdentifierPart :: UnicodeLeadSurrogate UnicodeTrailSurrogate
  1. lead 为数值等于 UnicodeLeadSurrogate 匹配代码点数值的代码单元。
  2. trail 为数值等于 UnicodeTrailSurrogate 匹配代码点数值的代码单元。
  3. 返回 UTF16SurrogatePairToCodePoint(lead, trail)。

22.2.2 模式语义(Pattern Semantics)

正则表达式模式通过下述过程被转换为一个抽象闭包(Abstract Closure)。实现被鼓励使用比下述更高效的算法,只要结果一致。该抽象闭包用作 RegExp 对象 [[RegExpMatcher]] 内部槽的值。

一个 Pattern 在其关联标志不包含 u 且不包含 v 时是一个 BMP 模式;否则是一个 Unicode 模式。BMP 模式针对被解释为由一系列 16 位值组成的字符串进行匹配,这些 16 位值是在基本多文种平面范围内的 Unicode 代码点。Unicode 模式针对被解释为由 UTF-16 编码的 Unicode 代码点组成的字符串进行匹配。在描述 BMP 模式行为的语境中,“character(字符)”指单个 16 位 Unicode BMP 代码点;在描述 Unicode 模式行为的语境中,“character” 指一个 UTF-16 编码的代码点(6.1.4)。在任一语境下,“character value(字符值)”指对应未编码代码点的数值。

Pattern 的语法与语义按如下方式定义:将 Pattern 的源文本视为 SourceCharacter 值的一个列表,其中每个 SourceCharacter 对应一个 Unicode 代码点。若一个 BMP 模式包含非 BMP 的 SourceCharacter,则整个模式使用 UTF-16 编码,该编码的各个代码单元作为该列表的元素。

Note

例如,考虑一个在源文本中表示为单个非 BMP 字符 U+1D11E(MUSICAL SYMBOL G CLEF)的模式。作为 Unicode 模式解释时,它将是一个只含该代码点 U+1D11E 的单元素(字符)列表。然而,作为 BMP 模式解释时,它首先被 UTF-16 编码,产生一个包含代码单元 0xD834 和 0xDD1E 的双元素列表。

模式以 ECMAScript 字符串值的形式传给 RegExp 构造函数,其中非 BMP 字符以 UTF-16 编码。例如,单字符 MUSICAL SYMBOL G CLEF 的模式,作为一个字符串值,是长度为 2 的字符串,其元素是代码单元 0xD834 与 0xDD1E。因此,将其作为由两个模式字符组成的 BMP 模式处理无需进一步转换;然而,要把它作为 Unicode 模式处理,必须使用 UTF16SurrogatePairToCodePoint 生成仅含一个模式字符(代码点 U+1D11E)的列表。

实现也许实际上不会执行这些到 UTF-16 之间的转换,但本规范语义要求匹配结果等效于执行了这些转换。

22.2.2.1 记号(Notation)

下述描述使用以下内部数据结构:

  • CharSetElement 是下列两种实体之一:
    • rer.[[UnicodeSets]]false,则 CharSetElement 是前述“模式语义”意义里的一个字符。
    • rer.[[UnicodeSets]]true,则 CharSetElement 是一个序列,其元素为前述“模式语义”意义里的字符。包含空序列、单字符序列以及多字符序列。为方便起见,处理此类 CharSetElement 时,单个字符与单字符序列可互换视之。
  • CharSet 是 CharSetElement 的数学集合。
  • CaptureRange 是一个记录 { [[StartIndex]], [[EndIndex]] },表示一次捕获中包含的字符范围;[[StartIndex]] 是表示范围在 Input 中起始索引(含)的整数,[[EndIndex]] 是表示范围在 Input 中结束索引(不含)的整数。任意 CaptureRange 必须满足 [[StartIndex]][[EndIndex]] 的不变量。
  • MatchState 是记录 { [[Input]], [[EndIndex]], [[Captures]] },其中 [[Input]] 是表示被匹配字符串的字符列表,[[EndIndex]] 是一个整数,[[Captures]] 是一个值列表,对应模式中每个左捕获括号MatchState 用于在正则表达式匹配算法中表示部分匹配状态。[[EndIndex]] 是当前模式已匹配的最后一个输入字符索引加 1;[[Captures]] 保存捕获括号的结果。[[Captures]] 的第 n 个元素要么是表示第 n 个捕获括号所捕获字符范围的 CaptureRange,要么在该捕获括号尚未到达时为 undefined。由于回溯,匹配过程中任意时刻可能存在多个 MatchState
  • MatcherContinuation 是一个抽象闭包,接收一个 MatchState 参数,返回一个 MatchStatefailure。该闭包尝试从其 MatchState 参数给出的中间状态起,将剩余(由闭包捕获的值指定)的模式部分与 Input 匹配。若匹配成功,返回达到的最终 MatchState;失败则返回 failure
  • Matcher 是一个抽象闭包,接收两个参数——一个 MatchState 和一个 MatcherContinuation——返回一个 MatchStatefailureMatcher 尝试从其 MatchState 参数给出的中间状态起,将模式的一个中间子模式(由闭包捕获值指定)与该 MatchState[[Input]] 匹配。MatcherContinuation 参数应为匹配剩余模式的闭包。匹配子模式得到新的 MatchState 后,Matcher 调用 MatcherContinuation 测试剩余模式是否也能匹配。若可以,返回该 MatcherContinuation 返回的 MatchState;否则 Matcher 可以在其选择点尝试不同选择,不断调用 MatcherContinuation,直到成功或所有可能性耗尽。

22.2.2.1.1 RegExp 记录(RegExp Records)

RegExp 记录 是一个记录值,用于存储编译(并可能在匹配)过程中需要的 RegExp 信息。

其具有以下字段:

Table 66: RegExp 记录字段
字段名 含义
[[IgnoreCase]] 一个布尔值 指示 "i" 是否出现在该 RegExp 的标志中
[[Multiline]] 一个布尔值 指示 "m" 是否出现在标志中
[[DotAll]] 一个布尔值 指示 "s" 是否出现在标志中
[[Unicode]] 一个布尔值 指示 "u" 是否出现在标志中
[[UnicodeSets]] 一个布尔值 指示 "v" 是否出现在标志中
[[CapturingGroupsCount]] 非负整数 该 RegExp 模式中的左捕获括号数量

22.2.2.2 运行时语义:CompilePattern

The syntax-directed operation 运行时语义:CompilePattern takes argument rer (一个 RegExp 记录) and returns 一个抽象闭包,接收一个字符列表与一个非负整数,返回 MatchStatefailure. It is defined piecewise over the following productions:

Pattern :: Disjunction
  1. mDisjunction 的 CompileSubpattern,参数为 rerforward
  2. 返回一个新的抽象闭包,具参数 (Input, index),捕获 rerm,被调用时执行:
    1. 断言:Input 是字符列表。
    2. 断言:0 ≤ indexInput 元素数量。
    3. c 为新的 MatcherContinuation,参数 (y),捕获无,其执行:
      1. 断言:yMatchState
      2. 返回 y
    4. cap 为一个长度为 rer.[[CapturingGroupsCount]] 的列表,索引 1..rer.[[CapturingGroupsCount]],初值皆为 undefined
    5. xMatchState { [[Input]]: Input, [[EndIndex]]: index, [[Captures]]: cap }。
    6. 返回 m(x, c)。
Note

一个 Pattern 编译成抽象闭包值。随后 RegExpBuiltinExec 可将此过程应用于字符列表与其中的偏移量,以判断该模式是否在该偏移精确匹配,并在匹配时确定捕获括号的值。22.2.2 中的算法设计为:编译模式可能抛出 SyntaxError;另一方面,一旦成功编译,将所得抽象闭包应用于字符列表查找匹配时不会抛异常(除非出现诸如内存不足的实现定义异常)。

22.2.2.3 运行时语义:CompileSubpattern

The syntax-directed operation 运行时语义:CompileSubpattern takes arguments rer (一个 RegExp 记录) and direction (forwardbackward) and returns 一个 Matcher.

Note 1

本节在 B.1.2.5 中有补充。

It is defined piecewise over the following productions:

Disjunction :: Alternative | Disjunction
  1. m1Alternative 的 CompileSubpattern,参数 rerdirection
  2. m2Disjunction 的 CompileSubpattern,参数 rerdirection
  3. 返回 MatchTwoAlternatives(m1, m2)。
Note 2

| 运算符分隔两个候选。模式先尝试匹配左侧 Alternative(后接正则表达式余部);若失败,再尝试右侧 Disjunction(后接余部)。若左 Alternative、右 Disjunction 及余部均有选择点,则在转向左 Alternative 的下一个选择之前,会先穷尽余部的所有选择;在穷尽左 Alternative 的所有选择后,才改试右 Disjunction。被 | 跳过的部分中的捕获括号产生 undefined 而不是字符串。例如:

/a|ab/.exec("abc")

返回 "a" 而非 "ab"。并且,

/((a)|(ab))((c)|(bc))/.exec("abc")

返回数组

["abc", "a", "a", undefined, "bc", undefined, "bc"]

而非

["abc", "ab", undefined, "ab", "c", "c", undefined]

两候选的尝试顺序与 direction 的值无关。

Alternative :: [empty]
  1. 返回 EmptyMatcher()。
Alternative :: Alternative Term
  1. m1Alternative 的 CompileSubpattern,参数 rerdirection
  2. m2Term 的 CompileSubpattern,参数 rerdirection
  3. 返回 MatchSequence(m1, m2, direction)。
Note 3

相邻的 Term 会尝试同时匹配 Input 的相邻片段。当 directionforward 时,若左 Alternative、右 Term 和余部存在选择点,则在进入右 Term 的下一个选择前会先穷尽余部所有选择,在进入左 Alternative 的下一个选择前会先穷尽右 Term 的所有选择;当 directionbackward 时,AlternativeTerm 的求值顺序反转。

Term :: Assertion
  1. 返回 Assertion 的 CompileAssertion,参数 rer
Note 4

结果 Matcherdirection 无关。

Term :: Atom
  1. 返回 Atom 的 CompileAtom,参数 rerdirection
Term :: Atom Quantifier
  1. mAtom 的 CompileAtom,参数 rerdirection
  2. qQuantifier 的 CompileQuantifier。
  3. 断言:q.[[Min]]q.[[Max]]
  4. parenIndex 为 CountLeftCapturingParensBefore(Term)。
  5. parenCount 为 CountLeftCapturingParensWithin(Atom)。
  6. 返回新的 Matcher,参数 (x, c),捕获 mqparenIndexparenCount,其执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. 返回 RepeatMatcher(m, q.[[Min]], q.[[Max]], q.[[Greedy]], x, c, parenIndex, parenCount)。

22.2.2.3.1 RepeatMatcher ( m, min, max, greedy, x, c, parenIndex, parenCount )

The abstract operation RepeatMatcher takes arguments m (一个 Matcher), min (非负整数), max (非负整数或 +∞), greedy (布尔值), x (MatchState), c (MatcherContinuation), parenIndex (非负整数), and parenCount (非负整数) and returns MatchStatefailure. It performs the following steps when called:

  1. max = 0,返回 c(x)。
  2. d 为新的 MatcherContinuation,参数 (y),捕获 mminmaxgreedyxcparenIndexparenCount,其执行:
    1. 断言:yMatchState
    2. min = 0 且 y.[[EndIndex]] = x.[[EndIndex]],返回 failure
    3. min = 0,令 min2 为 0;否则令 min2min - 1。
    4. max = +∞,令 max2 为 +∞;否则令 max2max - 1。
    5. 返回 RepeatMatcher(m, min2, max2, greedy, y, c, parenIndex, parenCount)。
  3. capx.[[Captures]] 的拷贝。
  4. 区间 parenIndex + 1 至 parenIndex + parenCount(含)内每个整数 k,设 cap[k] 为 undefined
  5. Inputx.[[Input]]
  6. ex.[[EndIndex]]
  7. xrMatchState { [[Input]]: Input, [[EndIndex]]: e, [[Captures]]: cap }。
  8. min ≠ 0,返回 m(xr, d)。
  9. greedyfalse,则
    1. zc(x)。
    2. z 不为 failure,返回 z
    3. 返回 m(xr, d)。
  10. zm(xr, d)。
  11. z 不为 failure,返回 z
  12. 返回 c(x)。
Note 1

Atom 后随 Quantifier 会按 Quantifier 指定的次数重复。Quantifier 可为非贪婪,此时 Atom 尽可能少重复仍满足余部匹配;或为贪婪,此时尽可能多重复仍满足余部匹配。重复的是 Atom 模式本身,而非其已匹配的输入字符序列,因此不同重复可匹配不同子串。

Note 2

Atom 与余部均有选择点,Atom 首先按尽可能多(或在非贪婪时尽可能少)重复。会在进入 Atom 最后一次重复的下一选择前穷尽余部选择;在进入倒数第二次重复的下一选择前穷尽最后一次重复的所有选择;此时可能出现允许更多或更少重复的情况,再次(按多或少的策略)穷尽后再进入倒数第二次重复的下一选择,依此类推。

比较:

/a[a-z]{2,4}/.exec("abcdefghi")

返回 "abcde"

/a[a-z]{2,4}?/.exec("abcdefghi")

返回 "abc"

再考虑:

/(aa|aabaac|ba|b|c)*/.exec("aabaac")

依据上述选择点顺序返回数组

["aaba", "ba"]

而不是:

["aabaac", "aabaac"]
["aabaac", "c"]

上述选择点次序可用来编写计算两个一元表示数的最大公约数的正则。以下示例计算 10 与 15 的 gcd:

"aaaaaaaaaa,aaaaaaaaaaaaaaa".replace(/^(a+)\1*,\1+$/, "$1")

返回一元表示的 gcd "aaaaa"

Note 3

RepeatMatcher 的步骤 4 在每次重复 Atom 时清除其捕获。其行为可见于:

/(z)((a+)?(b+)?(c))*/.exec("zaacbbbcac")

返回数组

["zaacbbbcac", "z", "ac", "a", undefined, "c"]

而非

["zaacbbbcac", "z", "ac", "a", "bbb", "c"]

因为最外层 * 的每次迭代都会清除量词作用域内 Atom 的捕获(此例中为第 2、3、4、5 号捕获)。

Note 4

RepeatMatcher 的步骤 2.b 指出:一旦最小重复次数满足,任何再匹配空字符序列的 Atom 展开将不再考虑,防止在如下模式中无限循环:

/(a*)*/.exec("b")

或稍复杂的:

/(a*)b\1+/.exec("baaaac")

其返回数组

["b", ""]

22.2.2.3.2 EmptyMatcher ( )

The abstract operation EmptyMatcher takes no arguments and returns 一个 Matcher. It performs the following steps when called:

  1. 返回新的 Matcher,参数 (x, c),捕获无,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. 返回 c(x)。

22.2.2.3.3 MatchTwoAlternatives ( m1, m2 )

The abstract operation MatchTwoAlternatives takes arguments m1 (一个 Matcher) and m2 (一个 Matcher) and returns 一个 Matcher. It performs the following steps when called:

  1. 返回新的 Matcher,参数 (x, c),捕获 m1m2,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. rm1(x, c)。
    4. r 不为 failure,返回 r
    5. 返回 m2(x, c)。

22.2.2.3.4 MatchSequence ( m1, m2, direction )

The abstract operation MatchSequence takes arguments m1 (一个 Matcher), m2 (一个 Matcher), and direction (forwardbackward) and returns 一个 Matcher. It performs the following steps when called:

  1. directionforward,则
    1. 返回新的 Matcher,参数 (x, c),捕获 m1m2,执行:
      1. 断言:xMatchState
      2. 断言:cMatcherContinuation
      3. d 为新的 MatcherContinuation,参数 (y),捕获 cm2,执行:
        1. 断言:yMatchState
        2. 返回 m2(y, c)。
      4. 返回 m1(x, d)。
  2. 否则,
    1. 断言:directionbackward
    2. 返回新的 Matcher,参数 (x, c),捕获 m1m2,执行:
      1. 断言:xMatchState
      2. 断言:cMatcherContinuation
      3. d 为新的 MatcherContinuation,参数 (y),捕获 cm1,执行:
        1. 断言:yMatchState
        2. 返回 m1(y, c)。
      4. 返回 m2(x, d)。

22.2.2.4 运行时语义:CompileAssertion

The syntax-directed operation 运行时语义:CompileAssertion takes argument rer (一个 RegExp 记录) and returns 一个 Matcher.

Note 1

本节在 B.1.2.6 中有补充。

It is defined piecewise over the following productions:

Assertion :: ^
  1. 返回新的 Matcher,参数 (x, c),捕获 rer,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. Inputx.[[Input]]
    4. ex.[[EndIndex]]
    5. e = 0,或 (rer.[[Multiline]]true 且字符 Input[e - 1] 被 LineTerminator 匹配),则
      1. 返回 c(x)。
    6. 返回 failure
Note 2

即使使用 y 标志,^ 也只匹配 Input 的开始,或(若 rer.[[Multiline]]true)行首。

Assertion :: $
  1. 返回新的 Matcher,参数 (x, c),捕获 rer,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. Inputx.[[Input]]
    4. ex.[[EndIndex]]
    5. InputLengthInput 元素数量。
    6. e = InputLength,或 (rer.[[Multiline]]true 且字符 Input[e] 被 LineTerminator 匹配),
      1. 返回 c(x)。
    7. 返回 failure
Assertion :: \b
  1. 返回新的 Matcher,参数 (x, c),捕获 rer,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. Inputx.[[Input]]
    4. ex.[[EndIndex]]
    5. aIsWordChar(rer, Input, e - 1)。
    6. bIsWordChar(rer, Input, e)。
    7. 若 (atruebfalse) 或 (afalsebtrue),返回 c(x)。
    8. 返回 failure
Assertion :: \B
  1. 返回新的 Matcher,参数 (x, c),捕获 rer,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. Inputx.[[Input]]
    4. ex.[[EndIndex]]
    5. aIsWordChar(rer, Input, e - 1)。
    6. bIsWordChar(rer, Input, e)。
    7. 若 (atruebtrue) 或 (afalsebfalse),返回 c(x)。
    8. 返回 failure
Assertion :: (?= Disjunction )
  1. mDisjunction 的 CompileSubpattern,参数 rerforward
  2. 返回新的 Matcher,参数 (x, c),捕获 m,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. d 为新的 MatcherContinuation,参数 (y),捕获无,执行:
      1. 断言:yMatchState
      2. 返回 y
    4. rm(x, d)。
    5. rfailure,返回 failure
    6. 断言:rMatchState
    7. capr.[[Captures]]
    8. Inputx.[[Input]]
    9. xex.[[EndIndex]]
    10. zMatchState { [[Input]]: Input, [[EndIndex]]: xe, [[Captures]]: cap }。
    11. 返回 c(z)。
Note 3

(?= Disjunction ) 是零宽正向先行断言。其成功要求 Disjunction 在当前位置匹配,但当前位置在匹配余部前不前进。若 Disjunction 在当前位置可多种方式匹配,仅尝试第一种。与其他正则运算不同,不会对 (?= 形式进行回溯(此异常行为源自 Perl)。仅当 Disjunction 含捕获括号且余部含对其的反向引用时此行为才重要。

例如:

/(?=(a+))/.exec("baaabac")

在首个 b 之后的空字符串处匹配,返回:

["", "aaa"]

为说明缺少回溯,考虑:

/(?=(a+))a*b\1/.exec("baaabac")

该表达式返回

["aba", "a"]

而非:

["aaaba", "a"]
Assertion :: (?! Disjunction )
  1. mDisjunction 的 CompileSubpattern,参数 rerforward
  2. 返回新的 Matcher,参数 (x, c),捕获 m,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. d 为新的 MatcherContinuation,参数 (y),捕获无,执行:
      1. 断言:yMatchState
      2. 返回 y
    4. rm(x, d)。
    5. r 不为 failure,返回 failure
    6. 返回 c(x)。
Note 4

(?! Disjunction ) 是零宽负向先行断言。其成功要求 Disjunction 在当前位置匹配失败。当前位置在匹配余部前不前进。Disjunction 可含捕获括号,但对它们的反向引用仅在 Disjunction 内有意义;模式其它位置引用这些捕获总是返回 undefined,因为负向先行必须失败整个模式才成功。例如:

/(.*?)a(?!(a+)b\2c)\2(.*)/.exec("baaabaac")

寻找一个 a,其后不紧跟着若干(正数 n)个 a、一个 b、再 n 个 a(由第一个 \2 指定)以及一个 c。第二个 \2 在负向先行外,匹配 undefined 因而总成功。整体返回数组:

["baaabaac", "ba", undefined, "abaac"]
Assertion :: (?<= Disjunction )
  1. mDisjunction 的 CompileSubpattern,参数 rerbackward
  2. 返回新的 Matcher,参数 (x, c),捕获 m,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. d 为新的 MatcherContinuation,参数 (y),捕获无,执行:
      1. 断言:yMatchState
      2. 返回 y
    4. rm(x, d)。
    5. rfailure,返回 failure
    6. 断言:rMatchState
    7. capr.[[Captures]]
    8. Inputx.[[Input]]
    9. xex.[[EndIndex]]
    10. zMatchState { [[Input]]: Input, [[EndIndex]]: xe, [[Captures]]: cap }。
    11. 返回 c(z)。
Assertion :: (?<! Disjunction )
  1. mDisjunction 的 CompileSubpattern,参数 rerbackward
  2. 返回新的 Matcher,参数 (x, c),捕获 m,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. d 为新的 MatcherContinuation,参数 (y),捕获无,执行:
      1. 断言:yMatchState
      2. 返回 y
    4. rm(x, d)。
    5. r 不为 failure,返回 failure
    6. 返回 c(x)。

22.2.2.4.1 IsWordChar ( rer, Input, e )

The abstract operation IsWordChar takes arguments rer (一个 RegExp 记录), Input (字符列表), and e (整数) and returns 布尔值. It performs the following steps when called:

  1. InputLengthInput 元素数量。
  2. e = -1 或 e = InputLength,返回 false
  3. c 为字符 Input[e]。
  4. WordCharacters(rer) 包含 c,返回 true
  5. 返回 false

22.2.2.5 运行时语义:CompileQuantifier

The syntax-directed operation 运行时语义:CompileQuantifier takes no arguments and returns 一个记录,字段 [[Min]](非负整数)、[[Max]](非负整数或 +∞)、[[Greedy]](布尔值). It is defined piecewise over the following productions:

Quantifier :: QuantifierPrefix
  1. qpQuantifierPrefix 的 CompileQuantifierPrefix。
  2. 返回记录 { [[Min]]: qp.[[Min]], [[Max]]: qp.[[Max]], [[Greedy]]: true }。
Quantifier :: QuantifierPrefix ?
  1. qpQuantifierPrefix 的 CompileQuantifierPrefix。
  2. 返回记录 { [[Min]]: qp.[[Min]], [[Max]]: qp.[[Max]], [[Greedy]]: false }。

22.2.2.6 运行时语义:CompileQuantifierPrefix

The syntax-directed operation 运行时语义:CompileQuantifierPrefix takes no arguments and returns 记录,字段 [[Min]](非负整数)与 [[Max]](非负整数或 +∞). It is defined piecewise over the following productions:

QuantifierPrefix :: *
  1. 返回记录 { [[Min]]: 0, [[Max]]: +∞ }。
QuantifierPrefix :: +
  1. 返回记录 { [[Min]]: 1, [[Max]]: +∞ }。
QuantifierPrefix :: ?
  1. 返回记录 { [[Min]]: 0, [[Max]]: 1 }。
QuantifierPrefix :: { DecimalDigits }
  1. iDecimalDigits 的 MV(参见 12.9.3)。
  2. 返回记录 { [[Min]]: i, [[Max]]: i }。
QuantifierPrefix :: { DecimalDigits ,}
  1. iDecimalDigits 的 MV。
  2. 返回记录 { [[Min]]: i, [[Max]]: +∞ }。
QuantifierPrefix :: { DecimalDigits , DecimalDigits }
  1. i 为第一组 DecimalDigits 的 MV。
  2. j 为第二组 DecimalDigits 的 MV。
  3. 返回记录 { [[Min]]: i, [[Max]]: j }。

22.2.2.7 运行时语义:CompileAtom

The syntax-directed operation 运行时语义:CompileAtom takes arguments rer (一个 RegExp 记录) and direction (forwardbackward) and returns 一个 Matcher.

Note 1

本节在 B.1.2.7 中有补充。

It is defined piecewise over the following productions:

Atom :: PatternCharacter
  1. chPatternCharacter 匹配的字符。
  2. A 为包含字符 ch 的单元素 CharSet
  3. 返回 CharacterSetMatcher(rer, A, false, direction)。
Atom :: .
  1. AAllCharacters(rer)。
  2. rer.[[DotAll]] 不为 true,则
    1. A 中移除所有对应 LineTerminator 产生式右侧代码点的字符。
  3. 返回 CharacterSetMatcher(rer, A, false, direction)。
Atom :: CharacterClass
  1. ccCharacterClass 的 CompileCharacterClass,参数 rer
  2. cscc.[[CharSet]]
  3. rer.[[UnicodeSets]]false,或 cs 的每个 CharSetElement 都是单字符(包括 cs 为空),返回 CharacterSetMatcher(rer, cs, cc.[[Invert]], direction)。
  4. 断言:cc.[[Invert]]false
  5. lm 为空的 Matcher 列表。
  6. cs 中每个包含超过 1 个字符的 CharSetElement s(按长度降序):
    1. cs2 为仅含 s 最后代码点的单元素 CharSet
    2. m2CharacterSetMatcher(rer, cs2, false, direction)。
    3. s 中每个代码点 c1(从倒数第二个向前迭代):
      1. cs1 为仅含 c1 的单元素 CharSet
      2. m1CharacterSetMatcher(rer, cs1, false, direction)。
      3. m2MatchSequence(m1, m2, direction)。
    4. m2 追加入 lm
  7. singles 为包含 cs 中所有单字符 CharSetElementCharSet
  8. CharacterSetMatcher(rer, singles, false, direction) 追加入 lm
  9. cs 含空字符序列,将 EmptyMatcher() 追加入 lm
  10. m2lm 中最后一个 Matcher
  11. lm 中每个 Matcher m1(自倒数第二个向前):
    1. m2MatchTwoAlternatives(m1, m2)。
  12. 返回 m2
Atom :: ( GroupSpecifieropt Disjunction )
  1. mDisjunction 的 CompileSubpattern,参数 rerdirection
  2. parenIndex 为 CountLeftCapturingParensBefore(Atom)。
  3. 返回新 Matcher,参数 (x, c),捕获 directionmparenIndex,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. d 为新的 MatcherContinuation,参数 (y),捕获 xcdirectionparenIndex,执行:
      1. 断言:yMatchState
      2. capy.[[Captures]] 的拷贝。
      3. Inputx.[[Input]]
      4. xex.[[EndIndex]]
      5. yey.[[EndIndex]]
      6. directionforward,则
        1. 断言:xeye
        2. rCaptureRange { [[StartIndex]]: xe, [[EndIndex]]: ye }。
      7. 否则,
        1. 断言:directionbackward
        2. 断言:yexe
        3. rCaptureRange { [[StartIndex]]: ye, [[EndIndex]]: xe }。
      8. cap[parenIndex + 1] = r
      9. zMatchState { [[Input]]: Input, [[EndIndex]]: ye, [[Captures]]: cap }。
      10. 返回 c(z)。
    4. 返回 m(x, d)。
Note 2

( Disjunction ) 形式的括号既分组 Disjunction 的组件,又保存匹配结果。该结果可用于反向引用(\ 加非零十进制数)、替换字符串引用,或作为正则匹配抽象闭包返回数组的一部分。若要禁止捕获行为,使用 (?: Disjunction )

Atom :: (? RegularExpressionModifiers : Disjunction )
  1. addModifiersRegularExpressionModifiers 匹配的源文本。
  2. removeModifiers 为空字符串。
  3. modifiedRerUpdateModifiers(rer, CodePointsToString(addModifiers), removeModifiers)。
  4. 返回 Disjunction 的 CompileSubpattern,参数 modifiedRerdirection
Atom :: (? RegularExpressionModifiers - RegularExpressionModifiers : Disjunction )
  1. addModifiers 为第一个 RegularExpressionModifiers 匹配的源文本。
  2. removeModifiers 为第二个 RegularExpressionModifiers 匹配的源文本。
  3. modifiedRerUpdateModifiers(rer, CodePointsToString(addModifiers), CodePointsToString(removeModifiers))。
  4. 返回 Disjunction 的 CompileSubpattern,参数 modifiedRerdirection
AtomEscape :: DecimalEscape
  1. nDecimalEscape 的 CapturingGroupNumber。
  2. 断言:nrer.[[CapturingGroupsCount]]
  3. 返回 BackreferenceMatcher(rer, « n », direction)。
Note 3

\ 后随非零十进制数字 n 的转义序列匹配第 n 组捕获括号的结果(22.2.2.1)。若模式捕获括号少于 n 则错误。若第 n 组存在但为 undefined(未捕获任何内容),该反向引用总是成功。

AtomEscape :: CharacterEscape
  1. cvCharacterEscape 的 CharacterValue。
  2. ch 为字符值为 cv 的字符。
  3. A 为包含 ch 的单元素 CharSet
    1. 返回 CharacterSetMatcher(rer, A, false, direction)。
AtomEscape :: CharacterClassEscape
  1. csCharacterClassEscape 的 CompileToCharSet,参数 rer
  2. rer.[[UnicodeSets]]false,或 cs 的每个 CharSetElement 都是单字符(含空),返回 CharacterSetMatcher(rer, cs, false, direction)。
  3. lm 为空 Matcher 列表。
  4. cs 中每个含多于 1 字符的 CharSetElement s(按长度降序):
    1. cs2 为仅含 s 最后代码点的单元素 CharSet
    2. m2CharacterSetMatcher(rer, cs2, false, direction)。
    3. s 中每个代码点 c1(自倒数第二个向前):
      1. cs1 为仅含 c1CharSet
      2. m1CharacterSetMatcher(rer, cs1, false, direction)。
      3. m2MatchSequence(m1, m2, direction)。
    4. m2 追加入 lm
  5. singles 为包含 cs 中所有单字符元素的 CharSet
  6. CharacterSetMatcher(rer, singles, false, direction) 追加入 lm
  7. cs 含空序列,将 EmptyMatcher() 追加入 lm
  8. m2lm 最末 Matcher
  9. lm 中每个 m1(自倒数第二向前):
    1. m2MatchTwoAlternatives(m1, m2)。
  10. 返回 m2
AtomEscape :: k GroupName
  1. matchingGroupSpecifiers 为 GroupSpecifiersThatMatch(GroupName)。
  2. parenIndices 为新空列表。
  3. matchingGroupSpecifiers 中每个 GroupSpecifier groupSpecifier
    1. parenIndex 为 CountLeftCapturingParensBefore(groupSpecifier)。
    2. parenIndex 追加入 parenIndices
  4. 返回 BackreferenceMatcher(rer, parenIndices, direction)。

22.2.2.7.1 CharacterSetMatcher ( rer, A, invert, direction )

The abstract operation CharacterSetMatcher takes arguments rer (一个 RegExp 记录), A (一个 CharSet), invert (布尔值), and direction (forwardbackward) and returns 一个 Matcher. It performs the following steps when called:

  1. rer.[[UnicodeSets]]true,则
    1. 断言:invertfalse
    2. 断言:A 的每个 CharSetElement 皆为单字符。
  2. 返回新的 Matcher,参数 (x, c),捕获 rerAinvertdirection,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. Inputx.[[Input]]
    4. ex.[[EndIndex]]
    5. directionforward,令 f = e + 1。
    6. 否则令 f = e - 1。
    7. InputLengthInput 元素数量。
    8. f < 0 或 f > InputLength,返回 failure
    9. index = min(e, f)。
    10. ch 为字符 Input[index]。
    11. cc = Canonicalize(rer, ch)。
    12. 若存在 A 中某 CharSetElement 含恰一字符 aCanonicalize(rer, a) = cc,令 found = true;否则 found = false
    13. invert = falsefound = false,返回 failure
    14. invert = truefound = true,返回 failure
    15. capx.[[Captures]]
    16. yMatchState { [[Input]]: Input, [[EndIndex]]: f, [[Captures]]: cap }。
    17. 返回 c(y)。

22.2.2.7.2 BackreferenceMatcher ( rer, ns, direction )

The abstract operation BackreferenceMatcher takes arguments rer (一个 RegExp 记录), ns (正整数列表), and direction (forwardbackward) and returns 一个 Matcher. It performs the following steps when called:

  1. 返回新的 Matcher,参数 (x, c),捕获 rernsdirection,执行:
    1. 断言:xMatchState
    2. 断言:cMatcherContinuation
    3. Inputx.[[Input]]
    4. capx.[[Captures]]
    5. rundefined
    6. ns 中每个整数 n
      1. cap[n] 不为 undefined,则
        1. 断言:rundefined
        2. r = cap[n]。
    7. rundefined,返回 c(x)。
    8. ex.[[EndIndex]]
    9. rsr.[[StartIndex]]
    10. rer.[[EndIndex]]
    11. len = re - rs
    12. directionforward,令 f = e + len;否则 f = e - len
    13. InputLengthInput 元素数量。
    14. f < 0 或 f > InputLength,返回 failure
    15. g = min(e, f)。
    16. 若存在区间 [0, len) 内整数 i 使 Canonicalize(rer, Input[rs + i]) ≠ Canonicalize(rer, Input[g + i]),返回 failure
    17. yMatchState { [[Input]]: Input, [[EndIndex]]: f, [[Captures]]: cap }。
    18. 返回 c(y)。

22.2.2.7.3 Canonicalize ( rer, ch )

The abstract operation Canonicalize takes arguments rer (一个 RegExp 记录) and ch (一个字符) and returns 一个字符. It performs the following steps when called:

  1. HasEitherUnicodeFlag(rer) 为 truerer.[[IgnoreCase]]true,则
    1. 若 Unicode 字符数据库文件 CaseFolding.txtch 提供简单或常用大小写折叠映射,则返回应用该映射后的 ch
    2. 返回 ch
  2. rer.[[IgnoreCase]]false,返回 ch
  3. 断言:ch 是 UTF-16 代码单元。
  4. cp 为数值等于 ch 数值的代码点。
  5. u 为根据 Unicode 默认大小写转换算法 toUppercase(« cp ») 的结果。
  6. uStr 为 CodePointsToString(u)。
  7. uStr 长度 ≠ 1,返回 ch
  8. cuuStr 的单个代码单元。
  9. ch 数值 ≥ 128 且 cu 数值 < 128,返回 ch
  10. 返回 cu
Note

HasEitherUnicodeFlag(rer) 为 true 的不区分大小写匹配中,比较前所有字符按 Unicode 标准提供的 simple case folding 隐式折叠。该映射始终映射到单个代码点,不会将 ß 映射到 ss/SS。但可将非 Basic Latin 代码点映射到该块内,如 ſ 折叠到 s 折叠到 k。包含这些代码点的字符串可被 /[a-z]/ui 匹配。

HasEitherUnicodeFlag(rer) 为 false 的不区分大小写匹配中,使用的是 toUppercase 而非 toCasefold,有细微差别。例如 被 toUppercase 映射为自身,但 toCasefold 映射为 ω,与 Ω 一起;因此 "\u2126"/[ω]/ui/[\u03A9]/ui 匹配,却不被 /[ω]/i/[\u03A9]/i 匹配。且无 Basic Latin 外代码点映射进该块,所以 "\u017F ſ""\u212A K" 不被 /[a-z]/i 匹配。

22.2.2.7.4 UpdateModifiers ( rer, add, remove )

The abstract operation UpdateModifiers takes arguments rer (一个 RegExp 记录), add (字符串), and remove (字符串) and returns 一个 RegExp 记录. It performs the following steps when called:

  1. 断言:addremove 不含共同元素。
  2. ignoreCase = rer.[[IgnoreCase]]
  3. multiline = rer.[[Multiline]]
  4. dotAll = rer.[[DotAll]]
  5. unicode = rer.[[Unicode]]
  6. unicodeSets = rer.[[UnicodeSets]]
  7. capturingGroupsCount = rer.[[CapturingGroupsCount]]
  8. remove"i",设 ignoreCase = false;否则若 add"i",设其为 true
  9. remove"m",设 multiline = false;否则若 add"m",设其为 true
  10. remove"s",设 dotAll = false;否则若 add"s",设其为 true
  11. 返回 RegExp 记录 { [[IgnoreCase]]: ignoreCase, [[Multiline]]: multiline, [[DotAll]]: dotAll, [[Unicode]]: unicode, [[UnicodeSets]]: unicodeSets, [[CapturingGroupsCount]]: capturingGroupsCount }。

22.2.2.8 运行时语义:CompileCharacterClass

The syntax-directed operation 运行时语义:CompileCharacterClass takes argument rer (一个 RegExp 记录) and returns 记录,字段 [[CharSet]]CharSet)与 [[Invert]](布尔值). It is defined piecewise over the following productions:

CharacterClass :: [ ClassContents ]
  1. AClassContents 的 CompileToCharSet,参数 rer
  2. 返回记录 { [[CharSet]]: A, [[Invert]]: false }。
CharacterClass :: [^ ClassContents ]
  1. AClassContents 的 CompileToCharSet,参数 rer
  2. rer.[[UnicodeSets]]true,则
    1. 返回记录 { [[CharSet]]: CharacterComplement(rer, A), [[Invert]]: false }。
  3. 返回记录 { [[CharSet]]: A, [[Invert]]: true }。

22.2.2.9 运行时语义:CompileToCharSet

The syntax-directed operation 运行时语义:CompileToCharSet takes argument rer (一个 RegExp 记录) and returns 一个 CharSet.

Note 1

本节在 B.1.2.8 中有补充。

It is defined piecewise over the following productions:

ClassContents :: [empty]
  1. 返回空 CharSet
NonemptyClassRanges :: ClassAtom NonemptyClassRangesNoDash
  1. AClassAtom 的 CompileToCharSet,参数 rer
  2. BNonemptyClassRangesNoDash 的 CompileToCharSet,参数 rer
  3. 返回 AB 的并集。
NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents
  1. A 为第一个 ClassAtom 的 CompileToCharSet,参数 rer
  2. B 为第二个 ClassAtom 的 CompileToCharSet,参数 rer
  3. CClassContents 的 CompileToCharSet,参数 rer
  4. DCharacterRange(A, B)。
  5. 返回 DC 的并集。
NonemptyClassRangesNoDash :: ClassAtomNoDash NonemptyClassRangesNoDash
  1. AClassAtomNoDash 的 CompileToCharSet,参数 rer
  2. BNonemptyClassRangesNoDash 的 CompileToCharSet,参数 rer
  3. 返回 AB 的并集。
NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents
  1. AClassAtomNoDash 的 CompileToCharSet,参数 rer
  2. BClassAtom 的 CompileToCharSet,参数 rer
  3. CClassContents 的 CompileToCharSet,参数 rer
  4. DCharacterRange(A, B)。
  5. 返回 DC 的并集。
Note 2

ClassContents 可展开为单个 ClassAtom,以及/或由连字符分隔的两个 ClassAtom 范围。后者包含两端之间所有字符(含端点);若任一 ClassAtom 不表示单字符(如 \w)或首字符值大于第二个字符值则错误。

Note 3

即便模式忽略大小写,范围两端大小写仍影响范围所含字符。例如 /[E-F]/i 只匹配 EFef,而 /[E-f]/i 匹配 Basic Latin 中所有大小写字母以及符号 [, \, ], ^, _, `

Note 4

- 可字面或作范围界定符。位于 ClassContents 首/末、范围起止、或紧随范围后时按字面处理。

ClassAtom :: -
  1. 返回含单字符 - U+002D 的 CharSet
ClassAtomNoDash :: SourceCharacter but not one of \ or ] or -
  1. 返回含 SourceCharacter 匹配字符的 CharSet
ClassEscape :: b - CharacterEscape
  1. cv 为此 ClassEscape 的 CharacterValue。
  2. c 为字符值为 cv 的字符。
  3. 返回含单字符 cCharSet
Note 5

ClassAtom 可使用除 \b\B、反向引用外的其他正则转义。在 CharacterClass 内,\b 表示退格,\B 与反向引用报错;在 ClassAtom 内使用反向引用导致错误。

CharacterClassEscape :: d
  1. 返回含字符 0..9 的十元素 CharSet
CharacterClassEscape :: D
  1. S CharacterClassEscape :: d 返回的 CharSet
  2. 返回 CharacterComplement(rer, S)。
CharacterClassEscape :: s
  1. 返回含 WhiteSpaceLineTerminator 产生式右侧代码点对应字符的 CharSet
CharacterClassEscape :: S
  1. S CharacterClassEscape :: s 返回的 CharSet
  2. 返回 CharacterComplement(rer, S)。
CharacterClassEscape :: w
  1. 返回 MaybeSimpleCaseFolding(rer, WordCharacters(rer))。
CharacterClassEscape :: W
  1. S CharacterClassEscape :: w 返回的 CharSet
  2. 返回 CharacterComplement(rer, S)。
CharacterClassEscape :: p{ UnicodePropertyValueExpression }
  1. 返回 UnicodePropertyValueExpression 的 CompileToCharSet,参数 rer
CharacterClassEscape :: P{ UnicodePropertyValueExpression }
  1. SUnicodePropertyValueExpression 的 CompileToCharSet,参数 rer
  2. 断言:S 仅含单代码点。
  3. 返回 CharacterComplement(rer, S)。
UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue
  1. psUnicodePropertyName 匹配的源文本。
  2. pUnicodeMatchProperty(rer, ps)。
  3. 断言:pTable 67 “Property name and aliases” 列列出的属性名或别名。
  4. vsUnicodePropertyValue 匹配的源文本。
  5. vUnicodeMatchPropertyValue(p, vs)。
  6. A 为含所有在字符数据库定义中具属性 p 且值 v 的 Unicode 代码点的 CharSet
  7. 返回 MaybeSimpleCaseFolding(rer, A)。
UnicodePropertyValueExpression :: LoneUnicodePropertyNameOrValue
  1. sLoneUnicodePropertyNameOrValue 匹配的源文本。
  2. UnicodeMatchPropertyValue(General_Category, s) 为 General_Category 属性的属性值或别名(见 PropertyValueAliases.txt),则
    1. 返回含字符数据库中属性 “General_Category” = s 的所有 Unicode 代码点的 CharSet
  3. pUnicodeMatchProperty(rer, s)。
  4. 断言:pTable 68 “Property name and aliases” 列列出的二进制属性或别名,或 Table 69 “Property name” 列列出的字符串二进制属性。
  5. A 为含所有字符数据库定义中属性 p = “True” 的 CharSetElementCharSet
  6. 返回 MaybeSimpleCaseFolding(rer, A)。
ClassUnion :: ClassSetRange ClassUnionopt
  1. AClassSetRange 的 CompileToCharSet,参数 rer
  2. ClassUnion 存在,则
    1. BClassUnion 的 CompileToCharSet,参数 rer
    2. 返回 AB
  3. 返回 A
ClassUnion :: ClassSetOperand ClassUnionopt
  1. AClassSetOperand 的 CompileToCharSet,参数 rer
  2. ClassUnion 存在,则
    1. BClassUnion 的 CompileToCharSet,参数 rer
    2. 返回 AB
  3. 返回 A
ClassIntersection :: ClassSetOperand && ClassSetOperand
  1. A 为第一个 ClassSetOperand 的 CompileToCharSet,参数 rer
  2. B 为第二个 ClassSetOperand 的 CompileToCharSet,参数 rer
  3. 返回 AB
ClassIntersection :: ClassIntersection && ClassSetOperand
  1. AClassIntersection 的 CompileToCharSet,参数 rer
  2. BClassSetOperand 的 CompileToCharSet,参数 rer
  3. 返回 AB
ClassSubtraction :: ClassSetOperand -- ClassSetOperand
  1. A 为第一个 ClassSetOperand 的 CompileToCharSet,参数 rer
  2. B 为第二个 ClassSetOperand 的 CompileToCharSet,参数 rer
  3. 返回含 A 中不在 B 中的元素的 CharSet
ClassSubtraction :: ClassSubtraction -- ClassSetOperand
  1. AClassSubtraction 的 CompileToCharSet,参数 rer
  2. BClassSetOperand 的 CompileToCharSet,参数 rer
  3. 返回含 A 中不在 B 中元素的 CharSet
ClassSetRange :: ClassSetCharacter - ClassSetCharacter
  1. A 为第一个 ClassSetCharacter 的 CompileToCharSet,参数 rer
  2. B 为第二个 ClassSetCharacter 的 CompileToCharSet,参数 rer
  3. 返回 MaybeSimpleCaseFolding(rer, CharacterRange(A, B))。
Note 6

结果通常由多段范围组成。当 UnicodeSets 与 IgnoreCase 同为 true 时,MaybeSimpleCaseFolding(rer, [Ā-č]) 仅包含该范围中奇数序号代码点。

ClassSetOperand :: ClassSetCharacter
  1. AClassSetCharacter 的 CompileToCharSet,参数 rer
  2. 返回 MaybeSimpleCaseFolding(rer, A)。
ClassSetOperand :: ClassStringDisjunction
  1. AClassStringDisjunction 的 CompileToCharSet,参数 rer
  2. 返回 MaybeSimpleCaseFolding(rer, A)。
ClassSetOperand :: NestedClass
  1. 返回 NestedClass 的 CompileToCharSet,参数 rer
NestedClass :: [ ClassContents ]
  1. 返回 ClassContents 的 CompileToCharSet,参数 rer
NestedClass :: [^ ClassContents ]
  1. AClassContents 的 CompileToCharSet,参数 rer
  2. 返回 CharacterComplement(rer, A)。
NestedClass :: \ CharacterClassEscape
  1. 返回 CharacterClassEscape 的 CompileToCharSet,参数 rer
ClassStringDisjunction :: \q{ ClassStringDisjunctionContents }
  1. 返回 ClassStringDisjunctionContents 的 CompileToCharSet,参数 rer
ClassStringDisjunctionContents :: ClassString
  1. sClassString 的 CompileClassSetString,参数 rer
  2. 返回含唯一字符串 sCharSet
ClassStringDisjunctionContents :: ClassString | ClassStringDisjunctionContents
  1. sClassString 的 CompileClassSetString,参数 rer
  2. A 为含字符串 sCharSet
  3. BClassStringDisjunctionContents 的 CompileToCharSet,参数 rer
  4. 返回 AB 的并集。
ClassSetCharacter :: SourceCharacter but not ClassSetSyntaxCharacter \ CharacterEscape \ ClassSetReservedPunctuator
  1. cv 为此 ClassSetCharacter 的 CharacterValue。
  2. c 为字符值为 cv 的字符。
  3. 返回含单字符 cCharSet
ClassSetCharacter :: \b
  1. 返回含单字符 U+0008 (BACKSPACE) 的 CharSet

22.2.2.9.1 CharacterRange ( A, B )

The abstract operation CharacterRange takes arguments A (一个 CharSet) and B (一个 CharSet) and returns 一个 CharSet. It performs the following steps when called:

  1. 断言:AB 各含恰一字符。
  2. aA 中该字符。
  3. bB 中该字符。
  4. ia 的字符值。
  5. jb 的字符值。
  6. 断言:ij
  7. 返回含所有字符值位于 [i, j] 间(含)的字符集合的 CharSet

22.2.2.9.2 HasEitherUnicodeFlag ( rer )

The abstract operation HasEitherUnicodeFlag takes argument rer (一个 RegExp 记录) and returns 布尔值. It performs the following steps when called:

  1. rer.[[Unicode]]truerer.[[UnicodeSets]]true
    1. 返回 true
  2. 返回 false

22.2.2.9.3 WordCharacters ( rer )

The abstract operation WordCharacters takes argument rer (一个 RegExp 记录) and returns 一个 CharSet. 返回一个包含被视为 \b\B\w\W 之“单词字符”的 CharSet。 It performs the following steps when called:

  1. basicWordChars 为含所有 ASCII 单词字符的 CharSet
  2. extraWordCharsCharSet,包含所有不在 basicWordChars 中但 Canonicalize(rer, c) 在其中的字符 c
  3. 断言:除非 HasEitherUnicodeFlag(rer) 为 truerer.[[IgnoreCase]]true,否则 extraWordChars 为空。
  4. 返回 basicWordCharsextraWordChars 的并集。

22.2.2.9.4 AllCharacters ( rer )

The abstract operation AllCharacters takes argument rer (一个 RegExp 记录) and returns 一个 CharSet. 依据正则标志返回“全部字符”集合。 It performs the following steps when called:

  1. rer.[[UnicodeSets]]truerer.[[IgnoreCase]]true,则
    1. 返回含所有 Unicode 代码点 c 且其 Simple Case Folding 映射为空(scf(c) = c)的 CharSet
  2. 否则若 HasEitherUnicodeFlag(rer) 为 true
    1. 返回含所有代码点值的 CharSet
  3. 否则,
    1. 返回含所有代码单元值的 CharSet

22.2.2.9.5 MaybeSimpleCaseFolding ( rer, A )

The abstract operation MaybeSimpleCaseFolding takes arguments rer (一个 RegExp 记录) and A (一个 CharSet) and returns 一个 CharSet. 若 rer.[[UnicodeSets]]falserer.[[IgnoreCase]]false,返回 A。否则使用 Unicode 字符数据库文件 Simple Case Foldingscf(cp))定义,对 A 中每个 CharSetElement 进行逐字符映射到规范形式并返回结果。 It performs the following steps when called:

  1. rer.[[UnicodeSets]]falserer.[[IgnoreCase]]false,返回 A
  2. B 为新空 CharSet
  3. A 的每个 CharSetElement s
    1. t 为空字符序列。
    2. s 中每个单代码点 cp
      1. 追加 scf(cp) 至 t
    3. t 加入 B
  4. 返回 B

22.2.2.9.6 CharacterComplement ( rer, S )

The abstract operation CharacterComplement takes arguments rer (一个 RegExp 记录) and S (一个 CharSet) and returns 一个 CharSet. It performs the following steps when called:

  1. AAllCharacters(rer)。
  2. 返回含 A 中不在 S 中的 CharSetElementCharSet

22.2.2.9.7 UnicodeMatchProperty ( rer, p )

The abstract operation UnicodeMatchProperty takes arguments rer (一个 RegExp 记录) and p (ECMAScript 源文本) and returns 一个 Unicode 属性名. It performs the following steps when called:

  1. rer.[[UnicodeSets]]truepTable 69 “Property name” 列列出的 Unicode property name,则
    1. 返回 Unicode 代码点列表 p
  2. 断言:pTable 67Table 68 “Property name and aliases” 列列出的属性名或别名。
  3. c 为该行 “Canonical property name” 列给出的 p 的规范属性名
  4. 返回 Unicode 代码点列表 c

实现必须支持 Table 67Table 68Table 69 中列出的属性名与别名;不得支持其他名称或别名。

Note 1

例如,Script_Extensionsscx 有效,但 script_extensionsScx 无效。

Note 2

列出属性集合为 UTS18 RL1.2 要求的超集。

Note 3

表中条目拼写(含大小写)与 Unicode 字符数据库 PropertyAliases.txt 保持一致,并遵守其稳定性保证。

Table 67: Non-binary Unicode property aliases and their canonical property names
Property name and aliases Canonical property name
General_Category General_Category
gc
Script Script
sc
Script_Extensions Script_Extensions
scx
Table 68: Binary Unicode property aliases and their canonical property names
Property name and aliases Canonical property name
ASCII ASCII
ASCII_Hex_Digit ASCII_Hex_Digit
AHex
Alphabetic Alphabetic
Alpha
Any Any
Assigned Assigned
Bidi_Control Bidi_Control
Bidi_C
Bidi_Mirrored Bidi_Mirrored
Bidi_M
Case_Ignorable Case_Ignorable
CI
Cased Cased
Changes_When_Casefolded Changes_When_Casefolded
CWCF
Changes_When_Casemapped Changes_When_Casemapped
CWCM
Changes_When_Lowercased Changes_When_Lowercased
CWL
Changes_When_NFKC_Casefolded Changes_When_NFKC_Casefolded
CWKCF
Changes_When_Titlecased Changes_When_Titlecased
CWT
Changes_When_Uppercased Changes_When_Uppercased
CWU
Dash Dash
Default_Ignorable_Code_Point Default_Ignorable_Code_Point
DI
Deprecated Deprecated
Dep
Diacritic Diacritic
Dia
Emoji Emoji
Emoji_Component Emoji_Component
EComp
Emoji_Modifier Emoji_Modifier
EMod
Emoji_Modifier_Base Emoji_Modifier_Base
EBase
Emoji_Presentation Emoji_Presentation
EPres
Extended_Pictographic Extended_Pictographic
ExtPict
Extender Extender
Ext
Grapheme_Base Grapheme_Base
Gr_Base
Grapheme_Extend Grapheme_Extend
Gr_Ext
Hex_Digit Hex_Digit
Hex
IDS_Binary_Operator IDS_Binary_Operator
IDSB
IDS_Trinary_Operator IDS_Trinary_Operator
IDST
ID_Continue ID_Continue
IDC
ID_Start ID_Start
IDS
Ideographic Ideographic
Ideo
Join_Control Join_Control
Join_C
Logical_Order_Exception Logical_Order_Exception
LOE
Lowercase Lowercase
Lower
Math Math
Noncharacter_Code_Point Noncharacter_Code_Point
NChar
Pattern_Syntax Pattern_Syntax
Pat_Syn
Pattern_White_Space Pattern_White_Space
Pat_WS
Quotation_Mark Quotation_Mark
QMark
Radical Radical
Regional_Indicator Regional_Indicator
RI
Sentence_Terminal Sentence_Terminal
STerm
Soft_Dotted Soft_Dotted
SD
Terminal_Punctuation Terminal_Punctuation
Term
Unified_Ideograph Unified_Ideograph
UIdeo
Uppercase Uppercase
Upper
Variation_Selector Variation_Selector
VS
White_Space White_Space
space
XID_Continue XID_Continue
XIDC
XID_Start XID_Start
XIDS
Table 69: Binary Unicode properties of strings
Property name
Basic_Emoji
Emoji_Keycap_Sequence
RGI_Emoji_Modifier_Sequence
RGI_Emoji_Flag_Sequence
RGI_Emoji_Tag_Sequence
RGI_Emoji_ZWJ_Sequence
RGI_Emoji

22.2.2.9.8 UnicodeMatchPropertyValue ( p, v )

The abstract operation UnicodeMatchPropertyValue takes arguments p (ECMAScript 源文本) and v (ECMAScript 源文本) and returns 一个 Unicode 属性值. It performs the following steps when called:

  1. 断言:pTable 67 “Canonical property name” 列列出的规范非别名属性名
  2. 断言:v 是文件 PropertyValueAliases.txt 中属性 p 的属性值或别名。
  3. value 为该行 “Canonical property value” 列中 v 的规范属性值。
  4. 返回 Unicode 代码点列表 value

实现必须支持 PropertyValueAliases.txt 中针对 Table 67 所列属性的属性值与别名;不得支持其他属性值或别名。

Note 1

例如,XpeoOld_Persian 是有效的 Script_Extensions 值,而 xpeoOld Persian 无效。

Note 2

该算法不同于 UAX44 中符号值匹配规则:不会忽略大小写、空白、U+002D、U+005F,也不支持 Is 前缀。

22.2.2.10 运行时语义:CompileClassSetString

The syntax-directed operation 运行时语义:CompileClassSetString takes argument rer (一个 RegExp 记录) and returns 一个字符序列. It is defined piecewise over the following productions:

ClassString :: [empty]
  1. 返回空字符序列。
ClassString :: NonEmptyClassString
  1. 返回 NonEmptyClassString 的 CompileClassSetString,参数 rer
NonEmptyClassString :: ClassSetCharacter NonEmptyClassStringopt
  1. csClassSetCharacter 的 CompileToCharSet,参数 rer
  2. s1cs 的单个 CharSetElement 所对应的字符序列。
  3. NonEmptyClassString 存在,则
    1. s2NonEmptyClassString 的 CompileClassSetString,参数 rer
    2. 返回 s1s2 的连接。
  4. 返回 s1

22.2.3 用于创建 RegExp 的抽象操作(Abstract Operations for RegExp Creation)

22.2.3.1 RegExpCreate ( P, F )

The abstract operation RegExpCreate takes arguments P (一个 ECMAScript 语言值) and F (一个字符串或 undefined) and returns 包含一个对象的正常完成或抛出完成. It performs the following steps when called:

  1. obj 为 ! RegExpAlloc(%RegExp%)。
  2. 返回 ? RegExpInitialize(obj, P, F)。

22.2.3.2 RegExpAlloc ( newTarget )

The abstract operation RegExpAlloc takes argument newTarget (一个构造函数) and returns 包含一个对象的正常完成或抛出完成. It performs the following steps when called:

  1. obj 为 ? OrdinaryCreateFromConstructor(newTarget, "%RegExp.prototype%", « [[OriginalSource]], [[OriginalFlags]], [[RegExpRecord]], [[RegExpMatcher]] »)。
  2. 执行 ! DefinePropertyOrThrow(obj, "lastIndex", PropertyDescriptor { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  3. 返回 obj

22.2.3.3 RegExpInitialize ( obj, pattern, flags )

The abstract operation RegExpInitialize takes arguments obj (一个对象), pattern (一个 ECMAScript 语言值), and flags (一个 ECMAScript 语言值) and returns 包含一个对象的正常完成或抛出完成. It performs the following steps when called:

  1. 如果 patternundefined,令 P 为空字符串。
  2. 否则,令 P 为 ? ToString(pattern)。
  3. 如果 flagsundefined,令 F 为空字符串。
  4. 否则,令 F 为 ? ToString(flags)。
  5. 如果 F 包含 "d""g""i""m""s""u""v""y" 之外的任一代码单元,或 F 中任一代码单元出现多于一次,抛出 SyntaxError 异常。
  6. 如果 F 包含 "i",令 itrue;否则令 ifalse
  7. 如果 F 包含 "m",令 mtrue;否则令 mfalse
  8. 如果 F 包含 "s",令 strue;否则令 sfalse
  9. 如果 F 包含 "u",令 utrue;否则令 ufalse
  10. 如果 F 包含 "v",令 vtrue;否则令 vfalse
  11. 如果 utruevtrue,则
    1. patternText 为 StringToCodePoints(P)。
  12. 否则,
    1. patternText 为将 P 的每个 16 位元素按 Unicode BMP 代码点解释的结果。不会对这些元素应用 UTF-16 解码。
  13. parseResult 为 ParsePattern(patternText, u, v)。
  14. 如果 parseResult 是一个非空 SyntaxError 对象列表,抛出 SyntaxError 异常。
  15. 断言:parseResult 是一个 Pattern 解析节点
  16. obj.[[OriginalSource]]P
  17. obj.[[OriginalFlags]]F
  18. capturingGroupsCount 为 CountLeftCapturingParensWithin(parseResult)。
  19. rerRegExp 记录 { [[IgnoreCase]]: i, [[Multiline]]: m, [[DotAll]]: s, [[Unicode]]: u, [[UnicodeSets]]: v, [[CapturingGroupsCount]]: capturingGroupsCount }。
  20. obj.[[RegExpRecord]]rer
  21. obj.[[RegExpMatcher]] 为 CompilePattern of parseResult with argument rer
  22. 执行 ? Set(obj, "lastIndex", +0𝔽, true)。
  23. 返回 obj

22.2.3.4 静态语义:ParsePattern ( patternText, u, v )

The abstract operation 静态语义:ParsePattern takes arguments patternText (一个 Unicode 代码点序列), u (一个布尔值), and v (一个布尔值) and returns 一个解析节点或非空 SyntaxError 对象列表.

Note

本节在 B.1.2.9 中有补充。

It performs the following steps when called:

  1. 如果 vtrueutrue,则
    1. parseResult 为包含一个或多个 SyntaxError 对象的列表。
  2. 否则如果 vtrue,则
    1. parseResult 为 ParseText(patternText, Pattern[+UnicodeMode, +UnicodeSetsMode, +NamedCaptureGroups])。
  3. 否则如果 utrue,则
    1. parseResult 为 ParseText(patternText, Pattern[+UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups])。
  4. 否则,
    1. parseResult 为 ParseText(patternText, Pattern[~UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups])。
  5. 返回 parseResult

22.2.4 RegExp 构造函数(The RegExp Constructor)

RegExp 构造函数

  • %RegExp%
  • 是全局对象 "RegExp" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 RegExp 对象。
  • 作为函数(而非构造函数)调用时,返回一个新的 RegExp 对象,或在唯一参数本身是 RegExp 对象时返回该参数。
  • 可用作类定义 extends 子句的值。打算继承指定 RegExp 行为的子类构造函数必须包含对 RegExp 构造函数super 调用,以创建并初始化带有所需内部槽的子类实例。

22.2.4.1 RegExp ( pattern, flags )

调用该函数时执行以下步骤:

  1. patternIsRegExp 为 ? IsRegExp(pattern)。
  2. 如果 NewTarget 为 undefined,则
    1. newTarget 为活动函数对象
    2. 如果 patternIsRegExptrueflagsundefined,则
      1. patternConstructor 为 ? Get(pattern, "constructor")。
      2. 如果 SameValue(newTarget, patternConstructor) 为 true,返回 pattern
  3. 否则,
    1. newTarget 为 NewTarget。
  4. 如果 pattern 是一个对象且具有 [[RegExpMatcher]] 内部槽,则
    1. Ppattern.[[OriginalSource]]
    2. 如果 flagsundefined,令 Fpattern.[[OriginalFlags]]
    3. 否则,令 Fflags
  5. 否则如果 patternIsRegExptrue,则
    1. P 为 ? Get(pattern, "source")。
    2. 如果 flagsundefined,则
      1. F 为 ? Get(pattern, "flags")。
    3. 否则,
      1. Fflags
  6. 否则,
    1. Ppattern
    2. Fflags
  7. O 为 ? RegExpAlloc(newTarget)。
  8. 返回 ? RegExpInitialize(O, P, F)。
Note

如果以 StringLiteral 形式传入 pattern,则在本函数处理该字符串之前会执行通常的转义序列替换。如果 pattern 必须包含一个转义序列才能被本函数识别,则 StringLiteral 中的任何 U+005C(反斜杠)代码点必须再被转义,以避免在形成 StringLiteral 内容时被移除。

22.2.5 RegExp 构造函数的属性(Properties of the RegExp Constructor)

RegExp 构造函数

22.2.5.1 RegExp.escape ( S )

该函数返回 S 的一个拷贝,其中在正则表达式 Pattern 中可能具有特殊意义的字符已被等效转义序列替换。

调用时执行以下步骤:

  1. 如果 S 不是字符串,抛出 TypeError 异常。
  2. escaped 为空字符串。
  3. cpList 为 StringToCodePoints(S)。
  4. cpList 中的每个代码点 cp,执行
    1. 如果 escaped 为空字符串且 cpDecimalDigitAsciiLetter 匹配,则
      1. 注:转义前导数字确保输出对应的模式文本可在 \0 字符转义或 DecimalEscape(如 \1)之后使用并仍匹配 S,而不是被解释为前一转义序列的延伸。转义前导 ASCII 字母在 \c 后的情境中亦如此。
      2. numericValuecp 的数值。
      3. hexNumber::toString(𝔽(numericValue), 16)。
      4. 断言:hex 的长度为 2。
      5. escaped 为 代码单元 0x005C (REVERSE SOLIDUS)、"x"hex 的字符串拼接。
    2. 否则,
      1. escapedescapedEncodeForRegExpEscape(cp) 的字符串拼接。
  5. 返回 escaped
Note

尽管名字相似,EscapeRegExpPatternRegExp.escape 所做的事情并不相同。前者转义一个模式以便作为字符串表示,而此函数转义一个字符串以便在模式内部表示。

22.2.5.1.1 EncodeForRegExpEscape ( cp )

The abstract operation EncodeForRegExpEscape takes argument cp (一个代码点) and returns 一个字符串. 返回一个用于匹配 cpPattern 的字符串。如果 cp 是空白或 ASCII 标点,则返回值是一个转义序列;否则返回值是 cp 自身的字符串表示。 It performs the following steps when called:

  1. 如果 cpSyntaxCharacter 匹配或 cp 是 U+002F (SOLIDUS),则
    1. 返回 0x005C (REVERSE SOLIDUS) 与 UTF16EncodeCodePoint(cp) 的字符串拼接。
  2. 否则如果 cpTable 65 “Code Point” 列所列出的代码点,则
    1. 返回 0x005C (REVERSE SOLIDUS) 与该行 “ControlEscape” 列中字符串的拼接。
  3. otherPunctuators",-=<>#&!%:;@~'`" 与代码单元 0x0022 (QUOTATION MARK) 的字符串拼接。
  4. toEscape 为 StringToCodePoints(otherPunctuators)。
  5. 如果 toEscape 包含 cp,或 cpWhiteSpaceLineTerminator 匹配,或 cp 数值与前导代理或尾随代理相同,则
    1. cpNumcp 的数值。
    2. 如果 cpNum ≤ 0xFF,则
      1. hexNumber::toString(𝔽(cpNum), 16)。
      2. 返回 代码单元 0x005C (REVERSE SOLIDUS)、"x"StringPad(hex, 2, "0", start) 的字符串拼接。
    3. escaped 为空字符串。
    4. codeUnits 为 UTF16EncodeCodePoint(cp)。
    5. codeUnits 中的每个代码单元 cu,执行
      1. escapedescapedUnicodeEscape(cu) 的字符串拼接。
    6. 返回 escaped
  6. 返回 UTF16EncodeCodePoint(cp)。

22.2.5.2 RegExp.prototype

RegExp.prototype 的初始值是 RegExp 原型对象

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

22.2.5.3 get RegExp [ %Symbol.species% ]

RegExp[%Symbol.species%] 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. 返回 this 值。

此函数的 "name" 属性值为 "get [Symbol.species]"

Note

RegExp 原型方法通常使用其 this 值的构造函数来创建派生对象。然而,子类构造函数可通过重新定义其 %Symbol.species% 属性来覆盖该默认行为。

22.2.6 RegExp 原型对象的属性(Properties of the RegExp Prototype Object)

RegExp 原型对象

  • %RegExp.prototype%
  • 是一个普通对象
  • 不是 RegExp 实例,且没有 [[RegExpMatcher]] 内部槽或 RegExp 实例对象的其他内部槽。
  • 有一个 [[Prototype]] 内部槽,其值为 %Object.prototype%
Note

RegExp 原型对象自身没有 "valueOf" 属性;但它从 Object 原型对象继承 "valueOf" 属性。

22.2.6.1 RegExp.prototype.constructor

RegExp.prototype.constructor 的初始值是 %RegExp%

22.2.6.2 RegExp.prototype.exec ( string )

该方法在 string 中搜索一次正则表达式模式的出现,并返回包含匹配结果的数组;若 string 未匹配则返回 null

调用时执行以下步骤:

  1. Rthis 值。
  2. 执行 ? RequireInternalSlot(R, [[RegExpMatcher]])。
  3. S 为 ? ToString(string)。
  4. 返回 ? RegExpBuiltinExec(R, S)。

22.2.6.3 get RegExp.prototype.dotAll

RegExp.prototype.dotAll 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Rthis 值。
  2. cu 为代码单元 0x0073 (LATIN SMALL LETTER S)。
  3. 返回 ? RegExpHasFlag(R, cu)。

22.2.6.4 get RegExp.prototype.flags

RegExp.prototype.flags 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Rthis 值。
  2. 如果 R 不是对象,抛出 TypeError 异常。
  3. codeUnits 为新的空列表。
  4. hasIndicesToBoolean(? Get(R, "hasIndices"))。
  5. 如果 hasIndicestrue,将代码单元 0x0064 (LATIN SMALL LETTER D) 追加到 codeUnits
  6. globalToBoolean(? Get(R, "global"))。
  7. 如果 globaltrue,将代码单元 0x0067 (LATIN SMALL LETTER G) 追加到 codeUnits
  8. ignoreCaseToBoolean(? Get(R, "ignoreCase"))。
  9. 如果 ignoreCasetrue,将代码单元 0x0069 (LATIN SMALL LETTER I) 追加到 codeUnits
  10. multilineToBoolean(? Get(R, "multiline"))。
  11. 如果 multilinetrue,将代码单元 0x006D (LATIN SMALL LETTER M) 追加到 codeUnits
  12. dotAllToBoolean(? Get(R, "dotAll"))。
  13. 如果 dotAlltrue,将代码单元 0x0073 (LATIN SMALL LETTER S) 追加到 codeUnits
  14. unicodeToBoolean(? Get(R, "unicode"))。
  15. 如果 unicodetrue,将代码单元 0x0075 (LATIN SMALL LETTER U) 追加到 codeUnits
  16. unicodeSetsToBoolean(? Get(R, "unicodeSets"))。
  17. 如果 unicodeSetstrue,将代码单元 0x0076 (LATIN SMALL LETTER V) 追加到 codeUnits
  18. stickyToBoolean(? Get(R, "sticky"))。
  19. 如果 stickytrue,将代码单元 0x0079 (LATIN SMALL LETTER Y) 追加到 codeUnits
  20. 返回代码单元为 codeUnits 列表元素的字符串值。若 codeUnits 为空,则返回空字符串。

22.2.6.4.1 RegExpHasFlag ( R, codeUnit )

The abstract operation RegExpHasFlag takes arguments R (一个 ECMAScript 语言值) and codeUnit (一个代码单元) and returns 包含布尔值或 undefined正常完成或抛出完成. It performs the following steps when called:

  1. 如果 R 不是对象,抛出 TypeError 异常。
  2. 如果 R 没有 [[OriginalFlags]] 内部槽,则
    1. 如果 SameValue(R, %RegExp.prototype%) 为 true,返回 undefined
    2. 否则,抛出 TypeError 异常。
  3. flagsR.[[OriginalFlags]]
  4. 如果 flags 包含 codeUnit,返回 true
  5. 返回 false

22.2.6.5 get RegExp.prototype.global

RegExp.prototype.global 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Rthis 值。
  2. cu 为代码单元 0x0067 (LATIN SMALL LETTER G)。
  3. 返回 ? RegExpHasFlag(R, cu)。

22.2.6.6 get RegExp.prototype.hasIndices

RegExp.prototype.hasIndices 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Rthis 值。
  2. cu 为代码单元 0x0064 (LATIN SMALL LETTER D)。
  3. 返回 ? RegExpHasFlag(R, cu)。

22.2.6.7 get RegExp.prototype.ignoreCase

RegExp.prototype.ignoreCase 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Rthis 值。
  2. cu 为代码单元 0x0069 (LATIN SMALL LETTER I)。
  3. 返回 ? RegExpHasFlag(R, cu)。

22.2.6.8 RegExp.prototype [ %Symbol.match% ] ( string )

调用该方法时执行以下步骤:

  1. rxthis 值。
  2. 如果 rx 不是对象,抛出 TypeError 异常。
  3. S 为 ? ToString(string)。
  4. flags 为 ? ToString(? Get(rx, "flags"))。
  5. 如果 flags 不包含 "g",则
    1. 返回 ? RegExpExec(rx, S)。
  6. 否则,
    1. 如果 flags 包含 "u"flags 包含 "v",令 fullUnicodetrue;否则令 fullUnicodefalse
    2. 执行 ? Set(rx, "lastIndex", +0𝔽, true)。
    3. A 为 ! ArrayCreate(0)。
    4. n 为 0。
    5. 重复,
      1. result 为 ? RegExpExec(rx, S)。
      2. 如果 resultnull,则
        1. 如果 n = 0,返回 null
        2. 返回 A
      3. 否则,
        1. matchStr 为 ? ToString(? Get(result, "0"))。
        2. 执行 ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), matchStr)。
        3. 如果 matchStr 为空字符串,则
          1. thisIndex(? ToLength(? Get(rx, "lastIndex")))。
          2. nextIndexAdvanceStringIndex(S, thisIndex, fullUnicode)。
          3. 执行 ? Set(rx, "lastIndex", 𝔽(nextIndex), true)。
        4. nn + 1。

该方法的 "name" 属性值为 "[Symbol.match]"

Note

%Symbol.match% 属性被 IsRegExp 抽象操作用于识别具有基本正则行为的对象。缺失 %Symbol.match% 属性或其值布尔化结果不为 true 表示该对象不打算作为正则表达式对象使用。

22.2.6.9 RegExp.prototype [ %Symbol.matchAll% ] ( string )

调用该方法时执行以下步骤:

  1. Rthis 值。
  2. 如果 R 不是对象,抛出 TypeError 异常。
  3. S 为 ? ToString(string)。
  4. C 为 ? SpeciesConstructor(R, %RegExp%)。
  5. flags 为 ? ToString(? Get(R, "flags"))。
  6. matcher 为 ? Construct(C, « R, flags »)。
  7. lastIndex 为 ? ToLength(? Get(R, "lastIndex"))。
  8. 执行 ? Set(matcher, "lastIndex", lastIndex, true)。
  9. 如果 flags 包含 "g",令 globaltrue
  10. 否则,令 globalfalse
  11. 如果 flags 包含 "u"flags 包含 "v",令 fullUnicodetrue
  12. 否则,令 fullUnicodefalse
  13. 返回 CreateRegExpStringIterator(matcher, S, global, fullUnicode)。

该方法的 "name" 属性值为 "[Symbol.matchAll]"

22.2.6.10 get RegExp.prototype.multiline

RegExp.prototype.multiline 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Rthis 值。
  2. cu 为代码单元 0x006D (LATIN SMALL LETTER M)。
  3. 返回 ? RegExpHasFlag(R, cu)。

22.2.6.11 RegExp.prototype [ %Symbol.replace% ] ( string, replaceValue )

调用该方法时执行以下步骤:

  1. rxthis 值。
  2. 如果 rx 不是对象,抛出 TypeError 异常。
  3. S 为 ? ToString(string)。
  4. lengthSS 的长度。
  5. functionalReplaceIsCallable(replaceValue)。
  6. 如果 functionalReplacefalse,则
    1. replaceValue 设为 ? ToString(replaceValue)。
  7. flags 为 ? ToString(? Get(rx, "flags"))。
  8. 如果 flags 包含 "g",令 globaltrue;否则令 globalfalse
  9. 如果 globaltrue,则
    1. 执行 ? Set(rx, "lastIndex", +0𝔽, true)。
  10. results 为新的空列表。
  11. donefalse
  12. donefalse 时重复,
    1. result 为 ? RegExpExec(rx, S)。
    2. 如果 resultnull,则
      1. donetrue
    3. 否则,
      1. result 追加到 results
      2. 如果 globalfalse,则
        1. donetrue
      3. 否则,
        1. matchStr 为 ? ToString(? Get(result, "0"))。
        2. 如果 matchStr 为空字符串,则
          1. thisIndex(? ToLength(? Get(rx, "lastIndex")))。
          2. 如果 flags 包含 "u"flags 包含 "v",令 fullUnicodetrue;否则令 fullUnicodefalse
          3. nextIndexAdvanceStringIndex(S, thisIndex, fullUnicode)。
          4. 执行 ? Set(rx, "lastIndex", 𝔽(nextIndex), true)。
  13. accumulatedResult 为空字符串。
  14. nextSourcePosition 为 0。
  15. results 中的每个元素 result,执行
    1. resultLength 为 ? LengthOfArrayLike(result)。
    2. nCapturesmax(resultLength - 1, 0)。
    3. matched 为 ? ToString(? Get(result, "0"))。
    4. matchLengthmatched 的长度。
    5. position 为 ? ToIntegerOrInfinity(? Get(result, "index"))。
    6. position 钳制到 0 与 lengthS 之间。
    7. captures 为新的空列表。
    8. n 为 1。
    9. nnCaptures 时重复,
      1. capN 为 ? Get(result, ! ToString(𝔽(n)))。
      2. 如果 capN 不为 undefined,则
        1. capN 为 ? ToString(capN)。
      3. capN 追加到 captures
      4. 注:当 n = 1 时,上一步将首元素放入 captures(索引 0)。更一般地,第 n 个捕获位于 captures[n - 1]。
      5. nn + 1。
    10. namedCaptures 为 ? Get(result, "groups")。
    11. 如果 functionalReplacetrue,则
      1. replacerArgs 为 « matched » 与 captures 以及 « 𝔽(position), S » 的列表拼接
      2. 如果 namedCaptures 不为 undefined,则
        1. namedCaptures 追加到 replacerArgs
      3. replacementValue 为 ? Call(replaceValue, undefined, replacerArgs)。
      4. replacementString 为 ? ToString(replacementValue)。
    12. 否则,
      1. 如果 namedCaptures 不为 undefined,则
        1. namedCaptures 为 ? ToObject(namedCaptures)。
      2. replacementString 为 ? GetSubstitution(matched, S, position, captures, namedCaptures, replaceValue)。
    13. 如果 positionnextSourcePosition,则
      1. 注:position 通常不应后移;若后移,说明存在行为不良的 RegExp 子类或通过访问触发副作用更改 rx 的 global 标志或其他特性。在此类情况下,对应替换被忽略。
      2. accumulatedResultaccumulatedResultS 的子串(从 nextSourcePositionposition)、replacementString 的串联。
      3. nextSourcePositionposition + matchLength
  16. 如果 nextSourcePositionlengthS,返回 accumulatedResult
  17. 返回 accumulatedResultSnextSourcePosition 起子串的拼接。

该方法的 "name" 属性值为 "[Symbol.replace]"

22.2.6.12 RegExp.prototype [ %Symbol.search% ] ( string )

调用该方法时执行以下步骤:

  1. rxthis 值。
  2. 如果 rx 不是对象,抛出 TypeError 异常。
  3. S 为 ? ToString(string)。
  4. previousLastIndex 为 ? Get(rx, "lastIndex")。
  5. 如果 previousLastIndex 不是 +0𝔽,则
    1. 执行 ? Set(rx, "lastIndex", +0𝔽, true)。
  6. result 为 ? RegExpExec(rx, S)。
  7. currentLastIndex 为 ? Get(rx, "lastIndex")。
  8. 如果 SameValue(currentLastIndex, previousLastIndex) 为 false,则
    1. 执行 ? Set(rx, "lastIndex", previousLastIndex, true)。
  9. 如果 resultnull,返回 -1𝔽
  10. 返回 ? Get(result, "index")。

该方法的 "name" 属性值为 "[Symbol.search]"

Note

执行搜索时忽略该 RegExp 对象的 "lastIndex""global" 属性。"lastIndex" 属性保持不变。

22.2.6.13 get RegExp.prototype.source

RegExp.prototype.source 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Rthis 值。
  2. 如果 R 不是对象,抛出 TypeError 异常。
  3. 如果 R 没有 [[OriginalSource]] 内部槽,则
    1. 如果 SameValue(R, %RegExp.prototype%) 为 true,返回 "(?:)"
    2. 否则,抛出 TypeError 异常。
  4. 断言:R 具有 [[OriginalFlags]] 内部槽。
  5. srcR.[[OriginalSource]]
  6. flagsR.[[OriginalFlags]]
  7. 返回 EscapeRegExpPattern(src, flags)。

22.2.6.13.1 EscapeRegExpPattern ( P, F )

The abstract operation EscapeRegExpPattern takes arguments P (一个字符串) and F (一个字符串) and returns 一个字符串. It performs the following steps when called:

  1. 如果 F 包含 "v",则
    1. patternSymbolPattern[+UnicodeMode, +UnicodeSetsMode]
  2. 否则如果 F 包含 "u",则
    1. patternSymbolPattern[+UnicodeMode, ~UnicodeSetsMode]
  3. 否则,
    1. patternSymbolPattern[~UnicodeMode, ~UnicodeSetsMode]
  4. S 为一种 patternSymbol 形式的字符串,该字符串等价于将 P 按 UTF-16 编码的 Unicode 代码点解释(6.1.4)后对特定代码点按下述规则转义得到的结果。S 可能与 P 相同或不同;但对 S 作为 patternSymbol 求值得到的抽象闭包必须与构造对象 [[RegExpMatcher]] 内部槽给出的抽象闭包行为一致。对同一 PF 的多次调用必须产生相同结果。
  5. 模式中出现的 / 或任何 LineTerminator 必须在 S 中按需转义,以确保 "/"S"/"F 的字符串拼接(在适当词法上下文中)可被解析为与所构造正则表达式行为一致的 RegularExpressionLiteral。例如,如果 P"/",则 S 可以是 "\/""\u002F" 等,但不能是 "/",因为 /// 后随 F 会被解析为 SingleLineComment 而非 RegularExpressionLiteral。如果 P 是空字符串,本规范可通过让 S"(?:)" 来满足。
  6. 返回 S
Note

尽管名字相似,RegExp.escape 与 EscapeRegExpPattern 所做事情不同。前者转义一个字符串以用于模式内部,后者转义一个模式以作为字符串表示。

22.2.6.14 RegExp.prototype [ %Symbol.split% ] ( string, limit )

Note 1

该方法返回一个数组,数组中存放将 string 转为字符串结果的各子串。子串通过自左向右搜索 this 值正则表达式的匹配来确定;这些出现不属于返回数组中任何字符串,而是用来分割字符串值。

this 值可以是一个空正则或一个可匹配空字符串的正则。在此情况下,正则不会匹配输入字符串开头或末尾的空 substring,也不会匹配前一次分隔符匹配末尾的空 substring。(例如,如果正则匹配空字符串,则字符串被拆分为单个代码单元;结果数组长度等于字符串长度,每个 substring 包含一个代码单元。)在给定索引处只考虑第一次匹配,即便回溯可能在该索引产生非空 substring。 (例如,/a*?/[Symbol.split]("ab") 结果为 ["a", "b"],而 /a*/[Symbol.split]("ab") 结果为 ["","b"]。)

如果 string 是(或转换为)空字符串,结果取决于正则是否能匹配空字符串。若能,结果数组无元素;否则结果数组含一个元素,即空字符串。

如果正则包含捕获括号,则每次匹配 separator 时捕获括号的结果(包括 undefined)会被拼接进输出数组。例如:

/<(\/)?([^<>]+)>/[Symbol.split]("A<B>bold</B>and<CODE>coded</CODE>")

计算结果为数组

["A", undefined, "B", "bold", "/", "B", "and", undefined, "CODE", "coded", "/", "CODE", ""]

如果 limit 不为 undefined,则输出数组截断为不超过 limit 个元素。

调用该方法时执行以下步骤:

  1. rxthis 值。
  2. 如果 rx 不是对象,抛出 TypeError 异常。
  3. S 为 ? ToString(string)。
  4. C 为 ? SpeciesConstructor(rx, %RegExp%)。
  5. flags 为 ? ToString(? Get(rx, "flags"))。
  6. 如果 flags 包含 "u"flags 包含 "v",令 unicodeMatchingtrue
  7. 否则,令 unicodeMatchingfalse
  8. 如果 flags 包含 "y",令 newFlagsflags
  9. 否则,令 newFlagsflags"y" 的串联。
  10. splitter 为 ? Construct(C, « rx, newFlags »)。
  11. A 为 ! ArrayCreate(0)。
  12. lengthA 为 0。
  13. 如果 limitundefined,令 lim 为 232 - 1;否则令 lim(? ToUint32(limit))。
  14. 如果 lim = 0,返回 A
  15. 如果 S 是空字符串,则
    1. z 为 ? RegExpExec(splitter, S)。
    2. 如果 z 不为 null,返回 A
    3. 执行 ! CreateDataPropertyOrThrow(A, "0", S)。
    4. 返回 A
  16. sizeS 的长度。
  17. p 为 0。
  18. qp
  19. q < size 时重复,
    1. 执行 ? Set(splitter, "lastIndex", 𝔽(q), true)。
    2. z 为 ? RegExpExec(splitter, S)。
    3. 如果 znull,则
      1. qAdvanceStringIndex(S, q, unicodeMatching)。
    4. 否则,
      1. e(? ToLength(? Get(splitter, "lastIndex")))。
      2. emin(e, size)。
      3. 如果 e = p,则
        1. qAdvanceStringIndex(S, q, unicodeMatching)。
      4. 否则,
        1. TSpq 的子串。
        2. 执行 ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(lengthA)), T)。
        3. lengthAlengthA + 1。
        4. 如果 lengthA = lim,返回 A
        5. pe
        6. numberOfCaptures 为 ? LengthOfArrayLike(z)。
        7. numberOfCapturesmax(numberOfCaptures - 1, 0)。
        8. i 为 1。
        9. inumberOfCaptures 时重复,
          1. nextCapture 为 ? Get(z, ! ToString(𝔽(i)))。
          2. 执行 ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(lengthA)), nextCapture)。
          3. ii + 1。
          4. lengthAlengthA + 1。
          5. 如果 lengthA = lim,返回 A
        10. qp
  20. TSpsize 的子串。
  21. 执行 ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(lengthA)), T)。
  22. 返回 A

该方法的 "name" 属性值为 "[Symbol.split]"

Note 2

该方法忽略此 RegExp 对象的 "global""sticky" 属性的值。

22.2.6.15 get RegExp.prototype.sticky

RegExp.prototype.sticky 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Rthis 值。
  2. cu 为代码单元 0x0079 (LATIN SMALL LETTER Y)。
  3. 返回 ? RegExpHasFlag(R, cu)。

22.2.6.16 RegExp.prototype.test ( S )

调用该方法时执行以下步骤:

  1. Rthis 值。
  2. 如果 R 不是对象,抛出 TypeError 异常。
  3. string 为 ? ToString(S)。
  4. match 为 ? RegExpExec(R, string)。
  5. 如果 match 不为 null,返回 true;否则返回 false

22.2.6.17 RegExp.prototype.toString ( )

  1. Rthis 值。
  2. 如果 R 不是对象,抛出 TypeError 异常。
  3. pattern 为 ? ToString(? Get(R, "source"))。
  4. flags 为 ? ToString(? Get(R, "flags"))。
  5. result"/"pattern"/"flags 的字符串拼接。
  6. 返回 result
Note

返回的字符串形式为 RegularExpressionLiteral,其求值得到的另一个 RegExp 对象与此对象行为相同。

22.2.6.18 get RegExp.prototype.unicode

RegExp.prototype.unicode 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Rthis 值。
  2. cu 为代码单元 0x0075 (LATIN SMALL LETTER U)。
  3. 返回 ? RegExpHasFlag(R, cu)。

22.2.6.19 get RegExp.prototype.unicodeSets

RegExp.prototype.unicodeSets 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Rthis 值。
  2. cu 为代码单元 0x0076 (LATIN SMALL LETTER V)。
  3. 返回 ? RegExpHasFlag(R, cu)。

22.2.7 用于 RegExp 匹配的抽象操作(Abstract Operations for RegExp Matching)

22.2.7.1 RegExpExec ( R, S )

The abstract operation RegExpExec takes arguments R (一个对象) and S (一个字符串) and returns 包含对象或 null正常完成或抛出完成. It performs the following steps when called:

  1. exec 为 ? Get(R, "exec")。
  2. 如果 IsCallable(exec) 为 true,则
    1. result 为 ? Call(exec, R, « S »)。
    2. 如果 result 不是对象且不为 null,抛出 TypeError 异常。
    3. 返回 result
  3. 执行 ? RequireInternalSlot(R, [[RegExpMatcher]])。
  4. 返回 ? RegExpBuiltinExec(R, S)。
Note

如果未找到可调用的 "exec" 属性,本算法会回退到使用内置的 RegExp 匹配算法。这为旧版本编写的代码提供兼容行为——在那些版本中,大多数使用正则的内置算法不会对 "exec" 进行动态属性查找。

22.2.7.2 RegExpBuiltinExec ( R, S )

The abstract operation RegExpBuiltinExec takes arguments R (一个已初始化的 RegExp 实例) and S (一个字符串) and returns 包含数组特异对象null正常完成或抛出完成. It performs the following steps when called:

  1. lengthS 的长度。
  2. lastIndex(? ToLength(! Get(R, "lastIndex")))。
  3. flagsR.[[OriginalFlags]]
  4. 如果 flags 包含 "g",令 globaltrue;否则令 globalfalse
  5. 如果 flags 包含 "y",令 stickytrue;否则令 stickyfalse
  6. 如果 flags 包含 "d",令 hasIndicestrue;否则令 hasIndicesfalse
  7. 如果 globalfalsestickyfalse,设 lastIndex 为 0。
  8. matcherR.[[RegExpMatcher]]
  9. 如果 flags 包含 "u"flags 包含 "v",令 fullUnicodetrue;否则令 fullUnicodefalse
  10. matchSucceededfalse
  11. 如果 fullUnicodetrue,令 input 为 StringToCodePoints(S);否则令 input 为一个列表,其元素为 S 的代码单元。
  12. 注:input 的每个元素都被视为一个字符。
  13. matchSucceededfalse 时重复,
    1. 如果 lastIndex > length,则
      1. 如果 globaltruestickytrue,则
        1. 执行 ? Set(R, "lastIndex", +0𝔽, true)。
      2. 返回 null
    2. inputIndex 为对应 SlastIndex 个元素的字符在 input 中的索引。
    3. rmatcher(input, inputIndex)。
    4. 如果 rfailure,则
      1. 如果 stickytrue,则
        1. 执行 ? Set(R, "lastIndex", +0𝔽, true)。
        2. 返回 null
      2. lastIndexAdvanceStringIndex(S, lastIndex, fullUnicode)。
    5. 否则,
      1. 断言:rMatchState
      2. matchSucceededtrue
  14. er.[[EndIndex]]
  15. 如果 fullUnicodetrue,设 eGetStringIndex(S, e)。
  16. 如果 globaltruestickytrue,则
    1. 执行 ? Set(R, "lastIndex", 𝔽(e), true)。
  17. nr.[[Captures]] 中的元素数量。
  18. 断言:n = R.[[RegExpRecord]].[[CapturingGroupsCount]]
  19. 断言:n < 232 - 1。
  20. A 为 ! ArrayCreate(n + 1)。
  21. 断言:A"length" 属性的数学值n + 1。
  22. 执行 ! CreateDataPropertyOrThrow(A, "index", 𝔽(lastIndex))。
  23. 执行 ! CreateDataPropertyOrThrow(A, "input", S)。
  24. matchMatch 记录 { [[StartIndex]]: lastIndex, [[EndIndex]]: e }。
  25. indices 为新的空列表。
  26. groupNames 为新的空列表。
  27. match 追加到 indices
  28. matchedSubstrGetMatchString(S, match)。
  29. 执行 ! CreateDataPropertyOrThrow(A, "0", matchedSubstr)。
  30. 如果 R 包含任意 GroupName,则
    1. groupsOrdinaryObjectCreate(null)。
    2. hasGroupstrue
  31. 否则,
    1. groupsundefined
    2. hasGroupsfalse
  32. 执行 ! CreateDataPropertyOrThrow(A, "groups", groups)。
  33. matchedGroupNames 为新的空列表。
  34. 对每个整数 i(1 ≤ in,升序),执行
    1. captureIr.[[Captures]] 的第 i 个元素。
    2. 如果 captureIundefined,则
      1. capturedValueundefined
      2. undefined 追加到 indices
    3. 否则,
      1. captureStartcaptureI.[[StartIndex]]
      2. captureEndcaptureI.[[EndIndex]]
      3. 如果 fullUnicodetrue,则
        1. captureStartGetStringIndex(S, captureStart)。
        2. captureEndGetStringIndex(S, captureEnd)。
      4. captureMatch 记录 { [[StartIndex]]: captureStart, [[EndIndex]]: captureEnd }。
      5. capturedValueGetMatchString(S, capture)。
      6. capture 追加到 indices
    4. 执行 ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(i)), capturedValue)。
    5. 如果 R 的第 i 个捕获是用 GroupName 定义的,则
      1. s 为该 GroupName 的 CapturingGroupName。
      2. 如果 matchedGroupNames 包含 s,则
        1. 断言:capturedValueundefined
        2. undefined 追加到 groupNames
      3. 否则,
        1. 如果 capturedValue 不为 undefined,将 s 追加到 matchedGroupNames
        2. 注:若多个组名为 sgroups 此时可能已有 s 属性;但由于 groups 是所有属性皆可写的数据属性普通对象CreateDataPropertyOrThrow 调用仍保证成功。
        3. 执行 ! CreateDataPropertyOrThrow(groups, s, capturedValue)。
        4. s 追加到 groupNames
    6. 否则,
      1. undefined 追加到 groupNames
  35. 如果 hasIndicestrue,则
    1. indicesArrayMakeMatchIndicesIndexPairArray(S, indices, groupNames, hasGroups)。
    2. 执行 ! CreateDataPropertyOrThrow(A, "indices", indicesArray)。
  36. 返回 A

22.2.7.3 AdvanceStringIndex ( S, index, unicode )

The abstract operation AdvanceStringIndex takes arguments S (一个字符串), index (一个非负整数), and unicode (一个布尔值) and returns 一个整数. It performs the following steps when called:

  1. 断言:index ≤ 253 - 1。
  2. 如果 unicodefalse,返回 index + 1。
  3. lengthS 的长度。
  4. 如果 index + 1 ≥ length,返回 index + 1。
  5. cp 为 CodePointAt(S, index)。
  6. 返回 index + cp.[[CodeUnitCount]]

22.2.7.4 GetStringIndex ( S, codePointIndex )

The abstract operation GetStringIndex takes arguments S (一个字符串) and codePointIndex (一个非负整数) and returns 一个非负整数. 按 6.1.4S 解释为 UTF-16 编码代码点序列,返回与代码点索引 codePointIndex 对应的代码单元索引(若存在)。否则返回 S 的长度。 It performs the following steps when called:

  1. 如果 S 是空字符串,返回 0。
  2. lenS 的长度。
  3. codeUnitCount 为 0。
  4. codePointCount 为 0。
  5. codeUnitCount < len 时重复,
    1. 如果 codePointCount = codePointIndex,返回 codeUnitCount
    2. cp 为 CodePointAt(S, codeUnitCount)。
    3. codeUnitCountcodeUnitCount + cp.[[CodeUnitCount]]
    4. codePointCountcodePointCount + 1。
  6. 返回 len

22.2.7.5 匹配记录(Match Records)

Match 记录 是用于封装正则匹配或捕获起止索引的记录值。

Match 记录具有 Table 70 中列出的字段。

Table 70: Match 记录字段
字段名 含义
[[StartIndex]] 一个非负整数 从字符串起始处开始(含)匹配开始的代码单元数量。
[[EndIndex]] 一个 ≥ [[StartIndex]] 的整数 从字符串起始处开始匹配结束(不含)位置的代码单元数量。

22.2.7.6 GetMatchString ( S, match )

The abstract operation GetMatchString takes arguments S (一个字符串) and match (一个 Match 记录) and returns 一个字符串. It performs the following steps when called:

  1. 断言:match.[[StartIndex]]match.[[EndIndex]]S 的长度。
  2. 返回 S 中从 match.[[StartIndex]]match.[[EndIndex]] 的子串。

22.2.7.7 GetMatchIndexPair ( S, match )

The abstract operation GetMatchIndexPair takes arguments S (一个字符串) and match (一个 Match 记录) and returns 一个数组. It performs the following steps when called:

  1. 断言:match.[[StartIndex]]match.[[EndIndex]]S 的长度。
  2. 返回 CreateArrayFromList𝔽(match.[[StartIndex]]), 𝔽(match.[[EndIndex]]) »)。

22.2.7.8 MakeMatchIndicesIndexPairArray ( S, indices, groupNames, hasGroups )

The abstract operation MakeMatchIndicesIndexPairArray takes arguments S (一个字符串), indices (一个由 Match 记录undefined 组成的列表), groupNames (一个由字符串或 undefined 组成的列表), and hasGroups (一个布尔值) and returns 一个数组. It performs the following steps when called:

  1. nindices 的元素数量。
  2. 断言:n < 232 - 1。
  3. 断言:groupNamesn - 1 个元素。
  4. 注:groupNames 列表的元素与 indices 列表自 indices[1] 起对齐。
  5. A 为 ! ArrayCreate(n)。
  6. 如果 hasGroupstrue,则
    1. groupsOrdinaryObjectCreate(null)。
  7. 否则,
    1. groupsundefined
  8. 执行 ! CreateDataPropertyOrThrow(A, "groups", groups)。
  9. 对每个整数 i(0 ≤ i < n,升序),执行
    1. matchIndicesindices[i]。
    2. 如果 matchIndices 不为 undefined,则
      1. matchIndexPairGetMatchIndexPair(S, matchIndices)。
    3. 否则,
      1. matchIndexPairundefined
    4. 执行 ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(i)), matchIndexPair)。
    5. 如果 i > 0,则
      1. sgroupNames[i - 1]。
      2. 如果 s 不为 undefined,则
        1. 断言:groups 不为 undefined
        2. 注:若多个组名为 sgroups 此时可能已有 s 属性;但由于 groups 是所有属性皆可写的数据属性普通对象CreateDataPropertyOrThrow 调用仍保证成功。
        3. 执行 ! CreateDataPropertyOrThrow(groups, s, matchIndexPair)。
  10. 返回 A

22.2.8 RegExp 实例的属性(Properties of RegExp Instances)

RegExp 实例是普通对象,从 RegExp 原型对象继承属性。RegExp 实例具有内部槽 [[OriginalSource]][[OriginalFlags]][[RegExpRecord]][[RegExpMatcher]][[RegExpMatcher]] 内部槽的值是该 RegExp 对象 Pattern 的抽象闭包表示。

Note

在 ECMAScript 2015 之前,RegExp 实例被指定为拥有自身数据属性 "source""global""ignoreCase""multiline"。这些属性现在被指定为 RegExp.prototype 的存取器属性。

RegExp 实例还具有以下属性:

22.2.8.1 lastIndex

"lastIndex" 属性的值指定下一次匹配开始的字符串索引。使用时将其强制转换为整数 Number(参见 22.2.7.2)。此属性具有 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }。

22.2.9 RegExp 字符串迭代器对象

RegExp String Iterator 是一个对象,表示针对某个特定 String 实例对象、以某个特定 RegExp 实例对象进行匹配时的特定迭代过程。RegExp String Iterator 对象没有命名构造函数;相反,它们通过调用某些 RegExp 实例对象的方法创建。

22.2.9.1 CreateRegExpStringIterator ( R, S, global, fullUnicode )

The abstract operation CreateRegExpStringIterator takes arguments R (一个对象), S (一个字符串), global (一个布尔值), and fullUnicode (一个布尔值) and returns 一个对象. It performs the following steps when called:

  1. iteratorOrdinaryObjectCreate(%RegExpStringIteratorPrototype%, « [[IteratingRegExp]], [[IteratedString]], [[Global]], [[Unicode]], [[Done]] »)。
  2. iterator.[[IteratingRegExp]]R
  3. iterator.[[IteratedString]]S
  4. iterator.[[Global]]global
  5. iterator.[[Unicode]]fullUnicode
  6. iterator.[[Done]]false
  7. 返回 iterator

22.2.9.2 %RegExpStringIteratorPrototype% 对象

%RegExpStringIteratorPrototype% 对象:

22.2.9.2.1 %RegExpStringIteratorPrototype%.next ( )

  1. Othis 值。
  2. O 不是对象,抛出 TypeError 异常。
  3. O 不具有 RegExp String Iterator 对象实例的全部内部槽(见 22.2.9.3),抛出 TypeError 异常。
  4. O.[[Done]]true,则
    1. 返回 CreateIteratorResultObject(undefined, true)。
  5. RO.[[IteratingRegExp]]
  6. SO.[[IteratedString]]
  7. globalO.[[Global]]
  8. fullUnicodeO.[[Unicode]]
  9. match 为 ? RegExpExec(R, S)。
  10. matchnull,则
    1. O.[[Done]]true
    2. 返回 CreateIteratorResultObject(undefined, true)。
  11. globalfalse,则
    1. O.[[Done]]true
    2. 返回 CreateIteratorResultObject(match, false)。
  12. matchStr 为 ? ToString(? Get(match, "0"))。
  13. matchStr 为空字符串,则
    1. thisIndex(? ToLength(? Get(R, "lastIndex")))。
    2. nextIndexAdvanceStringIndex(S, thisIndex, fullUnicode)。
    3. 执行 ? Set(R, "lastIndex", 𝔽(nextIndex), true)。
  14. 返回 CreateIteratorResultObject(match, false)。

22.2.9.2.2 %RegExpStringIteratorPrototype% [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "RegExp String Iterator"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

22.2.9.3 RegExp String Iterator 实例的属性

RegExp String Iterator 实例是普通对象,从内建对象 %RegExpStringIteratorPrototype% 继承属性。RegExp String Iterator 实例最初以 Table 71 中列出的内部槽创建。

Table 71: RegExp String Iterator 实例的内部槽
内部槽 类型 描述
[[IteratingRegExp]] an Object 用于迭代的正则表达式。IsRegExp([[IteratingRegExp]]) 初始为 true
[[IteratedString]] a String 当前被迭代的字符串值。
[[Global]] a Boolean 指示 [[IteratingRegExp]] 是否为全局模式。
[[Unicode]] a Boolean 指示 [[IteratingRegExp]] 是否处于 Unicode 模式。
[[Done]] a Boolean 指示迭代是否完成。

23 索引集合(Indexed Collections)

23.1 Array 对象

Array 是一种对某类属性名进行特殊处理的异质(exotic)对象。该特殊处理的定义见 10.4.2

23.1.1 Array 构造函数

Array 构造函数

  • %Array%
  • 是全局对象 "Array" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 Array。
  • 作为函数(而非构造函数)调用时同样创建并初始化一个新的 Array。因此函数调用 Array(…) 等价于使用相同参数的对象创建表达式 new Array(…)
  • 其行为随参数数量与类型不同而不同。
  • 可用作类定义 extends 子句的值。打算继承数组异质行为的子类构造函数必须包含对 Array 构造函数super 调用,以初始化作为数组异质对象的子类实例。但大多数 Array.prototype 方法是泛型的,不依赖其 this 为数组异质对象。

23.1.1.1 Array ( ...values )

此函数被调用时执行以下步骤:

  1. 若 NewTarget 为 undefined,令 newTarget 为活动函数对象;否则令 newTarget 为 NewTarget。
  2. proto 为 ? GetPrototypeFromConstructor(newTarget, "%Array.prototype%")。
  3. numberOfArgsvalues 中元素的数量。
  4. numberOfArgs = 0,则
    1. 返回 ! ArrayCreate(0, proto)。
  5. 否则若 numberOfArgs = 1,则
    1. lenvalues[0]。
    2. array 为 ! ArrayCreate(0, proto)。
    3. len 不是 Number,则
      1. 执行 ! CreateDataPropertyOrThrow(array, "0", len)。
      2. intLen1𝔽
    4. 否则,
      1. intLen 为 ! ToUint32(len)。
      2. SameValueZero(intLen, len) 为 false,抛出 RangeError 异常。
    5. 执行 ! Set(array, "length", intLen, true)。
    6. 返回 array
  6. 否则,
    1. 断言:numberOfArgs ≥ 2。
    2. array 为 ? ArrayCreate(numberOfArgs, proto)。
    3. k 为 0。
    4. k < numberOfArgs 时重复,
      1. Pk 为 ! ToString(𝔽(k))。
      2. itemKvalues[k]。
      3. 执行 ! CreateDataPropertyOrThrow(array, Pk, itemK)。
      4. k = k + 1。
    5. 断言:array"length" 属性数学值numberOfArgs
    6. 返回 array

23.1.2 Array 构造函数的属性

Array 构造函数

  • 具有 [[Prototype]] 内部槽,其值为 %Function.prototype%
  • 具有 "length" 属性,其值为 1𝔽
  • 具有以下属性:

23.1.2.1 Array.from ( items [ , mapper [ , thisArg ] ] )

此方法被调用时执行以下步骤:

  1. Cthis 值。
  2. mapperundefined,则
    1. mappingfalse
  3. 否则,
    1. IsCallable(mapper) 为 false,抛出 TypeError 异常。
    2. mappingtrue
  4. usingIterator 为 ? GetMethod(items, %Symbol.iterator%)。
  5. usingIterator 不为 undefined,则
    1. IsConstructor(C) 为 true,则
      1. A 为 ? Construct(C)。
    2. 否则,
      1. A 为 ! ArrayCreate(0)。
    3. iteratorRecord 为 ? GetIteratorFromMethod(items, usingIterator)。
    4. k 为 0。
    5. 重复,
      1. k ≥ 253 - 1,则
        1. errorThrowCompletion(新建的 TypeError 对象)。
        2. 返回 ? IteratorClose(iteratorRecord, error)。
      2. Pk 为 ! ToString(𝔽(k))。
      3. next 为 ? IteratorStepValue(iteratorRecord)。
      4. nextdone,则
        1. 执行 ? Set(A, "length", 𝔽(k), true)。
        2. 返回 A
      5. mappingtrue,则
        1. mappedValueCompletion(Call(mapper, thisArg, « next, 𝔽(k) »))。
        2. IfAbruptCloseIterator(mappedValue, iteratorRecord)。
      6. 否则,
        1. mappedValuenext
      7. defineStatusCompletion(CreateDataPropertyOrThrow(A, Pk, mappedValue))。
      8. IfAbruptCloseIterator(defineStatus, iteratorRecord)。
      9. k = k + 1。
  6. 注:items 不可迭代,假定为类数组对象
  7. arrayLike 为 ! ToObject(items)。
  8. len 为 ? LengthOfArrayLike(arrayLike)。
  9. IsConstructor(C) 为 true,则
    1. A 为 ? Construct(C, « 𝔽(len) »)。
  10. 否则,
    1. A 为 ? ArrayCreate(len)。
  11. k 为 0。
  12. k < len 时重复,
    1. Pk 为 ! ToString(𝔽(k))。
    2. kValue 为 ? Get(arrayLike, Pk)。
    3. mappingtrue,则
      1. mappedValue 为 ? Call(mapper, thisArg, « kValue, 𝔽(k) »)。
    4. 否则,
      1. mappedValuekValue
    5. 执行 ? CreateDataPropertyOrThrow(A, Pk, mappedValue)。
    6. k = k + 1。
  13. 执行 ? Set(A, "length", 𝔽(len), true)。
  14. 返回 A
Note

此方法是刻意设计的通用工厂方法;其 this 不必为 Array 构造函数,因此可被其他可用单个数值参数调用的构造函数继承或转移使用。

23.1.2.2 Array.isArray ( arg )

此函数被调用时执行以下步骤:

  1. 返回 ? IsArray(arg)。

23.1.2.3 Array.of ( ...items )

此方法被调用时执行以下步骤:

  1. lenitems 中元素数量。
  2. lenNumber𝔽(len)。
  3. Cthis 值。
  4. IsConstructor(C) 为 true,则
    1. A 为 ? Construct(C, « lenNumber »)。
  5. 否则,
    1. A 为 ? ArrayCreate(len)。
  6. k 为 0。
  7. k < len 时重复,
    1. kValueitems[k]。
    2. Pk 为 ! ToString(𝔽(k))。
    3. 执行 ? CreateDataPropertyOrThrow(A, Pk, kValue)。
    4. k = k + 1。
  8. 执行 ? Set(A, "length", lenNumber, true)。
  9. 返回 A
Note

此方法是刻意设计的通用工厂方法;其 this 不必为 Array 构造函数,因此可被其它构造函数继承或转移使用。

23.1.2.4 Array.prototype

Array.prototype 的值是 Array 原型对象

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

23.1.2.5 get Array [ %Symbol.species% ]

Array[%Symbol.species%] 是一个存取器属性,其 set 访问器为 undefined。其 get 访问器被调用时执行:

  1. 返回 this 值。

该函数 "name" 属性值为 "get [Symbol.species]"

Note

Array 原型方法通常使用其 this构造函数来创建派生对象;子类可通过重定义 %Symbol.species% 覆盖该默认行为。

23.1.3 Array 原型对象的属性

Array 原型对象

  • %Array.prototype%
  • 是一个 Array 异质对象,具有该类对象规定的内部方法。
  • "length" 属性,其初始值为 +0𝔽,属性特性为 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }。
  • 具有 [[Prototype]] 内部槽,其值为 %Object.prototype%
Note

指定为数组异质对象以保持与 ECMAScript 2015 之前代码的兼容性。

23.1.3.1 Array.prototype.at ( index )

  1. O 为 ? ToObject(this value)。
  2. len 为 ? LengthOfArrayLike(O)。
  3. relativeIndex 为 ? ToIntegerOrInfinity(index)。
  4. relativeIndex ≥ 0,则
    1. k = relativeIndex
  5. 否则,
    1. k = len + relativeIndex
  6. k < 0 或 klen,返回 undefined
  7. 返回 ? Get(O, ! ToString(𝔽(k)))。

23.1.3.2 Array.prototype.concat ( ...items )

返回一个数组,包含对象自身元素后接各参数的数组元素。

调用时执行:

  1. O 为 ? ToObject(this value)。
  2. A 为 ? ArraySpeciesCreate(O, 0)。
  3. n = 0。
  4. O 前置到 items
  5. items 中每个元素 E
    1. spreadable 为 ? IsConcatSpreadable(E)。
    2. spreadabletrue
      1. len 为 ? LengthOfArrayLike(E)。
      2. n + len > 253 - 1,抛出 TypeError
      3. k = 0。
      4. k < len
        1. Pk 为 ! ToString(𝔽(k))。
        2. exists 为 ? HasProperty(E, Pk)。
        3. existstrue
          1. subElement 为 ? Get(E, Pk)。
          2. 执行 ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), subElement)。
        4. n = n + 1。
        5. k = k + 1。
    3. 否则,
      1. 注:E 作为单个元素添加。
      2. n ≥ 253 - 1,抛出 TypeError
      3. 执行 ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), E)。
      4. n = n + 1。
  6. 执行 ? Set(A, "length", 𝔽(n), true)。
  7. 返回 A

此方法 "length" 属性为 1𝔽

Note 1

显式设置 "length"(参见 6)以确保尾部存在空洞或 A 不是内置数组时长度正确。

Note 2

本方法为泛型;this 不要求是 Array,可转移给其他对象使用。

23.1.3.2.1 IsConcatSpreadable ( O )

The abstract operation IsConcatSpreadable takes argument O (an ECMAScript language value) and returns 包含布尔值的正常完成或抛出完成. It performs the following steps when called:

  1. O 不是对象,返回 false
  2. spreadable 为 ? Get(O, %Symbol.isConcatSpreadable%)。
  3. spreadable 不为 undefined,返回 ToBoolean(spreadable)。
  4. 返回 ? IsArray(O)。

23.1.3.3 Array.prototype.constructor

Array.prototype.constructor 的初始值为 %Array%

23.1.3.4 Array.prototype.copyWithin ( target, start [ , end ] )

Note 1

end 可选;缺省使用 this 的长度。

Note 2

负的 target / start / end 分别视为 length + 参数

调用时执行:

  1. O 为 ? ToObject(this value)。
  2. len 为 ? LengthOfArrayLike(O)。
  3. relativeTarget 为 ? ToIntegerOrInfinity(target)。
  4. relativeTarget = -∞,令 to = 0。
  5. 否则若 relativeTarget < 0,令 to = max(len + relativeTarget, 0)。
  6. 否则令 to = min(relativeTarget, len)。
  7. relativeStart 为 ? ToIntegerOrInfinity(start)。
  8. relativeStart = -∞,令 from = 0。
  9. 否则若 relativeStart < 0,令 from = max(len + relativeStart, 0)。
  10. 否则令 from = min(relativeStart, len)。
  11. endundefined,令 relativeEnd = len;否则令 relativeEnd = ? ToIntegerOrInfinity(end)。
  12. relativeEnd = -∞,令 final = 0。
  13. 否则若 relativeEnd < 0,令 final = max(len + relativeEnd, 0)。
  14. 否则令 final = min(relativeEnd, len)。
  15. count = min(final - from, len - to)。
  16. from < toto < from + count,则
    1. direction = -1。
    2. from = from + count - 1。
    3. to = to + count - 1。
  17. 否则令 direction = 1。
  18. count > 0:
    1. fromKey = ! ToString(𝔽(from))。
    2. toKey = ! ToString(𝔽(to))。
    3. fromPresent = ? HasProperty(O, fromKey)。
    4. fromPresenttrue
      1. fromValue = ? Get(O, fromKey)。
      2. 执行 ? Set(O, toKey, fromValue, true)。
    5. 否则
      1. 执行 ? DeletePropertyOrThrow(O, toKey)。
    6. from += direction
    7. to += direction
    8. count -= 1。
  19. 返回 O
Note 3

方法为泛型,可转移到其它对象。

23.1.3.5 Array.prototype.entries ( )

调用时执行:

  1. O 为 ? ToObject(this value)。
  2. 返回 CreateArrayIterator(O, key+value)。

23.1.3.6 Array.prototype.every ( callback [ , thisArg ] )

Note 1

依次(升序)对存在的元素调用 callback,若遇到返回 false 的元素立即返回 false;否则返回 true。空数组结果为 true

执行步骤:

  1. O 为 ? ToObject(this value)。
  2. len 为 ? LengthOfArrayLike(O)。
  3. IsCallable(callback) 为 false,抛出 TypeError
  4. k = 0。
  5. k < len
    1. Pk = ! ToString(𝔽(k))。
    2. kPresent = ? HasProperty(O, Pk)。
    3. kPresent
      1. kValue = ? Get(O, Pk)。
      2. testResult = ToBoolean(? Call(callback, thisArg, « kValue, 𝔽(k), O »))。
      3. testResultfalse,返回 false
    4. k = k + 1。
  6. 返回 true
Note 2

泛型方法,可转移使用。

23.1.3.7 Array.prototype.fill ( value [ , start [ , end ] ] )

Note 1

start 缺省 +0𝔽end 缺省为长度;负值按长度偏移。

执行步骤:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. relativeStart = ? ToIntegerOrInfinity(start)。
  4. relativeStart = -∞,k = 0;否则若 < 0,k = max(len + relativeStart, 0);否则 k = min(relativeStart, len)。
  5. endundefinedrelativeEnd = len;否则 relativeEnd = ? ToIntegerOrInfinity(end)。
  6. relativeEnd = -∞,final = 0;否则若 < 0,final = max(len + relativeEnd, 0);否则 final = min(relativeEnd, len)。
  7. k < final
    1. Pk = ! ToString(𝔽(k))。
    2. Set(O, Pk, value, true)。
    3. k++。
  8. 返回 O
Note 2

泛型方法。

23.1.3.8 Array.prototype.filter ( callback [ , thisArg ] )

Note 1

对现有元素调用 callback,收集返回 true 的值构成新数组。

执行步骤:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. IsCallable(callback) 为 falseTypeError
  4. A = ? ArraySpeciesCreate(O, 0)。
  5. k = 0;to = 0。
  6. k < len
    1. Pk = ! ToString(𝔽(k))。
    2. kPresent = ? HasProperty(O, Pk)。
    3. kPresent
      1. kValue = ? Get(O, Pk)。
      2. selected = ToBoolean(? Call(callback, thisArg, « kValue, 𝔽(k), O »))。
      3. selected
        1. CreateDataPropertyOrThrow(A, ! ToString(𝔽(to)), kValue)。
        2. to++。
    4. k++。
  7. 返回 A
Note 2

泛型。

23.1.3.9 Array.prototype.find ( predicate [ , thisArg ] )

Note 1

升序查找首个使 predicate 结果为真值的元素,找不到返回 undefined

执行步骤:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. findRec = ? FindViaPredicate(O, len, ascending, predicate, thisArg)。
  4. 返回 findRec.[[Value]]
Note 2

泛型。

23.1.3.10 Array.prototype.findIndex ( predicate [ , thisArg ] )

Note 1

升序查找首个满足谓词的索引,未找到返回 -1。

执行:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. findRec = ? FindViaPredicate(O, len, ascending, predicate, thisArg)。
  4. 返回 findRec.[[Index]]
Note 2

泛型。

23.1.3.11 Array.prototype.findLast ( predicate [ , thisArg ] )

Note 1

降序查找首个满足谓词的元素,未找到返回 undefined

执行:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. findRec = ? FindViaPredicate(O, len, descending, predicate, thisArg)。
  4. 返回 findRec.[[Value]]
Note 2

泛型。

23.1.3.12 Array.prototype.findLastIndex ( predicate [ , thisArg ] )

Note 1

降序查找首个满足谓词的索引,未找到返回 -1。

执行:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. findRec = ? FindViaPredicate(O, len, descending, predicate, thisArg)。
  4. 返回 findRec.[[Index]]
Note 2

泛型。

23.1.3.12.1 FindViaPredicate ( O, len, direction, predicate, thisArg )

The abstract operation FindViaPredicate takes arguments O (an Object), len (a non-negative integer), direction (ascending or descending), predicate (an ECMAScript language value), and thisArg (an ECMAScript language value) and returns 返回含 [[Index]][[Value]] 字段的记录或抛出完成.

遍历 O 的索引(升序或降序)调用 predicate,返回首个真值对应的索引与值;若无则索引 -1𝔽,值 undefined

predicate 接收 (元素值, 索引, 被遍历对象)。

thisArg 作为 this 使用。

不直接修改 Opredicate 可修改。

遍历范围在开始前确定;新增元素不访问;修改元素按访问时值;删除后再访问的仍按原序列访问(TypedArray 特例除外按语义)。

It performs the following steps when called:

  1. IsCallable(predicate) 为 falseTypeError
  2. directionascending
    1. indices 为 [0, …, len-1] 升序列表。
  3. 否则,
    1. indices 为 [0, …, len-1] 降序列表。
  4. indices 中每个整数 k
    1. Pk = ! ToString(𝔽(k))。
    2. 注:若 OTypedArray,调用 Get正常完成
    3. kValue = ? Get(O, Pk)。
    4. testResult = ? Call(predicate, thisArg, « kValue, 𝔽(k), O »)。
    5. ToBoolean(testResult) 为 true,返回 { [[Index]]: 𝔽(k), [[Value]]: kValue }。
  5. 返回 { [[Index]]: -1𝔽, [[Value]]: undefined }。

23.1.3.13 Array.prototype.flat ( [ depth ] )

调用时执行:

  1. O = ? ToObject(this value)。
  2. sourceLen = ? LengthOfArrayLike(O)。
  3. depthNum = 1。
  4. depthundefined
    1. depthNum = ? ToIntegerOrInfinity(depth)。
    2. depthNum < 0,设为 0。
  5. A = ? ArraySpeciesCreate(O, 0)。
  6. ? FlattenIntoArray(A, O, sourceLen, 0, depthNum)。
  7. 返回 A

23.1.3.13.1 FlattenIntoArray ( target: an Object, source: an Object, sourceLen: a non-negative integer, start: a non-negative integer, depth: a non-negative integer or +∞, optional mapperFunction: a function object, optional thisArg: an ECMAScript language value, ): either a normal completion containing a non-negative integer or a throw completion

  1. 断言:若提供 mapperFunction,则 IsCallable(mapperFunction) 为 truethisArg 存在且 depth = 1。
  2. targetIndex = start
  3. sourceIndex = +0𝔽
  4. (sourceIndex) < sourceLen
    1. P = ! ToString(sourceIndex)。
    2. exists = ? HasProperty(source, P)。
    3. exists
      1. element = ? Get(source, P)。
      2. 若有 mapperFunctionelement = ? Call(mapperFunction, thisArg, « element, sourceIndex, source »)。
      3. shouldFlatten = false
      4. depth > 0:shouldFlatten = ? IsArray(element)。
      5. shouldFlatten
        1. depth = +∞,newDepth = +∞;否则 newDepth = depth - 1。
        2. elementLen = ? LengthOfArrayLike(element)。
        3. targetIndex = ? FlattenIntoArray(target, element, elementLen, targetIndex, newDepth)。
      6. 否则:
        1. targetIndex ≥ 253 - 1 抛 TypeError
        2. CreateDataPropertyOrThrow(target, ! ToString(𝔽(targetIndex)), element)。
        3. targetIndex++。
    4. sourceIndex += 1𝔽
  5. 返回 targetIndex

23.1.3.14 Array.prototype.flatMap ( mapperFunction [ , thisArg ] )

执行步骤:

  1. O = ? ToObject(this value)。
  2. sourceLen = ? LengthOfArrayLike(O)。
  3. IsCallable(mapperFunction) 为 falseTypeError
  4. A = ? ArraySpeciesCreate(O, 0)。
  5. ? FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, thisArg)。
  6. 返回 A

23.1.3.15 Array.prototype.forEach ( callback [ , thisArg ] )

Note 1

对存在元素升序调用 callback,不返回聚合值,缺失元素略过。

步骤:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. IsCallable(callback) 为 falseTypeError
  4. k = 0。
  5. k < len
    1. Pk = ! ToString(𝔽(k))。
    2. kPresent = ? HasProperty(O, Pk)。
    3. kPresent
      1. kValue = ? Get(O, Pk)。
      2. ? Call(callback, thisArg, « kValue, 𝔽(k), O »)。
    4. k++。
  6. 返回 undefined
Note 2

泛型。

23.1.3.16 Array.prototype.includes ( searchElement [ , fromIndex ] )

Note 1

使用 SameValueZero 比较,找到即返回 true,未找到 false;不跳过空洞(空洞按 undefined)。

步骤:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. len = 0 返回 false
  4. n = ? ToIntegerOrInfinity(fromIndex)。
  5. 断言:若 fromIndexundefinedn = 0。
  6. n = +∞ 返回 false;若 n = -∞ 令 n = 0。
  7. n ≥ 0:k = n;否则 k = len + n,若 k < 0 则 k = 0。
  8. k < len
    1. elementK = ? Get(O, ! ToString(𝔽(k)))。
    2. SameValueZero(searchElement, elementK) 为 true 返回 true
    3. k++。
  9. 返回 false
Note 2

泛型。

Note 3

区别于 indexOf:使用 SameValueZero 并且不跳过空洞。

23.1.3.17 Array.prototype.indexOf ( searchElement [ , fromIndex ] )

使用 IsStrictlyEqual 升序查找首个匹配索引,未找到返回 -1𝔽(跳过空洞)。

Note 1

fromIndex 缺省 +0𝔽;可为负表示从末尾偏移。

步骤:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. len = 0 返回 -1𝔽
  4. n = ? ToIntegerOrInfinity(fromIndex)。
  5. 断言:fromIndexundefinedn = 0。
  6. n = +∞ 返回 -1𝔽;若 n = -∞ 置 0。
  7. n ≥ 0:k = n;否则 k = len + n,若 k < 0 则 0。
  8. k < len
    1. Pk = ! ToString(𝔽(k))。
    2. kPresent = ? HasProperty(O, Pk)。
    3. kPresent
      1. elementK = ? Get(O, Pk)。
      2. IsStrictlyEqual(searchElement, elementK) 为 true 返回 𝔽(k)。
    4. k++。
  9. 返回 -1𝔽
Note 2

泛型。

23.1.3.18 Array.prototype.join ( separator )

将元素转换为字符串并用分隔符拼接;缺省分隔符为逗号。

步骤:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. separatorundefinedsep = ",";否则 sep = ? ToString(separator)。
  4. R = 空字符串;k = 0。
  5. k < len
    1. k > 0,R = R + sep
    2. element = ? Get(O, ! ToString(𝔽(k)))。
    3. element 既非 undefined 亦非 null
      1. S = ? ToString(element)。
      2. R = R + S
    4. k++。
  6. 返回 R
Note

泛型。

23.1.3.19 Array.prototype.keys ( )

步骤:

  1. O = ? ToObject(this value)。
  2. 返回 CreateArrayIterator(O, key)。

23.1.3.20 Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] )

Note 1

自右向左使用 IsStrictlyEqual 查找,返回最大匹配索引,否则 -1。

步骤:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. len = 0 返回 -1𝔽
  4. 若提供 fromIndexn = ? ToIntegerOrInfinity(fromIndex);否则 n = len - 1。
  5. n = -∞ 返回 -1𝔽
  6. n ≥ 0:k = min(n, len - 1);否则 k = len + n
  7. k ≥ 0:
    1. Pk = ! ToString(𝔽(k))。
    2. kPresent = ? HasProperty(O, Pk)。
    3. kPresent
      1. elementK = ? Get(O, Pk)。
      2. IsStrictlyEqual(searchElement, elementK) 为 true 返回 𝔽(k)。
    4. k--。
  8. 返回 -1𝔽
Note 2

泛型。

23.1.3.21 Array.prototype.map ( callback [ , thisArg ] )

Note 1

升序对存在元素调用 callback,生成新数组。

步骤:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. IsCallable(callback) 为 falseTypeError
  4. A = ? ArraySpeciesCreate(O, len)。
  5. k = 0。
  6. k < len
    1. Pk = ! ToString(𝔽(k))。
    2. kPresent = ? HasProperty(O, Pk)。
    3. kPresent
      1. kValue = ? Get(O, Pk)。
      2. mappedValue = ? Call(callback, thisArg, « kValue, 𝔽(k), O »)。
      3. CreateDataPropertyOrThrow(A, Pk, mappedValue)。
    4. k++。
  7. 返回 A
Note 2

泛型。

23.1.3.22 Array.prototype.pop ( )

Note 1

移除并返回最后一个元素。

步骤:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. len = 0:
    1. Set(O, "length", +0𝔽, true)。
    2. 返回 undefined
  4. 否则:
    1. newLen = 𝔽(len - 1)。
    2. index = ! ToString(newLen)。
    3. element = ? Get(O, index)。
    4. DeletePropertyOrThrow(O, index)。
    5. Set(O, "length", newLen, true)。
    6. 返回 element
Note 2

泛型。

23.1.3.23 Array.prototype.push ( ...items )

Note 1

将参数按顺序追加到末尾,返回新长度。

步骤:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. argCount = items 长度。
  4. len + argCount > 253 - 1 抛 TypeError
  5. 对每个 E 属于 items
    1. Set(O, ! ToString(𝔽(len)), E, true)。
    2. len++。
  6. Set(O, "length", 𝔽(len), true)。
  7. 返回 𝔽(len)。

此方法 "length" 属性为 1𝔽

Note 2

泛型。

23.1.3.24 Array.prototype.reduce ( callback [ , initialValue ] )

Note 1

从左到右归约;若未提供 initialValue,使用首个存在元素作为累加器起始;空数组且无初始值抛 TypeError

步骤:

  1. O = ? ToObject(this value)。
  2. len = ? LengthOfArrayLike(O)。
  3. IsCallable(callback) 为 falseTypeError
  4. len = 0 且无 initialValueTypeError
  5. k = 0;accumulator = undefined
  6. 若提供 initialValueaccumulator = initialValue
  7. 否则:
    1. kPresent = false
    2. 当 !kPresentk < len
      1. Pk = ! ToString(𝔽(k))。
      2. kPresent = ? HasProperty(O, Pk)。
      3. kPresentaccumulator = ? Get(O, Pk)。
      4. k++。
    3. 若 !kPresentTypeError
  8. k < len
    1. Pk = ! ToString(𝔽(k))。
    2. kPresent = ? HasProperty(O, Pk)。
    3. kPresent
      1. kValue = ? Get(O, Pk)。
      2. accumulator = ? Call(callback, undefined, « accumulator, kValue, 𝔽(k), O »)。
    4. k++。
  9. 返回 accumulator
Note 2

泛型。

23.1.3.25 Array.prototype.reduceRight ( callback [ , initialValue ] )

Note 1

从右向左归约,规则同 reduce 但方向相反。

步骤:

  1. O = ? ToObject(this value),len = ? LengthOfArrayLike(O)。
  2. IsCallable(callback) 为 falseTypeError
  3. len = 0 且无 initialValueTypeError
  4. k = len - 1;accumulator = undefined
  5. 若有初始值:accumulator = initialValue
  6. 否则:
    1. kPresent = false
    2. 当 !kPresentk ≥ 0:
      1. Pk = ! ToString(𝔽(k))。
      2. kPresent = ? HasProperty(O, Pk)。
      3. kPresentaccumulator = ? Get(O, Pk)。
      4. k--。
    3. 若 !kPresentTypeError
  7. k ≥ 0:
    1. Pk = ! ToString(𝔽(k))。
    2. kPresent = ? HasProperty(O, Pk)。
    3. kPresent
      1. kValue = ? Get(O, Pk)。
      2. accumulator = ? Call(callback, undefined, « accumulator, kValue, 𝔽(k), O »)。
    4. k--。
  8. 返回 accumulator
Note 2

泛型。

23.1.3.26 Array.prototype.reverse ( )

Note 1

就地反转顺序并返回该对象。

步骤:

  1. O = ? ToObject(this value),len = ? LengthOfArrayLike(O)。
  2. middle = floor(len/2),lower = 0。
  3. lowermiddle
    1. upper = len - lower - 1。
    2. upperP = ! ToString(𝔽(upper)),lowerP = ! ToString(𝔽(lower))。
    3. lowerExists = ? HasProperty(O, lowerP);若真:lowerValue = ? Get(O, lowerP)。
    4. upperExists = ? HasProperty(O, upperP);若真:upperValue = ? Get(O, upperP)。
    5. 若二者皆真:交换;仅上真:下设上并删上;仅下真:删下并设上;皆假:无操作。
    6. lower++。
  4. 返回 O
Note 2

泛型。

23.1.3.27 Array.prototype.shift ( )

移除首元素并返回。

步骤:

  1. O = ? ToObject(this value),len = ? LengthOfArrayLike(O)。
  2. len = 0:? Set(O, "length", +0𝔽, true);返回 undefined
  3. first = ? Get(O, "0")。
  4. k = 1。
  5. k < len
    1. from = ! ToString(𝔽(k)),to = ! ToString(𝔽(k-1))。
    2. fromPresent = ? HasProperty(O, from)。
    3. 若真:fromValue = ? Get(O, from);? Set(O, to, fromValue, true);否则 Delete to
    4. k++。
  6. DeletePropertyOrThrow(O, ! ToString(𝔽(len-1)))。
  7. Set(O, "length", 𝔽(len-1), true)。
  8. 返回 first
Note

泛型。

23.1.3.28 Array.prototype.slice ( start, end )

返回从 start(含)到 end(不含)之间的浅拷贝;负值按长度偏移。

步骤:

  1. O = ? ToObject(this value),len = ? LengthOfArrayLike(O)。
  2. relativeStart = ? ToIntegerOrInfinity(start)。
  3. 若 = -∞,k = 0;否则若 <0,k = max(len+relativeStart,0);否则 k = min(relativeStart, len)。
  4. relativeEnd = (endundefinedlen : ? ToIntegerOrInfinity(end))。
  5. relativeEnd = -∞,final = 0;若 <0,final = max(len+relativeEnd,0);否则 final = min(relativeEnd, len)。
  6. count = max(final - k, 0)。
  7. A = ? ArraySpeciesCreate(O, count)。
  8. n = 0。
  9. k < final
    1. Pk = ! ToString(𝔽(k))。
    2. kPresent = ? HasProperty(O, Pk)。
    3. 若真:kValue = ? Get(O, Pk);? CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), kValue)。
    4. k++;n++。
  10. Set(A, "length", 𝔽(n), true)。
  11. 返回 A
Note 1

显式设置长度确保非内置数组时正确。

Note 2

泛型。

23.1.3.29 Array.prototype.some ( callback [ , thisArg ] )

Note 1

升序测试是否存在使 callback 为真值的元素;空数组返回 false

步骤:

  1. O = ? ToObject(this value),len = ? LengthOfArrayLike(O)。
  2. IsCallable(callback) 为 falseTypeError
  3. k = 0。
  4. k < len
    1. Pk = ! ToString(𝔽(k))。
    2. kPresent = ? HasProperty(O, Pk)。
    3. 若真:
      1. kValue = ? Get(O, Pk)。
      2. testResult = ToBoolean(? Call(callback, thisArg, « kValue, 𝔽(k), O »))。
      3. testResulttrue 返回 true
    4. k++。
  5. 返回 false
Note 2

泛型。

23.1.3.30 Array.prototype.sort ( comparator )

对数组元素排序;若提供 comparator,必须可调用并按返回值符号决定顺序。

步骤:

  1. comparatorundefined 且不可调用,抛 TypeError
  2. obj = ? ToObject(this value)。
  3. len = ? LengthOfArrayLike(obj)。
  4. SortCompare = 抽象闭包(x, y):? CompareArrayElements(x, y, comparator)。
  5. sortedList = ? SortIndexedProperties(obj, len, SortCompare, skip-holes)。
  6. itemCount = sortedList 长度。
  7. j = 0。
  8. j < itemCount
    1. Set(obj, ! ToString(𝔽(j)), sortedList[j], true)。
    2. j++。
  9. 注:跳过空洞后删除剩余索引以保留空洞数量。
  10. j < len
    1. DeletePropertyOrThrow(obj, ! ToString(𝔽(j)))。
    2. j++。
  11. 返回 obj
Note 1

undefined 排序到末尾,其后是不存在的属性。

Note 2

ToString 期间的方法调用可能使比较器不一致。

Note 3

泛型。

23.1.3.30.1 SortIndexedProperties ( obj: an Object, len: a non-negative integer, SortCompare: an Abstract Closure with two parameters, holes: skip-holes or read-through-holes, ): either a normal completion containing a List of ECMAScript language values or a throw completion

  1. items = 空列表;k = 0。
  2. k < len
    1. Pk = ! ToString(𝔽(k))。
    2. holes = skip-holeskRead = ? HasProperty(obj, Pk);否则 kRead = true
    3. kReadkValue = ? Get(obj, Pk);追加 kValue
    4. k++。
  3. 以实现定义次序使用 SortCompare 排序 items;若出现 abrupt 完成即停止并返回。
  4. 返回 items

排序顺序是上述算法步骤 3 完成后 items 的排列顺序。如果对于 items 的元素,SortCompare 不是一个一致的比较器,则排序顺序是实现自定的。当由 Array.prototype.sortArray.prototype.toSorted 调用 SortIndexedProperties 时,如果 comparatorundefined,并且对传给 SortCompare 的任何特定值进行的所有 ToString 应用不会产生相同结果,则排序顺序同样是实现自定的。

除非指定排序顺序是实现自定的,否则它必须满足以下全部条件:

  • 存在某个对小于 itemCount 的非负整数的数学排列 π,使得对每个小于 itemCount 的非负整数 j,元素 old[j]new[π(j)] 完全相同。
  • 然后对所有非负整数 jk(各自小于 itemCount),如果 (SortCompare(old[j], old[k])) < 0,则 π(j) < π(k)
  • 并且对于所有满足 j < k < itemCount 的非负整数 jk,如果 (SortCompare(old[j], old[k])) = 0,则 π(j) < π(k);即排序是稳定的。

这里记号 old[j] 用于指代执行步骤 3 之前的 items[j],记号 new[j] 用于指代执行步骤 3 之后的 items[j]

若一个抽象闭包或函数 comparator 对一组值 S 满足下述所有要求,则称其为该集合的一个一致的比较器。对集合 S 中(可能相同)的所有值 abc,记号 a <C b 表示 (comparator(a, b)) < 0a =C b 表示 (comparator(a, b)) = 0a >C b 表示 (comparator(a, b)) > 0

  • 调用 comparator(a, b) 时,对于特定的值对 ab 总是返回相同的值 v。此外,v 是一个 Number,且 v 不是 NaN。注意这意味着对于给定的 aba <C ba =C ba >C b 三者中恰有一个为真。
  • 调用 comparator(a, b) 不会修改 objobj 原型链上的任何对象。
  • a =C a(自反性)
  • a =C b,则 b =C a(对称性)
  • a =C bb =C c,则 a =C c(=C 的传递性)
  • a <C bb <C c,则 a <C c(<C 的传递性)
  • a >C bb >C c,则 a >C c(>C 的传递性)
Note

上述条件是充分且必要的,以确保 comparator 将集合 S 划分为等价类,并且这些等价类是全序的。

23.1.3.30.2 CompareArrayElements ( x: an ECMAScript language value, y: an ECMAScript language value, comparator: a function object or undefined, ): either a normal completion containing a Number or an abrupt completion

  1. xyundefined 返回 +0𝔽
  2. xundefined 返回 1𝔽
  3. yundefined 返回 -1𝔽
  4. comparatorundefined
    1. v = ? ToNumber(? Call(comparator, undefined, « x, y »))。
    2. vNaN 返回 +0𝔽
    3. 返回 v
  5. xString = ? ToString(x)。
  6. yString = ? ToString(y)。
  7. xSmaller = ! IsLessThan(xString, yString, true)。
  8. xSmallertrue 返回 -1𝔽
  9. ySmaller = ! IsLessThan(yString, xString, true)。
  10. ySmallertrue 返回 1𝔽
  11. 返回 +0𝔽

23.1.3.31 Array.prototype.splice ( start, deleteCount, ...items )

Note 1

start 删除 deleteCount 个元素并以 items 插入,返回被删除元素数组。

步骤:

  1. O = ? ToObject(this value);len = ? LengthOfArrayLike(O)。
  2. relativeStart = ? ToIntegerOrInfinity(start)。
  3. 若 = -∞,actualStart = 0;否则若 <0,actualStart = max(len+relativeStart,0);否则 = min(relativeStart, len)。
  4. itemCount = items 长度。
  5. start 不存在:actualDeleteCount = 0。
  6. 否则若 deleteCount 不存在:actualDeleteCount = len - actualStart
  7. 否则 dc = ? ToIntegerOrInfinity(deleteCount);actualDeleteCount = clamp(dc, 0, len - actualStart)。
  8. len + itemCount - actualDeleteCount > 253-1 抛 TypeError
  9. A = ? ArraySpeciesCreate(O, actualDeleteCount)。
  10. k = 0。当 k < actualDeleteCount
    1. from = ! ToString(𝔽(actualStart + k))。
    2. 若 ? HasProperty(O, from):
      1. fromValue = ? Get(O, from)。
      2. CreateDataPropertyOrThrow(A, ! ToString(𝔽(k)), fromValue)。
    3. k++。
  11. Set(A, "length", 𝔽(actualDeleteCount), true)。
  12. itemCount < actualDeleteCount
    1. k = actualStart
    2. k < (len - actualDeleteCount):
      1. from = ! ToString(𝔽(k + actualDeleteCount))。
      2. to = ! ToString(𝔽(k + itemCount))。
      3. 若 ? HasProperty(O, from):fromValue = ? Get(O, from);? Set(O, to, fromValue, true);否则 Delete to
      4. k++。
    3. k = len
    4. k > (len - actualDeleteCount + itemCount):
      1. DeletePropertyOrThrow(O, ! ToString(𝔽(k-1)))。
      2. k--。
  13. 否则若 itemCount > actualDeleteCount
    1. k = (len - actualDeleteCount)。
    2. k > actualStart
      1. from = ! ToString(𝔽(k + actualDeleteCount -1))。
      2. to = ! ToString(𝔽(k + itemCount -1))。
      3. 若 ? HasProperty(O, from):fromValue = ? Get(O, from);? Set(O, to, fromValue, true);否则 Delete to
      4. k--。
  14. k = actualStart
  15. 对每个 Eitems:? Set(O, ! ToString(𝔽(k)), E, true);k++。
  16. Set(O, "length", 𝔽(len - actualDeleteCount + itemCount), true)。
  17. 返回 A
Note 2

显式设置长度确保非内置数组仍正确。

Note 3

泛型。

23.1.3.32 Array.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

支持 ECMA-402 的实现按其规范实现;否则使用此处规范。两个可选参数的意义由 ECMA-402 定义,未实现该 API 时不得另作他用。

Note 1

ECMA-402 第一版未替换此方法的规范。

步骤:

  1. array = ? ToObject(this value),len = ? LengthOfArrayLike(array)。
  2. separator = 实现定义的、符合当前区域设置的列表分隔符(如 ", ")。
  3. R = "";k = 0。
  4. k < len
    1. k > 0:R = R + separator
    2. element = ? Get(array, ! ToString(𝔽(k)))。
    3. elementundefined 且非 null
      1. S = ? ToString(? Invoke(element, "toLocaleString"))。
      2. R = R + S
    4. k++。
  5. 返回 R
Note 2

toString 类似,但使用区域化的元素表示与分隔符。

Note 3

泛型。

23.1.3.33 Array.prototype.toReversed ( )

返回一个新数组,其元素为原数组的反向拷贝。

  1. O = ? ToObject(this value),len = ? LengthOfArrayLike(O)。
  2. A = ? ArrayCreate(len)。
  3. k = 0。
  4. k < len
    1. from = ! ToString(𝔽(len - k - 1))。
    2. Pk = ! ToString(𝔽(k))。
    3. fromValue = ? Get(O, from)。
    4. CreateDataPropertyOrThrow(A, Pk, fromValue)。
    5. k++。
  5. 返回 A

23.1.3.34 Array.prototype.toSorted ( comparator )

返回排序后的新数组(不修改原数组)。

  1. comparatorundefined 且不可调用,抛 TypeError
  2. O = ? ToObject(this value),len = ? LengthOfArrayLike(O)。
  3. A = ? ArrayCreate(len)。
  4. SortCompare = 抽象闭包(x, y):? CompareArrayElements(x, y, comparator)。
  5. sortedList = ? SortIndexedProperties(O, len, SortCompare, read-through-holes)。
  6. j = 0。
  7. j < len
    1. CreateDataPropertyOrThrow(A, ! ToString(𝔽(j)), sortedList[j])。
    2. j++。
  8. 返回 A

23.1.3.35 Array.prototype.toSpliced ( start, skipCount, ...items )

返回应用类 splice 操作后的新数组(不修改原数组)。

  1. O = ? ToObject(this value),len = ? LengthOfArrayLike(O)。
  2. relativeStart = ? ToIntegerOrInfinity(start)。
  3. 若 = -∞,actualStart = 0;否则若 <0,actualStart = max(len+relativeStart,0);否则 actualStart = min(relativeStart, len)。
  4. insertCount = items 长度。
  5. start 不存在:actualSkipCount = 0;否则若 skipCount 不存在:actualSkipCount = len - actualStart;否则 sc = ? ToIntegerOrInfinity(skipCount);actualSkipCount = clamp(sc, 0, len-actualStart)。
  6. newLen = len + insertCount - actualSkipCount
  7. newLen > 253-1 抛 TypeError
  8. A = ? ArrayCreate(newLen)。
  9. i = 0;r = actualStart + actualSkipCount
  10. i < actualStart
    1. Pi = ! ToString(𝔽(i))。
    2. iValue = ? Get(O, Pi)。
    3. CreateDataPropertyOrThrow(A, Pi, iValue)。
    4. i++。
  11. items 中每个 E
    1. Pi = ! ToString(𝔽(i))。
    2. CreateDataPropertyOrThrow(A, Pi, E)。
    3. i++。
  12. i < newLen
    1. Pi = ! ToString(𝔽(i))。
    2. from = ! ToString(𝔽(r))。
    3. fromValue = ? Get(O, from)。
    4. CreateDataPropertyOrThrow(A, Pi, fromValue)。
    5. i++;r++。
  13. 返回 A

23.1.3.36 Array.prototype.toString ( )

调用时执行:

  1. array = ? ToObject(this value)。
  2. func = ? Get(array, "join")。
  3. IsCallable(func) 为 falsefunc = %Object.prototype.toString%。
  4. 返回 ? Call(func, array)。
Note

泛型。

23.1.3.37 Array.prototype.unshift ( ...items )

将参数插入开头并保持顺序,返回新长度。

步骤:

  1. O = ? ToObject(this value);len = ? LengthOfArrayLike(O)。
  2. argCount = items 长度。
  3. argCount > 0:
    1. len + argCount > 253-1 抛 TypeError
    2. k = len
    3. k > 0:
      1. from = ! ToString(𝔽(k-1));to = ! ToString(𝔽(k + argCount -1))。
      2. fromPresent = ? HasProperty(O, from)。
      3. 若真:fromValue = ? Get(O, from);? Set(O, to, fromValue, true);否则 Delete to
      4. k--。
    4. j = +0𝔽
    5. 对每个 Eitems:? Set(O, ! ToString(j), E, true);j += 1𝔽
  4. Set(O, "length", 𝔽(len + argCount), true)。
  5. 返回 𝔽(len + argCount)。

此方法 "length" 属性为 1𝔽

Note

泛型。

23.1.3.38 Array.prototype.values ( )

步骤:

  1. O = ? ToObject(this value)。
  2. 返回 CreateArrayIterator(O, value)。

23.1.3.39 Array.prototype.with ( index, value )

返回替换给定索引后的新数组(不修改原数组)。

  1. O = ? ToObject(this value);len = ? LengthOfArrayLike(O)。
  2. relativeIndex = ? ToIntegerOrInfinity(index)。
  3. relativeIndex ≥ 0:actualIndex = relativeIndex;否则 actualIndex = len + relativeIndex
  4. actualIndexlenactualIndex < 0 抛 RangeError
  5. A = ? ArrayCreate(len)。
  6. k = 0。
  7. k < len
    1. Pk = ! ToString(𝔽(k))。
    2. k = actualIndexfromValue = value;否则 fromValue = ? Get(O, Pk)。
    3. CreateDataPropertyOrThrow(A, Pk, fromValue)。
    4. k++。
  8. 返回 A

23.1.3.40 Array.prototype [ %Symbol.iterator% ] ( )

%Symbol.iterator% 初始值为 %Array.prototype.values%,定义见 23.1.3.38

23.1.3.41 Array.prototype [ %Symbol.unscopables% ]

%Symbol.unscopables% 数据属性初始值按以下步骤创建:

  1. unscopableList = OrdinaryObjectCreate(null)。
  2. CreateDataPropertyOrThrow(unscopableList, "at", true)。
  3. CreateDataPropertyOrThrow(unscopableList, "copyWithin", true)。
  4. CreateDataPropertyOrThrow(unscopableList, "entries", true)。
  5. CreateDataPropertyOrThrow(unscopableList, "fill", true)。
  6. CreateDataPropertyOrThrow(unscopableList, "find", true)。
  7. CreateDataPropertyOrThrow(unscopableList, "findIndex", true)。
  8. CreateDataPropertyOrThrow(unscopableList, "findLast", true)。
  9. CreateDataPropertyOrThrow(unscopableList, "findLastIndex", true)。
  10. CreateDataPropertyOrThrow(unscopableList, "flat", true)。
  11. CreateDataPropertyOrThrow(unscopableList, "flatMap", true)。
  12. CreateDataPropertyOrThrow(unscopableList, "includes", true)。
  13. CreateDataPropertyOrThrow(unscopableList, "keys", true)。
  14. CreateDataPropertyOrThrow(unscopableList, "toReversed", true)。
  15. CreateDataPropertyOrThrow(unscopableList, "toSorted", true)。
  16. CreateDataPropertyOrThrow(unscopableList, "toSpliced", true)。
  17. CreateDataPropertyOrThrow(unscopableList, "values", true)。
  18. 返回 unscopableList

该属性特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

Note

这些名称在 ES2015 前不是标准 Array.prototype 自有属性;在 with 语句中应忽略以避免遮蔽外层绑定。

"with" 未列入是因为其已为 保留字

23.1.4 Array 实例的属性

Array 实例是数组异质对象,具有对应内部方法,并继承自 Array 原型。

Array 实例具有 "length" 属性及一组可枚举数组索引属性。

23.1.4.1 length

"length"数据属性,其值始终大于任一可配置自有数组索引属性名的数值。

初始属性特性:{ [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }。

Note

减小 "length" 会删除旧长度与新长度之间的索引元素(不可配置者除外)。若尝试设置长度为小于等于某不可配置索引名的值,则实际长度会被设置为该索引名+1。参见 10.4.2.1

23.1.5 Array 迭代器对象

Array Iterator 表示针对某个特定 Array 实例的一次特定迭代。无命名构造函数;通过调用某些 Array 实例方法创建。

23.1.5.1 CreateArrayIterator ( array, kind )

The abstract operation CreateArrayIterator takes arguments array (an Object) and kind (key+value, key, or value) and returns an Object. 为返回迭代器的 Array 方法创建迭代器对象。 It performs the following steps when called:

  1. iterator = OrdinaryObjectCreate(%ArrayIteratorPrototype%, « [[IteratedArrayLike]], [[ArrayLikeNextIndex]], [[ArrayLikeIterationKind]] »)。
  2. iterator.[[IteratedArrayLike]] = array
  3. iterator.[[ArrayLikeNextIndex]] = 0。
  4. iterator.[[ArrayLikeIterationKind]] = kind
  5. 返回 iterator

23.1.5.2 %ArrayIteratorPrototype% 对象

%ArrayIteratorPrototype% 对象:

23.1.5.2.1 %ArrayIteratorPrototype%.next ( )

  1. O = this
  2. O 非对象抛 TypeError
  3. O 不具备数组迭代器实例全部内部槽抛 TypeError
  4. array = O.[[IteratedArrayLike]]
  5. arrayundefined 返回 CreateIteratorResultObject(undefined, true)。
  6. index = O.[[ArrayLikeNextIndex]]
  7. kind = O.[[ArrayLikeIterationKind]]
  8. array 具有 [[TypedArrayName]]
    1. taRecord = MakeTypedArrayWithBufferWitnessRecord(array, seq-cst)。
    2. IsTypedArrayOutOfBounds(taRecord) 为 trueTypeError
    3. len = TypedArrayLength(taRecord)。
  9. 否则 len = ? LengthOfArrayLike(array)。
  10. indexlen
    1. O.[[IteratedArrayLike]] = undefined
    2. 返回 CreateIteratorResultObject(undefined, true)。
  11. O.[[ArrayLikeNextIndex]] = index + 1。
  12. indexNumber = 𝔽(index)。
  13. kind = keyresult = indexNumber
  14. 否则:
    1. elementKey = ! ToString(indexNumber)。
    2. elementValue = ? Get(array, elementKey)。
    3. kind = valueresult = elementValue;否则(断言 key+valueresult = CreateArrayFromListindexNumber, elementValue »)。
  15. 返回 CreateIteratorResultObject(result, false)。

23.1.5.2.2 %ArrayIteratorPrototype% [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 初始值为 "Array Iterator"

属性特性:{ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

23.1.5.3 Array 迭代器实例的属性

Array 迭代器实例继承自内在对象 %ArrayIteratorPrototype%,并具有下表内部槽。

Table 72: Array 迭代器实例的内部槽
Internal Slot Type Description
[[IteratedArrayLike]] an Object or undefined 被迭代的类数组对象
[[ArrayLikeNextIndex]] a non-negative integer 下一个要访问的元素索引。
[[ArrayLikeIterationKind]] key+value, key, or value 迭代时返回的形式。

23.2 TypedArray 对象

TypedArray 提供其底层二进制数据缓冲区的类数组视图(25.1)。TypedArray 元素类型 是所有 TypedArray 实例元素所具有的底层二进制标量数据类型。针对每种受支持的元素类型,在 Table 73 中列出了一个不同的 TypedArray 构造函数Table 73 中的每个构造函数都有其对应且相互不同的原型对象。

Table 73: TypedArray 构造函数
构造函数名称与内在对象 元素类型 元素大小 转换操作 描述
Int8Array
%Int8Array%
int8 1 ToInt8 8 位二进制补码有符号整数
Uint8Array
%Uint8Array%
uint8 1 ToUint8 8 位无符号整数
Uint8ClampedArray
%Uint8ClampedArray%
uint8clamped 1 ToUint8Clamp 8 位无符号整数(限制转换)
Int16Array
%Int16Array%
int16 2 ToInt16 16 位二进制补码有符号整数
Uint16Array
%Uint16Array%
uint16 2 ToUint16 16 位无符号整数
Int32Array
%Int32Array%
int32 4 ToInt32 32 位二进制补码有符号整数
Uint32Array
%Uint32Array%
uint32 4 ToUint32 32 位无符号整数
BigInt64Array
%BigInt64Array%
bigint64 8 ToBigInt64 64 位二进制补码有符号整数
BigUint64Array
%BigUint64Array%
biguint64 8 ToBigUint64 64 位无符号整数
Float16Array
%Float16Array%
float16 2 16 位 IEEE 浮点数
Float32Array
%Float32Array%
float32 4 32 位 IEEE 浮点数
Float64Array
%Float64Array%
float64 8 64 位 IEEE 浮点数

在下列定义中,对 TypedArray 的引用应替换为上表中的适当构造函数名称。

23.2.1 %TypedArray% 内在对象

%TypedArray% 内在对象:

  • 是所有 TypedArray 构造函数对象继承自的构造函数对象。
  • 与其对应的原型对象一起,提供所有 TypedArray 构造函数及其实例所继承的共有属性。
  • 没有全局名称,也不作为全局对象的属性出现。
  • 作为各种 TypedArray 构造函数的抽象超类。
  • 作为抽象类构造函数被调用时会抛出错误。TypedArray 构造函数不会对其执行 super 调用。

23.2.1.1 %TypedArray% ( )

该函数被调用时执行以下步骤:

  1. 抛出 TypeError 异常。

此函数的 "length" 属性为 +0𝔽

23.2.2 %TypedArray% 内在对象的属性

%TypedArray% 内在对象:

  • 具有 [[Prototype]] 内部槽,其值为 %Function.prototype%
  • "name" 属性,其值为 "TypedArray"
  • 具有以下属性:

23.2.2.1 %TypedArray%.from ( source [ , mapper [ , thisArg ] ] )

该方法被调用时执行以下步骤:

  1. Cthis 值。
  2. IsConstructor(C) 为 false,抛出 TypeError 异常。
  3. mapperundefined,则
    1. mappingfalse
  4. 否则,
    1. IsCallable(mapper) 为 false,抛出 TypeError 异常。
    2. mappingtrue
  5. usingIterator 为 ? GetMethod(source, %Symbol.iterator%)。
  6. usingIterator 不为 undefined,则
    1. values 为 ? IteratorToList(? GetIteratorFromMethod(source, usingIterator))。
    2. lenvalues 中元素的数量。
    3. targetObj 为 ? TypedArrayCreateFromConstructor(C, « 𝔽(len) »)。
    4. k 为 0。
    5. k < len 重复,
      1. Pk 为 ! ToString(𝔽(k))。
      2. kValuevalues 的第一个元素。
      3. 移除 values 的第一个元素。
      4. mappingtrue,则
        1. mappedValue 为 ? Call(mapper, thisArg, « kValue, 𝔽(k) »)。
      5. 否则,
        1. mappedValuekValue
      6. 执行 ? Set(targetObj, Pk, mappedValue, true)。
      7. kk + 1。
    6. 断言:values 现在为空列表。
    7. 返回 targetObj
  7. 注:source 不是可迭代对象,因此假定其已为类数组对象
  8. arrayLike 为 ! ToObject(source)。
  9. len 为 ? LengthOfArrayLike(arrayLike)。
  10. targetObj 为 ? TypedArrayCreateFromConstructor(C, « 𝔽(len) »)。
  11. k 为 0。
  12. k < len 重复,
    1. Pk 为 ! ToString(𝔽(k))。
    2. kValue 为 ? Get(arrayLike, Pk)。
    3. mappingtrue,则
      1. mappedValue 为 ? Call(mapper, thisArg, « kValue, 𝔽(k) »)。
    4. 否则,
      1. mappedValuekValue
    5. 执行 ? Set(targetObj, Pk, mappedValue, true)。
    6. kk + 1。
  13. 返回 targetObj

23.2.2.2 %TypedArray%.of ( ...items )

该方法被调用时执行以下步骤:

  1. lenitems 中元素的数量。
  2. Cthis 值。
  3. IsConstructor(C) 为 false,抛出 TypeError 异常。
  4. newObj 为 ? TypedArrayCreateFromConstructor(C, « 𝔽(len) »)。
  5. k 为 0。
  6. k < len 重复,
    1. kValueitems[k]。
    2. Pk 为 ! ToString(𝔽(k))。
    3. 执行 ? Set(newObj, Pk, kValue, true)。
    4. kk + 1。
  7. 返回 newObj

23.2.2.3 %TypedArray%.prototype

%TypedArray%.prototype 的初始值是 %TypedArray% 原型对象

该属性特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

23.2.2.4 get %TypedArray% [ %Symbol.species% ]

%TypedArray%[%Symbol.species%] 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行:

  1. 返回 this 值。

该函数 "name" 属性的值为 "get [Symbol.species]"

Note

%TypedArray.prototype% 的方法通常使用其 this 值的构造函数创建派生对象。然而,子类构造函数可以通过重定义其 %Symbol.species% 属性来覆盖该默认行为。

23.2.3 %TypedArray% 原型对象的属性

%TypedArray% 原型对象

  • 具有 [[Prototype]] 内部槽,其值为 %Object.prototype%
  • %TypedArray.prototype%
  • 是一个普通对象
  • 没有 [[ViewedArrayBuffer]] 或其他特定于 TypedArray 实例对象的内部槽。

23.2.3.1 %TypedArray%.prototype.at ( index )

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. relativeIndex 为 ? ToIntegerOrInfinity(index)。
  5. relativeIndex ≥ 0,则
    1. k = relativeIndex
  6. 否则,
    1. k = len + relativeIndex
  7. k < 0 或 klen,返回 undefined
  8. 返回 ! Get(O, ! ToString(𝔽(k)))。

23.2.3.2 get %TypedArray%.prototype.buffer

%TypedArray%.prototype.buffer 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[TypedArrayName]])。
  3. 断言:O 具有 [[ViewedArrayBuffer]] 内部槽。
  4. bufferO.[[ViewedArrayBuffer]]
  5. 返回 buffer

23.2.3.3 get %TypedArray%.prototype.byteLength

%TypedArray%.prototype.byteLength 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[TypedArrayName]])。
  3. 断言:O 具有 [[ViewedArrayBuffer]] 内部槽。
  4. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)。
  5. sizeTypedArrayByteLength(taRecord)。
  6. 返回 𝔽(size)。

23.2.3.4 get %TypedArray%.prototype.byteOffset

%TypedArray%.prototype.byteOffset 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[TypedArrayName]])。
  3. 断言:O 具有 [[ViewedArrayBuffer]] 内部槽。
  4. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)。
  5. IsTypedArrayOutOfBounds(taRecord) 为 true,返回 +0𝔽
  6. offsetO.[[ByteOffset]]
  7. 返回 𝔽(offset)。

23.2.3.5 %TypedArray%.prototype.constructor

%TypedArray%.prototype.constructor 的初始值为 %TypedArray%

23.2.3.6 %TypedArray%.prototype.copyWithin ( target, start [ , end ] )

此方法参数的解释与用法与 23.1.3.4 中定义的 Array.prototype.copyWithin 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. relativeTarget 为 ? ToIntegerOrInfinity(target)。
  5. relativeTarget = -∞,令 targetIndex = 0。
  6. 否则若 relativeTarget < 0,令 targetIndex = max(len + relativeTarget, 0)。
  7. 否则令 targetIndex = min(relativeTarget, len)。
  8. relativeStart 为 ? ToIntegerOrInfinity(start)。
  9. relativeStart = -∞,令 startIndex = 0。
  10. 否则若 relativeStart < 0,令 startIndex = max(len + relativeStart, 0)。
  11. 否则令 startIndex = min(relativeStart, len)。
  12. endundefined,令 relativeEnd = len;否则令 relativeEnd = ? ToIntegerOrInfinity(end)。
  13. relativeEnd = -∞,令 endIndex = 0。
  14. 否则若 relativeEnd < 0,令 endIndex = max(len + relativeEnd, 0)。
  15. 否则令 endIndex = min(relativeEnd, len)。
  16. countmin(endIndex - startIndex, len - targetIndex)。
  17. count > 0,则
    1. 注:复制必须以保持源数据位级编码的方式进行。
    2. bufferO.[[ViewedArrayBuffer]]
    3. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)。
    4. IsTypedArrayOutOfBounds(taRecord) 为 true,抛出 TypeError 异常。
    5. lenTypedArrayLength(taRecord)。
    6. elementSizeTypedArrayElementSize(O)。
    7. byteOffsetO.[[ByteOffset]]
    8. bufferByteLimit 为 (len × elementSize) + byteOffset
    9. toByteIndex 为 (targetIndex × elementSize) + byteOffset
    10. fromByteIndex 为 (startIndex × elementSize) + byteOffset
    11. countBytescount × elementSize
    12. fromByteIndex < toByteIndextoByteIndex < fromByteIndex + countBytes,则
      1. direction = -1。
      2. fromByteIndex = fromByteIndex + countBytes - 1。
      3. toByteIndex = toByteIndex + countBytes - 1。
    13. 否则,
      1. direction = 1。
    14. countBytes > 0 重复,
      1. fromByteIndex < bufferByteLimittoByteIndex < bufferByteLimit,则
        1. valueGetValueFromBuffer(buffer, fromByteIndex, uint8, true, unordered)。
        2. 执行 SetValueInBuffer(buffer, toByteIndex, uint8, value, true, unordered)。
        3. fromByteIndex = fromByteIndex + direction
        4. toByteIndex = toByteIndex + direction
        5. countBytes = countBytes - 1。
      2. 否则,
        1. countBytes = 0。
  18. 返回 O

23.2.3.7 %TypedArray%.prototype.entries ( )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? ValidateTypedArray(O, seq-cst)。
  3. 返回 CreateArrayIterator(O, key+value)。

23.2.3.8 %TypedArray%.prototype.every ( callback [ , thisArg ] )

该方法参数的解释与用法与 23.1.3.6 中的 Array.prototype.every 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. IsCallable(callback) 为 false,抛出 TypeError 异常。
  5. k = 0。
  6. k < len 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. kValue = ! Get(O, Pk)。
    3. testResultToBoolean(? Call(callback, thisArg, « kValue, 𝔽(k), O »))。
    4. testResultfalse,返回 false
    5. k = k + 1。
  7. 返回 true

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.9 %TypedArray%.prototype.fill ( value [ , start [ , end ] ] )

该方法参数的解释与用法与 23.1.3.7 中的 Array.prototype.fill 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. O.[[ContentType]]bigint,设 value 为 ? ToBigInt(value)。
  5. 否则,设 value 为 ? ToNumber(value)。
  6. relativeStart 为 ? ToIntegerOrInfinity(start)。
  7. relativeStart = -∞,令 startIndex = 0。
  8. 否则若 relativeStart < 0,令 startIndex = max(len + relativeStart, 0)。
  9. 否则令 startIndex = min(relativeStart, len)。
  10. endundefined,令 relativeEnd = len;否则令 relativeEnd = ? ToIntegerOrInfinity(end)。
  11. relativeEnd = -∞,令 endIndex = 0。
  12. 否则若 relativeEnd < 0,令 endIndex = max(len + relativeEnd, 0)。
  13. 否则令 endIndex = min(relativeEnd, len)。
  14. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)。
  15. IsTypedArrayOutOfBounds(taRecord) 为 true,抛出 TypeError 异常。
  16. lenTypedArrayLength(taRecord)。
  17. endIndex = min(endIndex, len)。
  18. k = startIndex
  19. k < endIndex 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. 执行 ! Set(O, Pk, value, true)。
    3. k = k + 1。
  20. 返回 O

23.2.3.10 %TypedArray%.prototype.filter ( callback [ , thisArg ] )

该方法参数的解释与用法与 23.1.3.8 中的 Array.prototype.filter 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. IsCallable(callback) 为 false,抛出 TypeError 异常。
  5. kept 为一个新的空列表。
  6. captured 为 0。
  7. k 为 0。
  8. k < len 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. kValue = ! Get(O, Pk)。
    3. selected = ToBoolean(? Call(callback, thisArg, « kValue, 𝔽(k), O »))。
    4. selectedtrue,则
      1. kValue 追加到 kept
      2. captured = captured + 1。
    5. k = k + 1。
  9. A 为 ? TypedArraySpeciesCreate(O, « 𝔽(captured) »)。
  10. n = 0。
  11. kept 中每个元素 e
    1. 执行 ! Set(A, ! ToString(𝔽(n)), e, true)。
    2. n = n + 1。
  12. 返回 A

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.11 %TypedArray%.prototype.find ( predicate [ , thisArg ] )

该方法参数的解释与用法与 23.1.3.9 中的 Array.prototype.find 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. findRec 为 ? FindViaPredicate(O, len, ascending, predicate, thisArg)。
  5. 返回 findRec.[[Value]]

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.12 %TypedArray%.prototype.findIndex ( predicate [ , thisArg ] )

该方法参数的解释与用法与 23.1.3.10 中的 Array.prototype.findIndex 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. findRec 为 ? FindViaPredicate(O, len, ascending, predicate, thisArg)。
  5. 返回 findRec.[[Index]]

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.13 %TypedArray%.prototype.findLast ( predicate [ , thisArg ] )

该方法参数的解释与用法与 23.1.3.11 中的 Array.prototype.findLast 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. findRec 为 ? FindViaPredicate(O, len, descending, predicate, thisArg)。
  5. 返回 findRec.[[Value]]

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.14 %TypedArray%.prototype.findLastIndex ( predicate [ , thisArg ] )

该方法参数的解释与用法与 23.1.3.12 中的 Array.prototype.findLastIndex 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. findRec 为 ? FindViaPredicate(O, len, descending, predicate, thisArg)。
  5. 返回 findRec.[[Index]]

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.15 %TypedArray%.prototype.forEach ( callback [ , thisArg ] )

该方法参数的解释与用法与 23.1.3.15 中的 Array.prototype.forEach 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. IsCallable(callback) 为 false,抛出 TypeError 异常。
  5. k = 0。
  6. k < len 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. kValue = ! Get(O, Pk)。
    3. 执行 ? Call(callback, thisArg, « kValue, 𝔽(k), O »)。
    4. k = k + 1。
  7. 返回 undefined

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.16 %TypedArray%.prototype.includes ( searchElement [ , fromIndex ] )

该方法参数的解释与用法与 23.1.3.16 中的 Array.prototype.includes 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. len = 0,返回 false
  5. n 为 ? ToIntegerOrInfinity(fromIndex)。
  6. 断言:若 fromIndexundefined,则 n 为 0。
  7. n = +∞,返回 false
  8. 否则若 n = -∞,设 n = 0。
  9. n ≥ 0,则
    1. k = n
  10. 否则,
    1. k = len + n
    2. k < 0,设 k = 0。
  11. k < len 重复,
    1. elementK 为 ! Get(O, ! ToString(𝔽(k)))。
    2. SameValueZero(searchElement, elementK) 为 true,返回 true
    3. k = k + 1。
  12. 返回 false

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.17 %TypedArray%.prototype.indexOf ( searchElement [ , fromIndex ] )

该方法参数的解释与用法与 23.1.3.17 中的 Array.prototype.indexOf 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. len = 0,返回 -1𝔽
  5. n 为 ? ToIntegerOrInfinity(fromIndex)。
  6. 断言:若 fromIndexundefined,则 n 为 0。
  7. n = +∞,返回 -1𝔽
  8. 否则若 n = -∞,设 n = 0。
  9. n ≥ 0,则
    1. k = n
  10. 否则,
    1. k = len + n
    2. k < 0,设 k = 0。
  11. k < len 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. kPresent = ! HasProperty(O, Pk)。
    3. kPresenttrue,则
      1. elementK = ! Get(O, Pk)。
      2. IsStrictlyEqual(searchElement, elementK) 为 true,返回 𝔽(k)。
    4. k = k + 1。
  12. 返回 -1𝔽

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.18 %TypedArray%.prototype.join ( separator )

该方法参数的解释与用法与 23.1.3.18 中的 Array.prototype.join 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. separatorundefined,令 sep = ","
  5. 否则,令 sep = ? ToString(separator)。
  6. R 为空字符串。
  7. k = 0。
  8. k < len 重复,
    1. k > 0,设 RRsep 的字符串拼接。
    2. element 为 ! Get(O, ! ToString(𝔽(k)))。
    3. element 不为 undefined,则
      1. S 为 ! ToString(element)。
      2. RRS 的字符串拼接。
    4. k = k + 1。
  9. 返回 R

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.19 %TypedArray%.prototype.keys ( )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? ValidateTypedArray(O, seq-cst)。
  3. 返回 CreateArrayIterator(O, key)。

23.2.3.20 %TypedArray%.prototype.lastIndexOf ( searchElement [ , fromIndex ] )

该方法参数的解释与用法与 23.1.3.20 中的 Array.prototype.lastIndexOf 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. len = 0,返回 -1𝔽
  5. 若提供 fromIndex,令 n 为 ? ToIntegerOrInfinity(fromIndex);否则令 n = len - 1。
  6. n = -∞,返回 -1𝔽
  7. n ≥ 0,则
    1. k = min(n, len - 1)。
  8. 否则,
    1. k = len + n
  9. k ≥ 0 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. kPresent = ! HasProperty(O, Pk)。
    3. kPresenttrue,则
      1. elementK = ! Get(O, Pk)。
      2. IsStrictlyEqual(searchElement, elementK) 为 true,返回 𝔽(k)。
    4. k = k - 1。
  10. 返回 -1𝔽

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.21 get %TypedArray%.prototype.length

%TypedArray%.prototype.length 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[TypedArrayName]])。
  3. 断言:O 具有 [[ViewedArrayBuffer]][[ArrayLength]] 内部槽。
  4. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)。
  5. IsTypedArrayOutOfBounds(taRecord) 为 true,返回 +0𝔽
  6. lengthTypedArrayLength(taRecord)。
  7. 返回 𝔽(length)。

该函数不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.22 %TypedArray%.prototype.map ( callback [ , thisArg ] )

该方法参数的解释与用法与 23.1.3.21 中的 Array.prototype.map 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. IsCallable(callback) 为 false,抛出 TypeError 异常。
  5. A 为 ? TypedArraySpeciesCreate(O, « 𝔽(len) »)。
  6. k = 0。
  7. k < len 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. kValue = ! Get(O, Pk)。
    3. mappedValue = ? Call(callback, thisArg, « kValue, 𝔽(k), O »)。
    4. 执行 ? Set(A, Pk, mappedValue, true)。
    5. k = k + 1。
  8. 返回 A

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.23 %TypedArray%.prototype.reduce ( callback [ , initialValue ] )

该方法参数的解释与用法与 23.1.3.24 中的 Array.prototype.reduce 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. IsCallable(callback) 为 false,抛出 TypeError 异常。
  5. len = 0 且 initialValue 不存在,抛出 TypeError 异常。
  6. k = 0。
  7. accumulator = undefined
  8. 若存在 initialValue,则
    1. accumulator = initialValue
  9. 否则,
    1. Pk = ! ToString(𝔽(k))。
    2. accumulator = ! Get(O, Pk)。
    3. k = k + 1。
  10. k < len 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. kValue = ! Get(O, Pk)。
    3. accumulator = ? Call(callback, undefined, « accumulator, kValue, 𝔽(k), O »)。
    4. k = k + 1。
  11. 返回 accumulator

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.24 %TypedArray%.prototype.reduceRight ( callback [ , initialValue ] )

该方法参数的解释与用法与 23.1.3.25 中的 Array.prototype.reduceRight 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. IsCallable(callback) 为 false,抛出 TypeError 异常。
  5. len = 0 且 initialValue 不存在,抛出 TypeError 异常。
  6. k = len - 1。
  7. accumulator = undefined
  8. 若存在 initialValue,则
    1. accumulator = initialValue
  9. 否则,
    1. Pk = ! ToString(𝔽(k))。
    2. accumulator = ! Get(O, Pk)。
    3. k = k - 1。
  10. k ≥ 0 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. kValue = ! Get(O, Pk)。
    3. accumulator = ? Call(callback, undefined, « accumulator, kValue, 𝔽(k), O »)。
    4. k = k - 1。
  11. 返回 accumulator

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.25 %TypedArray%.prototype.reverse ( )

该方法参数的解释与用法与 23.1.3.26 中的 Array.prototype.reverse 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. middle = floor(len / 2)。
  5. lower = 0。
  6. lowermiddle 重复,
    1. upper = len - lower - 1。
    2. upperP = ! ToString(𝔽(upper))。
    3. lowerP = ! ToString(𝔽(lower))。
    4. lowerValue = ! Get(O, lowerP)。
    5. upperValue = ! Get(O, upperP)。
    6. 执行 ! Set(O, lowerP, upperValue, true)。
    7. 执行 ! Set(O, upperP, lowerValue, true)。
    8. lower = lower + 1。
  7. 返回 O

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.26 %TypedArray%.prototype.set ( source [ , offset ] )

该方法在此 TypedArray 中设置多个值,从 source 读取这些值。具体细节依据 source 的类型不同而不同。可选的 offset 指定开始写入的首个元素索引。如省略则视为 0。

其被调用时执行以下步骤:

  1. targetthis 值。
  2. 执行 ? RequireInternalSlot(target, [[TypedArrayName]])。
  3. 断言:target 具有 [[ViewedArrayBuffer]] 内部槽。
  4. targetOffset 为 ? ToIntegerOrInfinity(offset)。
  5. targetOffset < 0,抛出 RangeError 异常。
  6. source 是具有 [[TypedArrayName]] 内部槽的对象,则
    1. 执行 ? SetTypedArrayFromTypedArray(target, targetOffset, source)。
  7. 否则,
    1. 执行 ? SetTypedArrayFromArrayLike(target, targetOffset, source)。
  8. 返回 undefined

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.26.1 SetTypedArrayFromArrayLike ( target, targetOffset, source )

The abstract operation SetTypedArrayFromArrayLike takes arguments target (a TypedArray), targetOffset (a non-negative integer or +∞), and source (an ECMAScript language value, but not a TypedArray) and returns 返回 unused正常完成或抛出完成. 从 source 读取值并自 targetOffset 开始在 target 中设置多个值。 It performs the following steps when called:

  1. targetRecordMakeTypedArrayWithBufferWitnessRecord(target, seq-cst)。
  2. IsTypedArrayOutOfBounds(targetRecord) 为 true,抛出 TypeError 异常。
  3. targetLengthTypedArrayLength(targetRecord)。
  4. src 为 ? ToObject(source)。
  5. srcLength 为 ? LengthOfArrayLike(src)。
  6. targetOffset = +∞,抛出 RangeError 异常。
  7. srcLength + targetOffset > targetLength,抛出 RangeError 异常。
  8. k = 0。
  9. k < srcLength 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. value = ? Get(src, Pk)。
    3. targetIndex = 𝔽(targetOffset + k)。
    4. 执行 ? TypedArraySetElement(target, targetIndex, value)。
    5. k = k + 1。
  10. 返回 unused

23.2.3.26.2 SetTypedArrayFromTypedArray ( target, targetOffset, source )

The abstract operation SetTypedArrayFromTypedArray takes arguments target (a TypedArray), targetOffset (a non-negative integer or +∞), and source (a TypedArray) and returns 返回 unused正常完成或抛出完成. 从 source 读取值并自 targetOffset 开始在 target 中设置多个值。 It performs the following steps when called:

  1. targetBuffertarget.[[ViewedArrayBuffer]]
  2. targetRecordMakeTypedArrayWithBufferWitnessRecord(target, seq-cst)。
  3. IsTypedArrayOutOfBounds(targetRecord) 为 true,抛出 TypeError 异常。
  4. targetLengthTypedArrayLength(targetRecord)。
  5. srcBuffersource.[[ViewedArrayBuffer]]
  6. srcRecordMakeTypedArrayWithBufferWitnessRecord(source, seq-cst)。
  7. IsTypedArrayOutOfBounds(srcRecord) 为 true,抛出 TypeError 异常。
  8. srcLengthTypedArrayLength(srcRecord)。
  9. targetTypeTypedArrayElementType(target)。
  10. targetElementSizeTypedArrayElementSize(target)。
  11. targetByteOffsettarget.[[ByteOffset]]
  12. srcTypeTypedArrayElementType(source)。
  13. srcElementSizeTypedArrayElementSize(source)。
  14. srcByteOffsetsource.[[ByteOffset]]
  15. targetOffset = +∞,抛出 RangeError 异常。
  16. srcLength + targetOffset > targetLength,抛出 RangeError 异常。
  17. target.[[ContentType]] 不等于 source.[[ContentType]],抛出 TypeError 异常。
  18. IsSharedArrayBuffer(srcBuffer) 为 trueIsSharedArrayBuffer(targetBuffer) 为 truesrcBuffer.[[ArrayBufferData]]targetBuffer.[[ArrayBufferData]],令 sameSharedArrayBuffer = true;否则令 sameSharedArrayBuffer = false
  19. SameValue(srcBuffer, targetBuffer) 为 truesameSharedArrayBuffertrue,则
    1. srcByteLengthTypedArrayByteLength(srcRecord)。
    2. srcBuffer 为 ? CloneArrayBuffer(srcBuffer, srcByteOffset, srcByteLength)。
    3. srcByteIndex = 0。
  20. 否则,
    1. srcByteIndex = srcByteOffset
  21. targetByteIndex = (targetOffset × targetElementSize) + targetByteOffset
  22. limit = targetByteIndex + (targetElementSize × srcLength)。
  23. srcTypetargetType,则
    1. 注:复制必须保持源数据的位级编码。
    2. targetByteIndex < limit 重复,
      1. valueGetValueFromBuffer(srcBuffer, srcByteIndex, uint8, true, unordered)。
      2. 执行 SetValueInBuffer(targetBuffer, targetByteIndex, uint8, value, true, unordered)。
      3. srcByteIndex = srcByteIndex + 1。
      4. targetByteIndex = targetByteIndex + 1。
  24. 否则,
    1. targetByteIndex < limit 重复,
      1. valueGetValueFromBuffer(srcBuffer, srcByteIndex, srcType, true, unordered)。
      2. 执行 SetValueInBuffer(targetBuffer, targetByteIndex, targetType, value, true, unordered)。
      3. srcByteIndex = srcByteIndex + srcElementSize
      4. targetByteIndex = targetByteIndex + targetElementSize
  25. 返回 unused

23.2.3.27 %TypedArray%.prototype.slice ( start, end )

该方法参数的解释与用法与 23.1.3.28 中的 Array.prototype.slice 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. srcArrayLengthTypedArrayLength(taRecord)。
  4. relativeStart 为 ? ToIntegerOrInfinity(start)。
  5. relativeStart = -∞,令 startIndex = 0。
  6. 否则若 relativeStart < 0,令 startIndex = max(srcArrayLength + relativeStart, 0)。
  7. 否则令 startIndex = min(relativeStart, srcArrayLength)。
  8. endundefined,令 relativeEnd = srcArrayLength;否则令 relativeEnd = ? ToIntegerOrInfinity(end)。
  9. relativeEnd = -∞,令 endIndex = 0。
  10. 否则若 relativeEnd < 0,令 endIndex = max(srcArrayLength + relativeEnd, 0)。
  11. 否则令 endIndex = min(relativeEnd, srcArrayLength)。
  12. countBytes = max(endIndex - startIndex, 0)。
  13. A 为 ? TypedArraySpeciesCreate(O, « 𝔽(countBytes) »)。
  14. countBytes > 0,则
    1. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)。
    2. IsTypedArrayOutOfBounds(taRecord) 为 true,抛出 TypeError 异常。
    3. endIndex = min(endIndex, TypedArrayLength(taRecord))。
    4. countBytes = max(endIndex - startIndex, 0)。
    5. srcType = TypedArrayElementType(O)。
    6. targetType = TypedArrayElementType(A)。
    7. srcTypetargetType,则
      1. 注:传输必须保持源数据的位级编码。
      2. srcBuffer = O.[[ViewedArrayBuffer]]
      3. targetBuffer = A.[[ViewedArrayBuffer]]
      4. elementSize = TypedArrayElementSize(O)。
      5. srcByteOffset = O.[[ByteOffset]]
      6. srcByteIndex = (startIndex × elementSize) + srcByteOffset
      7. targetByteIndex = A.[[ByteOffset]]
      8. endByteIndex = targetByteIndex + (countBytes × elementSize)。
      9. targetByteIndex < endByteIndex 重复,
        1. valueGetValueFromBuffer(srcBuffer, srcByteIndex, uint8, true, unordered)。
        2. 执行 SetValueInBuffer(targetBuffer, targetByteIndex, uint8, value, true, unordered)。
        3. srcByteIndex = srcByteIndex + 1。
        4. targetByteIndex = targetByteIndex + 1。
    8. 否则,
      1. n = 0。
      2. k = startIndex
      3. k < endIndex 重复,
        1. Pk = ! ToString(𝔽(k))。
        2. kValue = ! Get(O, Pk)。
        3. 执行 ! Set(A, ! ToString(𝔽(n)), kValue, true)。
        4. k = k + 1。
        5. n = n + 1。
  15. 返回 A

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.28 %TypedArray%.prototype.some ( callback [ , thisArg ] )

该方法参数的解释与用法与 23.1.3.29 中的 Array.prototype.some 相同。

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. IsCallable(callback) 为 false,抛出 TypeError 异常。
  5. k = 0。
  6. k < len 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. kValue = ! Get(O, Pk)。
    3. testResult = ToBoolean(? Call(callback, thisArg, « kValue, 𝔽(k), O »))。
    4. testResulttrue,返回 true
    5. k = k + 1。
  7. 返回 false

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.29 %TypedArray%.prototype.sort ( comparator )

这是一个不同的方法;除下面描述的情况外,其实现与 23.1.3.30Array.prototype.sort 的要求相同。该方法的实现可以利用 this 值是长度固定且其整数索引属性非稀疏的对象这一知识进行优化。

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

其被调用时执行以下步骤:

  1. comparator 不为 undefinedIsCallable(comparator) 为 false,抛出 TypeError 异常。
  2. objthis 值。
  3. taRecord 为 ? ValidateTypedArray(obj, seq-cst)。
  4. lenTypedArrayLength(taRecord)。
  5. 注:以下闭包执行数值比较而非 23.1.3.30 中使用的字符串比较。
  6. SortCompare 为具有参数 (x, y) 并捕获 comparator 的新抽象闭包,调用时执行:
    1. 返回 ? CompareTypedArrayElements(x, y, comparator)。
  7. sortedList 为 ? SortIndexedProperties(obj, len, SortCompare, read-through-holes)。
  8. j = 0。
  9. j < len 重复,
    1. 执行 ! Set(obj, ! ToString(𝔽(j)), sortedList[j], true)。
    2. j = j + 1。
  10. 返回 obj
Note

因为 NaN 总是比较大于任何其他值(见 CompareTypedArrayElements),当未提供 comparator 时,NaN 属性值总是排在结果末尾。

23.2.3.30 %TypedArray%.prototype.subarray ( start, end )

该方法返回一个新的 TypedArray,其元素类型与该 TypedArray 相同,其 ArrayBuffer 为该 TypedArray 的 ArrayBuffer,引用从 start(含)到 end(不含)区间的元素。若 startend 为负值,则表示自数组末尾起的索引。

其被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[TypedArrayName]])。
  3. 断言:O 具有 [[ViewedArrayBuffer]] 内部槽。
  4. bufferO.[[ViewedArrayBuffer]]
  5. srcRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)。
  6. IsTypedArrayOutOfBounds(srcRecord) 为 true,则
    1. srcLength = 0。
  7. 否则,
    1. srcLength = TypedArrayLength(srcRecord)。
  8. relativeStart 为 ? ToIntegerOrInfinity(start)。
  9. relativeStart = -∞,令 startIndex = 0。
  10. 否则若 relativeStart < 0,令 startIndex = max(srcLength + relativeStart, 0)。
  11. 否则令 startIndex = min(relativeStart, srcLength)。
  12. elementSizeTypedArrayElementSize(O)。
  13. srcByteOffsetO.[[ByteOffset]]
  14. beginByteOffset = srcByteOffset + (startIndex × elementSize)。
  15. O.[[ArrayLength]]autoendundefined,则
    1. argumentsList 为 « buffer, 𝔽(beginByteOffset) »。
  16. 否则,
    1. endundefined,令 relativeEnd = srcLength;否则令 relativeEnd = ? ToIntegerOrInfinity(end)。
    2. relativeEnd = -∞,令 endIndex = 0。
    3. 否则若 relativeEnd < 0,令 endIndex = max(srcLength + relativeEnd, 0)。
    4. 否则令 endIndex = min(relativeEnd, srcLength)。
    5. newLength = max(endIndex - startIndex, 0)。
    6. argumentsList = « buffer, 𝔽(beginByteOffset), 𝔽(newLength) »。
  17. 返回 ? TypedArraySpeciesCreate(O, argumentsList)。

该方法不是泛型。this 值必须为具有 [[TypedArrayName]] 内部槽的对象。

23.2.3.31 %TypedArray%.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

这是一个不同的方法,实现与 23.1.3.32Array.prototype.toLocaleString 的算法相同,只是用 TypedArrayLength 取代对 "length"[[Get]]。在底层缓冲区不可调整大小且整数索引属性非稀疏时,实现可以利用 this 值长度固定的知识进行优化。然而,该优化不得引入任何可观测的指定行为变化。

该方法不是泛型。在求值算法前,使用 this 值与 seq-cst 作为参数调用 ValidateTypedArray。若其结果为异常完成,则抛出该异常而不再执行算法。

Note

若 ECMAScript 实现包含 ECMA-402 国际化 API,则该方法基于 ECMA-402 规范中 Array.prototype.toLocaleString 的算法。

23.2.3.32 %TypedArray%.prototype.toReversed ( )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. A 为 ? TypedArrayCreateSameType(O, len)。
  5. k = 0。
  6. k < len 重复,
    1. from = ! ToString(𝔽(len - k - 1))。
    2. Pk = ! ToString(𝔽(k))。
    3. fromValue = ! Get(O, from)。
    4. 执行 ! Set(A, Pk, fromValue, true)。
    5. k = k + 1。
  7. 返回 A

23.2.3.33 %TypedArray%.prototype.toSorted ( comparator )

该方法被调用时执行以下步骤:

  1. comparator 不为 undefinedIsCallable(comparator) 为 false,抛出 TypeError 异常。
  2. Othis 值。
  3. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  4. lenTypedArrayLength(taRecord)。
  5. A 为 ? TypedArrayCreateSameType(O, len)。
  6. 注:以下闭包执行数值比较,而非 23.1.3.34 中使用的字符串比较。
  7. SortCompare 为具有参数 (x, y) 并捕获 comparator 的新抽象闭包,调用时执行:
    1. 返回 ? CompareTypedArrayElements(x, y, comparator)。
  8. sortedList 为 ? SortIndexedProperties(O, len, SortCompare, read-through-holes)。
  9. j = 0。
  10. j < len 重复,
    1. 执行 ! Set(A, ! ToString(𝔽(j)), sortedList[j], true)。
    2. j = j + 1。
  11. 返回 A

23.2.3.34 %TypedArray%.prototype.toString ( )

"toString" 属性的初始值为 %Array.prototype.toString%,定义见 23.1.3.36

23.2.3.35 %TypedArray%.prototype.values ( )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? ValidateTypedArray(O, seq-cst)。
  3. 返回 CreateArrayIterator(O, value)。

23.2.3.36 %TypedArray%.prototype.with ( index, value )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. taRecord 为 ? ValidateTypedArray(O, seq-cst)。
  3. lenTypedArrayLength(taRecord)。
  4. relativeIndex 为 ? ToIntegerOrInfinity(index)。
  5. relativeIndex ≥ 0,令 actualIndex = relativeIndex
  6. 否则,令 actualIndex = len + relativeIndex
  7. O.[[ContentType]]bigint,令 numericValue = ? ToBigInt(value)。
  8. 否则,令 numericValue = ? ToNumber(value)。
  9. IsValidIntegerIndex(O, 𝔽(actualIndex)) 为 false,抛出 RangeError 异常。
  10. A 为 ? TypedArrayCreateSameType(O, len)。
  11. k = 0。
  12. k < len 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. k = actualIndex,令 fromValue = numericValue;否则令 fromValue = ! Get(O, Pk)。
    3. 执行 ! Set(A, Pk, fromValue, true)。
    4. k = k + 1。
  13. 返回 A

23.2.3.37 %TypedArray%.prototype [ %Symbol.iterator% ] ( )

%Symbol.iterator% 属性的初始值为 %TypedArray.prototype.values%,定义见 23.2.3.35

23.2.3.38 get %TypedArray%.prototype [ %Symbol.toStringTag% ]

%TypedArray%.prototype[%Symbol.toStringTag%] 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行:

  1. Othis 值。
  2. O 不是对象,返回 undefined
  3. O 不具有 [[TypedArrayName]] 内部槽,返回 undefined
  4. name = O.[[TypedArrayName]]
  5. 断言:name 是一个字符串。
  6. 返回 name

该属性特性为 { [[Enumerable]]: false, [[Configurable]]: true }。

该函数 "name" 属性的初始值为 "get [Symbol.toStringTag]"

23.2.4 TypedArray 对象的抽象操作

23.2.4.1 TypedArrayCreateFromConstructor ( constructor, argumentList )

The abstract operation TypedArrayCreateFromConstructor takes arguments constructor (a constructor) and argumentList (a List of ECMAScript language values) and returns 返回一个 TypedArray正常完成或抛出完成. 用于通过构造函数创建一个新的 TypedArray。 It performs the following steps when called:

  1. newTypedArray 为 ? Construct(constructor, argumentList)。
  2. taRecord 为 ? ValidateTypedArray(newTypedArray, seq-cst)。
  3. 断言:newTypedArray 具有 TypedArray 实例的属性 中提及的所有内部槽。
  4. argumentList 中元素数量为 1 且 argumentList[0] 是 Number,则
    1. IsTypedArrayOutOfBounds(taRecord) 为 true,抛出 TypeError 异常。
    2. lengthTypedArrayLength(taRecord)。
    3. length < (argumentList[0]),抛出 TypeError 异常。
  5. 返回 newTypedArray

23.2.4.2 TypedArrayCreateSameType ( exemplar, length )

The abstract operation TypedArrayCreateSameType takes arguments exemplar (a TypedArray) and length (a non-negative integer) and returns 返回一个 TypedArray正常完成或抛出完成. 用于使用从 exemplar 派生的构造函数及一个 length 创建新的 TypedArray。不同于可通过 %Symbol.species% 构造自定义子类的 TypedArraySpeciesCreate,本操作始终使用内置的 TypedArray 构造函数之一。 It performs the following steps when called:

  1. constructor 为与 exemplar.[[TypedArrayName]]构造函数名称关联的内在对象,见 Table 73
  2. result 为 ? TypedArrayCreateFromConstructor(constructor, « 𝔽(length) »)。
  3. 断言:result 具有 [[TypedArrayName]][[ContentType]] 内部槽。
  4. 断言:result.[[ContentType]]exemplar.[[ContentType]]
  5. 返回 result

23.2.4.3 TypedArraySpeciesCreate ( exemplar, argumentList )

The abstract operation TypedArraySpeciesCreate takes arguments exemplar (a TypedArray) and argumentList (a List of ECMAScript language values) and returns 返回一个 TypedArray正常完成或抛出完成. 用于通过从 exemplar 派生的构造函数创建新的 TypedArray。不同于可通过 %Symbol.species% 创建非 Array 对象的 ArraySpeciesCreate,该操作强制构造函数必须创建一个实际的 TypedArray。 It performs the following steps when called:

  1. defaultConstructor 为与 exemplar.[[TypedArrayName]]构造函数名称关联的内在对象,见 Table 73
  2. constructor 为 ? SpeciesConstructor(exemplar, defaultConstructor)。
  3. result 为 ? TypedArrayCreateFromConstructor(constructor, argumentList)。
  4. result.[[ContentType]] 不为 exemplar.[[ContentType]],抛出 TypeError 异常。
  5. 返回 result

23.2.4.4 ValidateTypedArray ( O, order )

The abstract operation ValidateTypedArray takes arguments O (an ECMAScript language value) and order (seq-cst or unordered) and returns 返回一个带缓冲见证记录的 TypedArray正常完成或抛出完成. It performs the following steps when called:

  1. 执行 ? RequireInternalSlot(O, [[TypedArrayName]])。
  2. 断言:O 具有 [[ViewedArrayBuffer]] 内部槽。
  3. taRecordMakeTypedArrayWithBufferWitnessRecord(O, order)。
  4. IsTypedArrayOutOfBounds(taRecord) 为 true,抛出 TypeError 异常。
  5. 返回 taRecord

23.2.4.5 TypedArrayElementSize ( O )

The abstract operation TypedArrayElementSize takes argument O (a TypedArray) and returns a non-negative integer. It performs the following steps when called:

  1. 返回在 Table 73 中为 O.[[TypedArrayName]] 指定的元素大小值。

23.2.4.6 TypedArrayElementType ( O )

The abstract operation TypedArrayElementType takes argument O (a TypedArray) and returns a TypedArray element type. It performs the following steps when called:

  1. 返回在 Table 73 中为 O.[[TypedArrayName]] 指定的元素类型值。

23.2.4.7 CompareTypedArrayElements ( x, y, comparator )

The abstract operation CompareTypedArrayElements takes arguments x (a Number or a BigInt), y (a Number or a BigInt), and comparator (a function object or undefined) and returns 返回一个 Number 的正常完成或一个突然完成. It performs the following steps when called:

  1. 断言:xy 同为 Number,或 xy 同为 BigInt。
  2. comparator 不为 undefined,则
    1. v 为 ? ToNumber(? Call(comparator, undefined, « x, y »))。
    2. vNaN,返回 +0𝔽
    3. 返回 v
  3. xy 均为 NaN,返回 +0𝔽
  4. xNaN,返回 1𝔽
  5. yNaN,返回 -1𝔽
  6. x < y,返回 -1𝔽
  7. x > y,返回 1𝔽
  8. x-0𝔽y+0𝔽,返回 -1𝔽
  9. x+0𝔽y-0𝔽,返回 1𝔽
  10. 返回 +0𝔽
Note
该操作执行数值比较,而非 23.1.3.30.2 中使用的字符串比较。

23.2.5 TypedArray 构造函数

每个 TypedArray 构造函数

  • 是具有下文所述结构的内在对象,区别仅在于在 Table 73 中用作构造函数名的名称不同于 TypedArray
  • 是其行为根据参数数量与类型而不同的函数。一次 TypedArray 调用的实际行为取决于传入的参数数量与种类。
  • 不应作为函数被调用,若以此方式调用将抛出异常。
  • 可作为类定义 extends 子句的值。意在继承所规定 TypedArray 行为的子类构造函数必须包含对 TypedArray 构造函数super 调用,以使用支持 %TypedArray%.prototype 内置方法所需的内部状态创建并初始化子类实例。

23.2.5.1 TypedArray ( ...args )

每个 TypedArray 构造函数被调用时执行以下步骤:

  1. 若 NewTarget 为 undefined,抛出 TypeError 异常。
  2. constructorName 为此 TypedArray 构造函数Table 73 中指定的构造函数名称的字符串值。
  3. proto"%TypedArray.prototype%"
  4. numberOfArgsargs 中元素的数量。
  5. numberOfArgs = 0,则
    1. 返回 ? AllocateTypedArray(constructorName, NewTarget, proto, 0)。
  6. 否则,
    1. firstArgument = args[0]。
    2. firstArgument 是对象,则
      1. O 为 ? AllocateTypedArray(constructorName, NewTarget, proto)。
      2. firstArgument 具有 [[TypedArrayName]] 内部槽,则
        1. 执行 ? InitializeTypedArrayFromTypedArray(O, firstArgument)。
      3. 否则若 firstArgument 具有 [[ArrayBufferData]] 内部槽,则
        1. numberOfArgs > 1,令 byteOffset = args[1];否则 byteOffset = undefined
        2. numberOfArgs > 2,令 length = args[2];否则 length = undefined
        3. 执行 ? InitializeTypedArrayFromArrayBuffer(O, firstArgument, byteOffset, length)。
      4. 否则,
        1. 断言:firstArgument 是对象且不具有 [[TypedArrayName]][[ArrayBufferData]]
        2. usingIterator = ? GetMethod(firstArgument, %Symbol.iterator%)。
        3. usingIterator 不为 undefined,则
          1. values = ? IteratorToList(? GetIteratorFromMethod(firstArgument, usingIterator))。
          2. 执行 ? InitializeTypedArrayFromList(O, values)。
        4. 否则,
          1. 注:firstArgument 不是可迭代对象,因此假定其已为类数组对象
          2. 执行 ? InitializeTypedArrayFromArrayLike(O, firstArgument)。
      5. 返回 O
    3. 否则,
      1. 断言:firstArgument 不是对象。
      2. elementLength = ? ToIndex(firstArgument)。
      3. 返回 ? AllocateTypedArray(constructorName, NewTarget, proto, elementLength)。

23.2.5.1.1 AllocateTypedArray ( constructorName, newTarget, defaultProto [ , length ] )

The abstract operation AllocateTypedArray takes arguments constructorName (a String which is the name of a TypedArray constructor in Table 73), newTarget (a constructor), and defaultProto (a String) and optional argument length (a non-negative integer) and returns 返回一个 TypedArray正常完成或抛出完成. 用于验证并创建某个 TypedArray 构造函数的实例。若传入 length,则还会分配一个该长度的 ArrayBuffer 并与新实例关联。AllocateTypedArray 提供 TypedArray 使用的通用语义。 It performs the following steps when called:

  1. proto 为 ? GetPrototypeFromConstructor(newTarget, defaultProto)。
  2. objTypedArrayCreate(proto)。
  3. 断言:obj.[[ViewedArrayBuffer]]undefined
  4. obj.[[TypedArrayName]] = constructorName
  5. constructorName"BigInt64Array""BigUint64Array",设 obj.[[ContentType]] = bigint
  6. 否则,设 obj.[[ContentType]] = number
  7. length 不存在,则
    1. obj.[[ByteLength]] = 0。
    2. obj.[[ByteOffset]] = 0。
    3. obj.[[ArrayLength]] = 0。
  8. 否则,
    1. 执行 ? AllocateTypedArrayBuffer(obj, length)。
  9. 返回 obj

23.2.5.1.2 InitializeTypedArrayFromTypedArray ( O, srcArray )

The abstract operation InitializeTypedArrayFromTypedArray takes arguments O (a TypedArray) and srcArray (a TypedArray) and returns 返回 unused正常完成或抛出完成. It performs the following steps when called:

  1. srcData = srcArray.[[ViewedArrayBuffer]]
  2. elementType = TypedArrayElementType(O)。
  3. elementSize = TypedArrayElementSize(O)。
  4. srcType = TypedArrayElementType(srcArray)。
  5. srcElementSize = TypedArrayElementSize(srcArray)。
  6. srcByteOffset = srcArray.[[ByteOffset]]
  7. srcRecordMakeTypedArrayWithBufferWitnessRecord(srcArray, seq-cst)。
  8. IsTypedArrayOutOfBounds(srcRecord) 为 true,抛出 TypeError 异常。
  9. elementLength = TypedArrayLength(srcRecord)。
  10. byteLength = elementSize × elementLength
  11. elementTypesrcType,则
    1. data = ? CloneArrayBuffer(srcData, srcByteOffset, byteLength)。
  12. 否则,
    1. data = ? AllocateArrayBuffer(%ArrayBuffer%, byteLength)。
    2. srcArray.[[ContentType]] 不等于 O.[[ContentType]],抛出 TypeError 异常。
    3. srcByteIndex = srcByteOffset
    4. targetByteIndex = 0。
    5. count = elementLength
    6. count > 0 重复,
      1. value = GetValueFromBuffer(srcData, srcByteIndex, srcType, true, unordered)。
      2. 执行 SetValueInBuffer(data, targetByteIndex, elementType, value, true, unordered)。
      3. srcByteIndex = srcByteIndex + srcElementSize
      4. targetByteIndex = targetByteIndex + elementSize
      5. count = count - 1。
  13. O.[[ViewedArrayBuffer]] = data
  14. O.[[ByteLength]] = byteLength
  15. O.[[ByteOffset]] = 0。
  16. O.[[ArrayLength]] = elementLength
  17. 返回 unused

23.2.5.1.3 InitializeTypedArrayFromArrayBuffer ( O, buffer, byteOffset, length )

The abstract operation InitializeTypedArrayFromArrayBuffer takes arguments O (a TypedArray), buffer (an ArrayBuffer or a SharedArrayBuffer), byteOffset (an ECMAScript language value), and length (an ECMAScript language value) and returns 返回 unused正常完成或抛出完成. It performs the following steps when called:

  1. elementSize = TypedArrayElementSize(O)。
  2. offset = ? ToIndex(byteOffset)。
  3. offsetelementSize ≠ 0,抛出 RangeError 异常。
  4. bufferIsFixedLength = IsFixedLengthArrayBuffer(buffer)。
  5. length 不为 undefined,则
    1. newLength = ? ToIndex(length)。
  6. IsDetachedBuffer(buffer) 为 true,抛出 TypeError 异常。
  7. bufferByteLength = ArrayBufferByteLength(buffer, seq-cst)。
  8. lengthundefinedbufferIsFixedLengthfalse,则
    1. offset > bufferByteLength,抛出 RangeError 异常。
    2. O.[[ByteLength]] = auto
    3. O.[[ArrayLength]] = auto
  9. 否则,
    1. lengthundefined,则
      1. bufferByteLengthelementSize ≠ 0,抛出 RangeError 异常。
      2. newByteLength = bufferByteLength - offset
      3. newByteLength < 0,抛出 RangeError 异常。
    2. 否则,
      1. newByteLength = newLength × elementSize
      2. offset + newByteLength > bufferByteLength,抛出 RangeError 异常。
    3. O.[[ByteLength]] = newByteLength
    4. O.[[ArrayLength]] = newByteLength / elementSize
  10. O.[[ViewedArrayBuffer]] = buffer
  11. O.[[ByteOffset]] = offset
  12. 返回 unused

23.2.5.1.4 InitializeTypedArrayFromList ( O, values )

The abstract operation InitializeTypedArrayFromList takes arguments O (a TypedArray) and values (a List of ECMAScript language values) and returns 返回 unused正常完成或抛出完成. It performs the following steps when called:

  1. lenvalues 中的元素数量。
  2. 执行 ? AllocateTypedArrayBuffer(O, len)。
  3. k = 0。
  4. k < len 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. kValuevalues 的第一个元素。
    3. 移除 values 的第一个元素。
    4. 执行 ? Set(O, Pk, kValue, true)。
    5. k = k + 1。
  5. 断言:values 现在为空列表。
  6. 返回 unused

23.2.5.1.5 InitializeTypedArrayFromArrayLike ( O, arrayLike )

The abstract operation InitializeTypedArrayFromArrayLike takes arguments O (a TypedArray) and arrayLike (an Object, but not a TypedArray or an ArrayBuffer) and returns 返回 unused正常完成或抛出完成. It performs the following steps when called:

  1. len 为 ? LengthOfArrayLike(arrayLike)。
  2. 执行 ? AllocateTypedArrayBuffer(O, len)。
  3. k = 0。
  4. k < len 重复,
    1. Pk = ! ToString(𝔽(k))。
    2. kValue = ? Get(arrayLike, Pk)。
    3. 执行 ? Set(O, Pk, kValue, true)。
    4. k = k + 1。
  5. 返回 unused

23.2.5.1.6 AllocateTypedArrayBuffer ( O, length )

The abstract operation AllocateTypedArrayBuffer takes arguments O (a TypedArray) and length (a non-negative integer) and returns 返回 unused正常完成或抛出完成. 为 O 分配并关联一个 ArrayBuffer。 It performs the following steps when called:

  1. 断言:O.[[ViewedArrayBuffer]]undefined
  2. elementSize = TypedArrayElementSize(O)。
  3. byteLength = elementSize × length
  4. data = ? AllocateArrayBuffer(%ArrayBuffer%, byteLength)。
  5. O.[[ViewedArrayBuffer]] = data
  6. O.[[ByteLength]] = byteLength
  7. O.[[ByteOffset]] = 0。
  8. O.[[ArrayLength]] = length
  9. 返回 unused

23.2.6 TypedArray 构造函数的属性

每个 TypedArray 构造函数

  • 具有 [[Prototype]] 内部槽,其值为 %TypedArray%
  • 具有 "length" 属性,其值为 3𝔽
  • 具有 "name" 属性,其值为在 Table 73 中为其指定的构造函数名称的字符串值。
  • 具有以下属性:

23.2.6.1 TypedArray.BYTES_PER_ELEMENT

TypedArray.BYTES_PER_ELEMENT 的值是 Table 73 中为 TypedArray 指定的元素大小值。

该属性特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

23.2.6.2 TypedArray.prototype

TypedArray.prototype 的初始值是对应的 TypedArray 原型内在对象(23.2.7)。

该属性特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

23.2.7 TypedArray 原型对象的属性

每个 TypedArray 原型对象:

  • 具有 [[Prototype]] 内部槽,其值为 %TypedArray.prototype%
  • 是一个普通对象
  • 没有 [[ViewedArrayBuffer]] 或其他特定于 TypedArray 实例对象的内部槽。

23.2.7.1 TypedArray.prototype.BYTES_PER_ELEMENT

TypedArray.prototype.BYTES_PER_ELEMENT 的值是 Table 73 中为 TypedArray 指定的元素大小值。

该属性特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

23.2.7.2 TypedArray.prototype.constructor

给定 TypedArray 构造函数的原型的 "constructor" 属性初始值为该构造函数本身。

23.2.8 TypedArray 实例的属性

TypedArray 实例是 TypedArrays。每个 TypedArray 实例从对应的 TypedArray 原型对象继承属性。每个 TypedArray 实例具有以下内部槽:[[ViewedArrayBuffer]][[TypedArrayName]][[ContentType]][[ByteLength]][[ByteOffset]][[ArrayLength]]

24 键控集合(Keyed Collections)

24.1 Map 对象

Map 是键/值对的集合,其中键和值都可以是任意 ECMAScript 语言值。一个特定的键值在该 Map 的集合中只能出现一次。不同的键值通过 SameValueZero 比较算法的语义加以区分。

Map 必须使用哈希表或其他在平均情况下能提供次线性访问时间的机制实现。本规范中使用的数据结构仅用于描述 Map 所需的可观察语义,而不是一个可行的实现模型。

24.1.1 Map 构造函数

Map 构造函数

  • %Map%
  • 是全局对象 "Map" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 Map。
  • 不应作为普通函数调用;若以此方式调用将抛出异常。
  • 可作为类定义 extends 子句的值。希望继承指定 Map 行为的子类构造函数必须包含对 Map 构造函数super 调用,以创建并初始化具有支持 Map.prototype 内置方法所需内部状态的子类实例。

24.1.1.1 Map ( [ iterable ] )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 是 undefined,抛出 TypeError 异常。
  2. map 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Map.prototype%", « [[MapData]] »)。
  3. map.[[MapData]] 设为一个新的空 List
  4. 如果 iterableundefinednull,返回 map
  5. adder 为 ? Get(map, "set")。
  6. 如果 IsCallable(adder) 为 false,抛出 TypeError 异常。
  7. 返回 ? AddEntriesFromIterable(map, iterable, adder)。
Note

如果参数 iterable 存在,期望它是一个实现了 %Symbol.iterator% 方法的对象,该迭代器返回的每个值是一个长度为 2 的类数组对象,其第一个元素用作 Map 的键,第二个元素是与该键关联的值。

24.1.1.2 AddEntriesFromIterable ( target, iterable, adder )

The abstract operation AddEntriesFromIterable takes arguments target (an Object), iterable (an ECMAScript language value, but not undefined or null), and adder (a function object) and returns 要么是包含一个 ECMAScript 语言值正常完成要么是抛出完成. adder 将以 target 作为接收者被调用。 It performs the following steps when called:

  1. iteratorRecord 为 ? GetIterator(iterable, sync)。
  2. 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,返回 target
    3. 如果 next 不是一个 Object,则
      1. errorThrowCompletion(一个新建的 TypeError 对象)。
      2. 返回 ? IteratorClose(iteratorRecord, error)。
    4. kCompletion(Get(next, "0" ))。
    5. IfAbruptCloseIterator(k, iteratorRecord)。
    6. vCompletion(Get(next, "1" ))。
    7. IfAbruptCloseIterator(v, iteratorRecord)。
    8. statusCompletion(Call(adder, target, « k, v »))。
    9. IfAbruptCloseIterator(status, iteratorRecord)。
Note

参数 iterable 期望是一个实现 %Symbol.iterator% 方法的对象,其迭代器产出的每个值是一个二元的类数组对象,第一个元素为 Map 键,第二个元素为与键关联的值。

24.1.2 Map 构造函数的属性

Map 构造函数

24.1.2.1 Map.groupBy ( items, callback )

Note

callback 应该是接受两个参数的函数。groupBy 按升序对 items 中的每个元素调用 callback,并构造一个新的 Map。callback 返回的每个值作为 Map 的一个键。对每个这样的键,结果 Map 有一个条目,其键是该键,其值是包含所有使得 callback 返回该键的元素的数组。

callback 以两个参数被调用:元素的值以及该元素的索引。

groupBy 的返回值是一个 Map。

该函数被调用时执行以下步骤:

  1. groups 为 ? GroupBy(items, callback, collection)。
  2. map 为 ! Construct(%Map%)。
  3. groups 中每个 Record { [[Key]], [[Elements]] } g
    1. elementsCreateArrayFromList(g.[[Elements]])。
    2. entry 为记录 { [[Key]]: g.[[Key]], [[Value]]: elements }。
    3. entry 追加到 map.[[MapData]]
  4. 返回 map

24.1.2.2 Map.prototype

Map.prototype 的初始值是 Map 原型对象

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

24.1.2.3 get Map [ %Symbol.species% ]

Map[%Symbol.species%] 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. 返回 this 值。

该函数 "name" 属性的值为 "get [Symbol.species]"

Note

创建派生集合对象的方法应调用 %Symbol.species% 来确定用于创建派生对象的构造函数。子类构造函数可以重写 %Symbol.species% 以改变默认的构造函数选择。

24.1.3 Map 原型对象的属性

Map 原型对象

24.1.3.1 Map.prototype.clear ( )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 执行 ? RequireInternalSlot(M, [[MapData]])。
  3. M.[[MapData]] 中每个 Record { [[Key]], [[Value]] } p
    1. p.[[Key]] 设为 empty
    2. p.[[Value]] 设为 empty
  4. 返回 undefined
Note

保留现有的 [[MapData]] List,是因为可能存在已经在该 List 中迭代到一半的 Map 迭代器对象。

24.1.3.2 Map.prototype.constructor

Map.prototype.constructor 的初始值是 %Map%

24.1.3.3 Map.prototype.delete ( key )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 执行 ? RequireInternalSlot(M, [[MapData]])。
  3. key 设为 CanonicalizeKeyedCollectionKey(key)。
  4. M.[[MapData]] 中每个 Record { [[Key]], [[Value]] } p
    1. 如果 p.[[Key]] 不是 emptySameValue(p.[[Key]], key) 为 true,则
      1. p.[[Key]] 设为 empty
      2. p.[[Value]] 设为 empty
      3. 返回 true
  5. 返回 false
Note

empty 用作规范设备以指示一个条目已被删除。实际实现可采取其它操作,如在内部数据结构中物理移除此条目。

24.1.3.4 Map.prototype.entries ( )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 返回 ? CreateMapIterator(M, key+value)。

24.1.3.5 Map.prototype.forEach ( callback [ , thisArg ] )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 执行 ? RequireInternalSlot(M, [[MapData]])。
  3. 如果 IsCallable(callback) 为 false,抛出 TypeError 异常。
  4. entriesM.[[MapData]]
  5. numEntriesentries 中元素的数量。
  6. index 为 0。
  7. index < numEntries 重复,
    1. eentries[index]。
    2. index 设为 index + 1。
    3. 如果 e.[[Key]] 不是 empty,则
      1. 执行 ? Call(callback, thisArg, « e.[[Value]], e.[[Key]], M »)。
      2. 注:在执行 callback 期间 entries 中元素数量可能增加。
      3. numEntries 设为 entries 中元素的数量。
  8. 返回 undefined
Note

callback 应为接受三个参数的函数。forEach 按键插入顺序对 Map 中每个键/值对调用一次 callback。仅对 Map 中实际存在的键调用;已删除的键不会调用。

如果提供 thisArg,它将在每次调用 callback 时用作 this 值;否则使用 undefined

callback 以三个参数调用:条目的值、条目的键以及被遍历的 Map。

forEach 不直接修改其被调用的对象,但该对象可在 callback 内被修改。Map 的 [[MapData]] 中的每个条目只访问一次。调用开始后新增的键会被访问。一个键如果在访问后被删除然后在调用结束前又被重新加入会被再次访问。调用开始后删除且尚未访问的键不会被访问,除非它在调用结束前再次添加。

24.1.3.6 Map.prototype.get ( key )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 执行 ? RequireInternalSlot(M, [[MapData]])。
  3. key 设为 CanonicalizeKeyedCollectionKey(key)。
  4. M.[[MapData]] 中每个 Record { [[Key]], [[Value]] } p
    1. 如果 p.[[Key]] 不是 emptySameValue(p.[[Key]], key) 为 true,返回 p.[[Value]]
  5. 返回 undefined

24.1.3.7 Map.prototype.has ( key )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 执行 ? RequireInternalSlot(M, [[MapData]])。
  3. key 设为 CanonicalizeKeyedCollectionKey(key)。
  4. M.[[MapData]] 中每个 Record { [[Key]], [[Value]] } p
    1. 如果 p.[[Key]] 不是 emptySameValue(p.[[Key]], key) 为 true,返回 true
  5. 返回 false

24.1.3.8 Map.prototype.keys ( )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 返回 ? CreateMapIterator(M, key)。

24.1.3.9 Map.prototype.set ( key, value )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 执行 ? RequireInternalSlot(M, [[MapData]])。
  3. key 设为 CanonicalizeKeyedCollectionKey(key)。
  4. M.[[MapData]] 中每个 Record { [[Key]], [[Value]] } p
    1. 如果 p.[[Key]] 不是 emptySameValue(p.[[Key]], key) 为 true,则
      1. p.[[Value]] 设为 value
      2. 返回 M
  5. p 为记录 { [[Key]]: key, [[Value]]: value }。
  6. p 追加到 M.[[MapData]]
  7. 返回 M

24.1.3.10 get Map.prototype.size

Map.prototype.size 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Mthis 值。
  2. 执行 ? RequireInternalSlot(M, [[MapData]])。
  3. count 为 0。
  4. M.[[MapData]] 中每个 Record { [[Key]], [[Value]] } p
    1. 如果 p.[[Key]] 不是 empty,将 count 设为 count + 1。
  5. 返回 𝔽(count)。

24.1.3.11 Map.prototype.values ( )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 返回 ? CreateMapIterator(M, value)。

24.1.3.12 Map.prototype [ %Symbol.iterator% ] ( )

%Symbol.iterator% 属性的初始值是 %Map.prototype.entries%,定义见 24.1.3.4

24.1.3.13 Map.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "Map"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

24.1.4 Map 实例的属性

Map 实例是普通对象,从 Map 原型对象继承属性。Map 实例还具有 [[MapData]] 内部槽。

24.1.5 Map 迭代器对象

Map Iterator 是一个表示对某个特定 Map 实例对象的特定迭代的对象。没有命名的 Map 迭代器构造函数。相反,通过调用某些 Map 实例对象的方法创建 Map 迭代器对象。

24.1.5.1 CreateMapIterator ( map, kind )

The abstract operation CreateMapIterator takes arguments map (an ECMAScript language value) and kind (key+value, key, or value) and returns 一个包含 Generator 的正常完成或抛出完成. 用于为返回此类迭代器的 Map 方法创建迭代器对象。 It performs the following steps when called:

  1. 执行 ? RequireInternalSlot(map, [[MapData]])。
  2. closure 为一个无参数的新抽象闭包,捕获 mapkind 并在调用时执行:
    1. entriesmap.[[MapData]]
    2. index 为 0。
    3. numEntriesentries 中元素的数量。
    4. index < numEntries 重复,
      1. eentries[index]。
      2. index 设为 index + 1。
      3. 如果 e.[[Key]] 不是 empty,则
        1. 如果 kindkey,则
          1. resulte.[[Key]]
        2. 否则如果 kindvalue,则
          1. resulte.[[Value]]
        3. 否则,
          1. 断言:kindkey+value
          2. resultCreateArrayFromListe.[[Key]], e.[[Value]] »)。
        4. 执行 ? GeneratorYield(CreateIteratorResultObject(result, false))。
        5. 注:在 GeneratorYield 暂停本抽象操作执行期间,entries 中的元素数量可能增加。
        6. numEntries 设为 entries 中元素的数量。
    5. 返回 NormalCompletion(unused)。
  3. 返回 CreateIteratorFromClosure(closure, "%MapIteratorPrototype%", %MapIteratorPrototype%)。

24.1.5.2 %MapIteratorPrototype% 对象

%MapIteratorPrototype% 对象:

  • 具有所有 Map 迭代器对象继承的属性。
  • 是一个普通对象
  • 有一个 [[Prototype]] 内部槽,其值为 %Iterator.prototype%
  • 具有以下属性:

24.1.5.2.1 %MapIteratorPrototype%.next ( )

  1. 返回 ? GeneratorResume(this value, empty, "%MapIteratorPrototype%")。

24.1.5.2.2 %MapIteratorPrototype% [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "Map Iterator"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

24.2 Set 对象

Set 对象是 ECMAScript 语言值的集合。一个特定的值在 Set 的集合中只能出现一次。不同的值通过 SameValueZero 比较算法的语义区分。

Set 对象必须使用哈希表或其他平均情况下提供次线性访问时间的机制实现。本规范使用的数据结构仅用于描述 Set 对象所需的可观察语义,不是可行的实现模型。

24.2.1 Set 对象的抽象操作

24.2.1.1 Set 记录

Set Record 是用于封装 Set 或类似对象接口的 Record 值。

Set 记录具有 Table 74 中列出的字段。

Table 74: Set 记录字段
字段名 取值 含义
[[SetObject]] an Object 该 Set 或类似对象。
[[Size]] a non-negative integer or +∞ 对象报告的大小。
[[Has]] a function object 对象的 has 方法。
[[Keys]] a function object 对象的 keys 方法。

24.2.1.2 GetSetRecord ( obj )

The abstract operation GetSetRecord takes argument obj (an ECMAScript language value) and returns 一个包含 Set Record正常完成或抛出完成. It performs the following steps when called:

  1. 如果 obj 不是一个 Object,抛出 TypeError 异常。
  2. rawSize 为 ? Get(obj, "size")。
  3. numSize 为 ? ToNumber(rawSize)。
  4. 注:如果 rawSizeundefined,则 numSize 将为 NaN
  5. 如果 numSizeNaN,抛出 TypeError 异常。
  6. intSize 为 ! ToIntegerOrInfinity(numSize)。
  7. 如果 intSize < 0,抛出 RangeError 异常。
  8. has 为 ? Get(obj, "has")。
  9. 如果 IsCallable(has) 为 false,抛出 TypeError 异常。
  10. keys 为 ? Get(obj, "keys")。
  11. 如果 IsCallable(keys) 为 false,抛出 TypeError 异常。
  12. 返回一个新的 Set Record { [[SetObject]]: obj, [[Size]]: intSize, [[Has]]: has, [[Keys]]: keys }。

24.2.1.3 SetDataHas ( setData, value )

The abstract operation SetDataHas takes arguments setData (a List of either ECMAScript language values or empty) and value (an ECMAScript language value) and returns a Boolean. It performs the following steps when called:

  1. 如果 SetDataIndex(setData, value) 是 not-found,返回 false
  2. 返回 true

24.2.1.4 SetDataIndex ( setData, value )

The abstract operation SetDataIndex takes arguments setData (a List of either ECMAScript language values or empty) and value (an ECMAScript language value) and returns 一个非负整数或 not-found. It performs the following steps when called:

  1. value 设为 CanonicalizeKeyedCollectionKey(value)。
  2. sizesetData 中的元素数量。
  3. index 为 0。
  4. index < size 重复,
    1. esetData[index]。
    2. 如果 e 不是 emptyevalue,则
      1. 返回 index
    3. index 设为 index + 1。
  5. 返回 not-found

24.2.1.5 SetDataSize ( setData )

The abstract operation SetDataSize takes argument setData (a List of either ECMAScript language values or empty) and returns 一个非负整数. It performs the following steps when called:

  1. count 为 0。
  2. setData 中每个元素 e
    1. 如果 e 不是 empty,将 count 设为 count + 1。
  3. 返回 count

24.2.2 Set 构造函数

Set 构造函数

  • %Set%
  • 是全局对象 "Set" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 Set 对象。
  • 不应作为普通函数调用;若以此方式调用将抛出异常。
  • 可作为类定义 extends 子句的值。希望继承指定 Set 行为的子类构造函数必须包含对 Set 构造函数super 调用,以创建并初始化具有支持 Set.prototype 内置方法所需内部状态的子类实例。

24.2.2.1 Set ( [ iterable ] )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 是 undefined,抛出 TypeError 异常。
  2. set 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Set.prototype%", « [[SetData]] »)。
  3. set.[[SetData]] 设为一个新的空 List
  4. 如果 iterableundefinednull,返回 set
  5. adder 为 ? Get(set, "add")。
  6. 如果 IsCallable(adder) 为 false,抛出 TypeError 异常。
  7. iteratorRecord 为 ? GetIterator(iterable, sync)。
  8. 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,返回 set
    3. statusCompletion(Call(adder, set, « next »))。
    4. IfAbruptCloseIterator(status, iteratorRecord)。

24.2.3 Set 构造函数的属性

Set 构造函数

24.2.3.1 Set.prototype

Set.prototype 的初始值是 Set 原型对象

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

24.2.3.2 get Set [ %Symbol.species% ]

Set[%Symbol.species%] 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. 返回 this 值。

该函数 "name" 属性的值为 "get [Symbol.species]"

Note

创建派生集合对象的方法应调用 %Symbol.species% 来确定用于创建派生对象的构造函数。子类构造函数可重写 %Symbol.species% 来改变默认的构造函数选择。

24.2.4 Set 原型对象的属性

Set 原型对象

24.2.4.1 Set.prototype.add ( value )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 执行 ? RequireInternalSlot(S, [[SetData]])。
  3. value 设为 CanonicalizeKeyedCollectionKey(value)。
  4. S.[[SetData]] 中每个元素 e
    1. 如果 e 不是 emptySameValue(e, value) 为 true,则
      1. 返回 S
  5. value 追加到 S.[[SetData]]
  6. 返回 S

24.2.4.2 Set.prototype.clear ( )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 执行 ? RequireInternalSlot(S, [[SetData]])。
  3. S.[[SetData]] 中每个元素 e
    1. 用值为 empty 的元素替换 S.[[SetData]] 中值为 e 的元素。
  4. 返回 undefined
Note

保留现有 [[SetData]] List,因为可能存在已经在该 List 中迭代到一半的 Set 迭代器对象。

24.2.4.3 Set.prototype.constructor

Set.prototype.constructor 的初始值是 %Set%

24.2.4.4 Set.prototype.delete ( value )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 执行 ? RequireInternalSlot(S, [[SetData]])。
  3. value 设为 CanonicalizeKeyedCollectionKey(value)。
  4. S.[[SetData]] 中每个元素 e
    1. 如果 e 不是 emptySameValue(e, value) 为 true,则
      1. 用值为 empty 的元素替换 S.[[SetData]] 中值为 e 的元素。
      2. 返回 true
  5. 返回 false
Note

empty 用作规范设备指示条目已删除。实际实现可以物理删除该条目等。

24.2.4.5 Set.prototype.difference ( other )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[SetData]])。
  3. otherRec 为 ? GetSetRecord(other)。
  4. resultSetDataO.[[SetData]] 的一个拷贝。
  5. 如果 SetDataSize(O.[[SetData]]) ≤ otherRec.[[Size]],则
    1. thisSizeO.[[SetData]] 中元素的数量。
    2. index 为 0。
    3. index < thisSize 重复,
      1. eresultSetData[index]。
      2. 如果 e 不是 empty,则
        1. inOtherToBoolean(? Call(otherRec.[[Has]], otherRec.[[SetObject]], « e »))。
        2. 如果 inOthertrue,则
          1. resultSetData[index] 设为 empty
      3. index 设为 index + 1。
  6. 否则,
    1. keysIter 为 ? GetIteratorFromMethod(otherRec.[[SetObject]], otherRec.[[Keys]])。
    2. nextnot-started
    3. next 不是 done 重复,
      1. next 设为 ? IteratorStepValue(keysIter)。
      2. 如果 next 不是 done,则
        1. next 设为 CanonicalizeKeyedCollectionKey(next)。
        2. valueIndexSetDataIndex(resultSetData, next)。
        3. 如果 valueIndex 不是 not-found,则
          1. resultSetData[valueIndex] 设为 empty
  7. resultOrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »)。
  8. result.[[SetData]] 设为 resultSetData
  9. 返回 result

24.2.4.6 Set.prototype.entries ( )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateSetIterator(S, key+value)。
Note

在迭代语义上,Set 类似于每个条目键和值相同的 Map。

24.2.4.7 Set.prototype.forEach ( callback [ , thisArg ] )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 执行 ? RequireInternalSlot(S, [[SetData]])。
  3. 如果 IsCallable(callback) 为 false,抛出 TypeError 异常。
  4. entriesS.[[SetData]]
  5. numEntriesentries 中元素的数量。
  6. index 为 0。
  7. index < numEntries 重复,
    1. eentries[index]。
    2. index 设为 index + 1。
    3. 如果 e 不是 empty,则
      1. 执行 ? Call(callback, thisArg, « e, e, S »)。
      2. 注:执行 callback 期间 entries 中元素数量可能增加。
      3. numEntries 设为 entries 中元素的数量。
  8. 返回 undefined
Note

callback 应为接受三个参数的函数。forEach 按值插入顺序对 Set 对象中每个值调用一次 callback。仅对实际存在的值调用;对已删除的值不会调用。

如果提供 thisArg,它作为每次调用 callbackthis 值;否则使用 undefined

callback 以三个参数调用:前两个参数是 Set 中的一个值(相同的值传两次),第三个参数是被遍历的 Set 对象。

callback 传递三个参数是为了与 Map 和 Array 的 forEach 回调函数保持一致;在 Set 中每个值同时被视为键和值。

forEach 不直接修改其被调用的对象,但对象可在 callback 中被修改。

每个值通常只访问一次;但如果某值在被访问后被删除并在调用结束前重新加入,会被再次访问。调用开始后删除且尚未访问的值不会被访问,除非在调用结束前再次添加。调用开始后新增的值会被访问。

24.2.4.8 Set.prototype.has ( value )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 执行 ? RequireInternalSlot(S, [[SetData]])。
  3. value 设为 CanonicalizeKeyedCollectionKey(value)。
  4. S.[[SetData]] 中每个元素 e
    1. 如果 e 不是 emptySameValue(e, value) 为 true,返回 true
  5. 返回 false

24.2.4.9 Set.prototype.intersection ( other )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[SetData]])。
  3. otherRec 为 ? GetSetRecord(other)。
  4. resultSetData 为一个新的空 List
  5. 如果 SetDataSize(O.[[SetData]]) ≤ otherRec.[[Size]],则
    1. thisSizeO.[[SetData]] 中元素的数量。
    2. index 为 0。
    3. index < thisSize 重复,
      1. eO.[[SetData]][index]。
      2. index 设为 index + 1。
      3. 如果 e 不是 empty,则
        1. inOtherToBoolean(? Call(otherRec.[[Has]], otherRec.[[SetObject]], « e »))。
        2. 如果 inOthertrue,则
          1. 注:早先对 otherRec.[[Has]] 的调用可能移除并重新添加 O.[[SetData]] 的元素,导致同一元素在本次迭代中被访问两次。
          2. 如果 SetDataHas(resultSetData, e) 为 false,则
            1. e 追加到 resultSetData
        3. 注:执行 otherRec.[[Has]] 期间 O.[[SetData]] 中元素数量可能增加。
        4. thisSize 设为 O.[[SetData]] 中元素的数量。
  6. 否则,
    1. keysIter 为 ? GetIteratorFromMethod(otherRec.[[SetObject]], otherRec.[[Keys]])。
    2. nextnot-started
    3. next 不是 done 重复,
      1. next 设为 ? IteratorStepValue(keysIter)。
      2. 如果 next 不是 done,则
        1. next 设为 CanonicalizeKeyedCollectionKey(next)。
        2. inThisSetDataHas(O.[[SetData]], next)。
        3. 如果 inThistrue,则
          1. 注:因为 other 是一个任意对象,其 "keys" 迭代器可能多次产生同一值。
          2. 如果 SetDataHas(resultSetData, next) 为 false,则
            1. next 追加到 resultSetData
  7. resultOrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »)。
  8. result.[[SetData]] 设为 resultSetData
  9. 返回 result

24.2.4.10 Set.prototype.isDisjointFrom ( other )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[SetData]])。
  3. otherRec 为 ? GetSetRecord(other)。
  4. 如果 SetDataSize(O.[[SetData]]) ≤ otherRec.[[Size]],则
    1. thisSizeO.[[SetData]] 中元素的数量。
    2. index 为 0。
    3. index < thisSize 重复,
      1. eO.[[SetData]][index]。
      2. index 设为 index + 1。
      3. 如果 e 不是 empty,则
        1. inOtherToBoolean(? Call(otherRec.[[Has]], otherRec.[[SetObject]], « e »))。
        2. 如果 inOthertrue,返回 false
        3. 注:执行 otherRec.[[Has]] 期间 O.[[SetData]] 中元素数量可能增加。
        4. thisSize 设为 O.[[SetData]] 中元素的数量。
  5. 否则,
    1. keysIter 为 ? GetIteratorFromMethod(otherRec.[[SetObject]], otherRec.[[Keys]])。
    2. nextnot-started
    3. next 不是 done 重复,
      1. next 设为 ? IteratorStepValue(keysIter)。
      2. 如果 next 不是 done,则
        1. 如果 SetDataHas(O.[[SetData]], next) 为 true,则
          1. 执行 ? IteratorClose(keysIter, NormalCompletion(unused))。
          2. 返回 false
  6. 返回 true

24.2.4.11 Set.prototype.isSubsetOf ( other )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[SetData]])。
  3. otherRec 为 ? GetSetRecord(other)。
  4. 如果 SetDataSize(O.[[SetData]]) > otherRec.[[Size]],返回 false
  5. thisSizeO.[[SetData]] 中元素数量。
  6. index 为 0。
  7. index < thisSize 重复,
    1. eO.[[SetData]][index]。
    2. index 设为 index + 1。
    3. 如果 e 不是 empty,则
      1. inOtherToBoolean(? Call(otherRec.[[Has]], otherRec.[[SetObject]], « e »))。
      2. 如果 inOtherfalse,返回 false
      3. 注:执行 otherRec.[[Has]] 期间 O.[[SetData]] 中元素数量可能增加。
      4. thisSize 设为 O.[[SetData]] 中元素的数量。
  8. 返回 true

24.2.4.12 Set.prototype.isSupersetOf ( other )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[SetData]])。
  3. otherRec 为 ? GetSetRecord(other)。
  4. 如果 SetDataSize(O.[[SetData]]) < otherRec.[[Size]],返回 false
  5. keysIter 为 ? GetIteratorFromMethod(otherRec.[[SetObject]], otherRec.[[Keys]])。
  6. nextnot-started
  7. next 不是 done 重复,
    1. next 设为 ? IteratorStepValue(keysIter)。
    2. 如果 next 不是 done,则
      1. 如果 SetDataHas(O.[[SetData]], next) 为 false,则
        1. 执行 ? IteratorClose(keysIter, NormalCompletion(unused))。
        2. 返回 false
  8. 返回 true

24.2.4.13 Set.prototype.keys ( )

"keys" 属性的初始值是 %Set.prototype.values%,定义见 24.2.4.17

Note

在迭代语义上,Set 类似于每个条目键和值相同的 Map。

24.2.4.14 get Set.prototype.size

Set.prototype.size 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Sthis 值。
  2. 执行 ? RequireInternalSlot(S, [[SetData]])。
  3. sizeSetDataSize(S.[[SetData]])。
  4. 返回 𝔽(size)。

24.2.4.15 Set.prototype.symmetricDifference ( other )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[SetData]])。
  3. otherRec 为 ? GetSetRecord(other)。
  4. keysIter 为 ? GetIteratorFromMethod(otherRec.[[SetObject]], otherRec.[[Keys]])。
  5. resultSetDataO.[[SetData]] 的一个拷贝。
  6. nextnot-started
  7. next 不是 done 重复,
    1. next 设为 ? IteratorStepValue(keysIter)。
    2. 如果 next 不是 done,则
      1. next 设为 CanonicalizeKeyedCollectionKey(next)。
      2. resultIndexSetDataIndex(resultSetData, next)。
      3. 如果 resultIndexnot-found,令 alreadyInResultfalse;否则令其为 true
      4. 如果 SetDataHas(O.[[SetData]], next) 为 true,则
        1. 如果 alreadyInResulttrue,将 resultSetData[resultIndex] 设为 empty
      5. 否则,
        1. 如果 alreadyInResultfalse,将 next 追加到 resultSetData
  8. resultOrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »)。
  9. result.[[SetData]] 设为 resultSetData
  10. 返回 result

24.2.4.16 Set.prototype.union ( other )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[SetData]])。
  3. otherRec 为 ? GetSetRecord(other)。
  4. keysIter 为 ? GetIteratorFromMethod(otherRec.[[SetObject]], otherRec.[[Keys]])。
  5. resultSetDataO.[[SetData]] 的一个拷贝。
  6. nextnot-started
  7. next 不是 done 重复,
    1. next 设为 ? IteratorStepValue(keysIter)。
    2. 如果 next 不是 done,则
      1. next 设为 CanonicalizeKeyedCollectionKey(next)。
      2. 如果 SetDataHas(resultSetData, next) 为 false,则
        1. next 追加到 resultSetData
  8. resultOrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »)。
  9. result.[[SetData]] 设为 resultSetData
  10. 返回 result

24.2.4.17 Set.prototype.values ( )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateSetIterator(S, value)。

24.2.4.18 Set.prototype [ %Symbol.iterator% ] ( )

%Symbol.iterator% 属性的初始值是 %Set.prototype.values%,定义见 24.2.4.17

24.2.4.19 Set.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "Set"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

24.2.5 Set 实例的属性

Set 实例是普通对象,从 Set 原型对象继承属性。Set 实例还具有 [[SetData]] 内部槽。

24.2.6 Set 迭代器对象

Set Iterator 是一个普通对象,结构如下,表示对某个特定 Set 实例对象的特定迭代。没有命名的 Set 迭代器构造函数。相反,通过调用某些 Set 实例对象的方法创建 Set 迭代器对象。

24.2.6.1 CreateSetIterator ( set, kind )

The abstract operation CreateSetIterator takes arguments set (an ECMAScript language value) and kind (key+value or value) and returns 一个包含 Generator 的正常完成或抛出完成. 用于为返回此类迭代器的 Set 方法创建迭代器对象。 It performs the following steps when called:

  1. 执行 ? RequireInternalSlot(set, [[SetData]])。
  2. closure 为一个无参数的新抽象闭包,捕获 setkind 并在调用时执行:
    1. index 为 0。
    2. entriesset.[[SetData]]
    3. numEntriesentries 中元素的数量。
    4. index < numEntries 重复,
      1. eentries[index]。
      2. index 设为 index + 1。
      3. 如果 e 不是 empty,则
        1. 如果 kindkey+value,则
          1. resultCreateArrayFromListe, e »)。
          2. 执行 ? GeneratorYield(CreateIteratorResultObject(result, false))。
        2. 否则,
          1. 断言:kindvalue
          2. 执行 ? GeneratorYield(CreateIteratorResultObject(e, false))。
        3. 注:在 GeneratorYield 暂停本抽象操作执行期间,entries 中元素数量可能增加。
        4. numEntries 设为 entries 中元素的数量。
    5. 返回 NormalCompletion(unused)。
  3. 返回 CreateIteratorFromClosure(closure, "%SetIteratorPrototype%", %SetIteratorPrototype%)。

24.2.6.2 %SetIteratorPrototype% 对象

%SetIteratorPrototype% 对象:

  • 具有所有 Set 迭代器对象继承的属性。
  • 是一个普通对象
  • 有一个 [[Prototype]] 内部槽,其值为 %Iterator.prototype%
  • 具有以下属性:

24.2.6.2.1 %SetIteratorPrototype%.next ( )

  1. 返回 ? GeneratorResume(this value, empty, "%SetIteratorPrototype%")。

24.2.6.2.2 %SetIteratorPrototype% [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "Set Iterator"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

24.3 WeakMap 对象

WeakMap 是键/值对的集合,其中键是对象和/或符号,值可以是任意 ECMAScript 语言值。可以查询 WeakMap 是否包含具有特定键的键/值对,但没有枚举其持有键的机制。在特定条件下,非存活的值会作为 WeakMap 的键被移除,详见 9.9.3

实现可以在 WeakMap 的键/值对变得不可访问与其被移除之间施加任意决定的延迟。若该延迟对 ECMAScript 程序可观察,将导致不确定性并影响程序执行。因此,实现不得提供任何不需要观察者出示被观察键就能观察 WeakMap 键的方式。

WeakMap 必须使用哈希表或其他平均情况下提供次线性访问时间的机制实现。本规范使用的数据结构仅用于描述 WeakMap 所需的可观察语义,而非可行实现模型。

Note

WeakMap 和 WeakSet 旨在提供一种动态地将状态与对象或符号关联的机制,在没有 WeakMap 或 WeakSet 实例的情况下,如果对象或符号本来会变得不可访问并被实现的垃圾回收机制回收,这种机制不会“泄漏”内存资源。该特性可以通过使用按对象/符号反向映射 WeakMap 或 WeakSet 实例到键来实现。或者,每个 WeakMap 或 WeakSet 实例可以在内部存储其键和值数据,但这种方法需要 WeakMap 或 WeakSet 实现与垃圾回收器协同。以下参考文献描述的机制可能对 WeakMap 和 WeakSet 的实现有用:

Barry Hayes. 1997. Ephemerons: a new finalization mechanism. 载于 Proceedings of the 12th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications (OOPSLA '97), A. Michael Berman (编). ACM, New York, NY, USA, 176-183, http://doi.acm.org/10.1145/263698.263733

Alexandra Barros, Roberto Ierusalimschy, Eliminating Cycles in Weak Tables. Journal of Universal Computer Science - J.UCS, vol. 14, no. 21, pp. 3481-3497, 2008, http://www.jucs.org/jucs_14_21/eliminating_cycles_in_weak

24.3.1 WeakMap 构造函数

WeakMap 构造函数

  • %WeakMap%
  • 是全局对象 "WeakMap" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 WeakMap。
  • 不应作为普通函数调用;若以此方式调用将抛出异常。
  • 可作为类定义 extends 子句的值。希望继承指定 WeakMap 行为的子类构造函数必须包含对 WeakMap 构造函数super 调用,以创建并初始化具有支持 WeakMap.prototype 内置方法所需内部状态的子类实例。

24.3.1.1 WeakMap ( [ iterable ] )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 是 undefined,抛出 TypeError 异常。
  2. map 为 ? OrdinaryCreateFromConstructor(NewTarget, "%WeakMap.prototype%", « [[WeakMapData]] »)。
  3. map.[[WeakMapData]] 设为一个新的空 List
  4. 如果 iterableundefinednull,返回 map
  5. adder 为 ? Get(map, "set")。
  6. 如果 IsCallable(adder) 为 false,抛出 TypeError 异常。
  7. 返回 ? AddEntriesFromIterable(map, iterable, adder)。
Note

如果参数 iterable 存在,期望它是一个实现了 %Symbol.iterator% 方法的对象,迭代器返回的每个值是一个包含两个元素的类数组对象,第一个元素作为 WeakMap 键,第二个元素为与该键关联的值。

24.3.2 WeakMap 构造函数的属性

WeakMap 构造函数

24.3.2.1 WeakMap.prototype

WeakMap.prototype 的初始值是 WeakMap 原型对象

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

24.3.3 WeakMap 原型对象的属性

WeakMap 原型对象

  • %WeakMap.prototype%
  • 有一个 [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 是一个普通对象
  • 没有 [[WeakMapData]] 内部槽。

24.3.3.1 WeakMap.prototype.constructor

WeakMap.prototype.constructor 的初始值是 %WeakMap%

24.3.3.2 WeakMap.prototype.delete ( key )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 执行 ? RequireInternalSlot(M, [[WeakMapData]])。
  3. 如果 CanBeHeldWeakly(key) 为 false,返回 false
  4. M.[[WeakMapData]] 中每个 Record { [[Key]], [[Value]] } p
    1. 如果 p.[[Key]] 不是 emptySameValue(p.[[Key]], key) 为 true,则
      1. p.[[Key]] 设为 empty
      2. p.[[Value]] 设为 empty
      3. 返回 true
  5. 返回 false
Note

empty 用作规范设备指示条目已删除。实际实现可能物理移除该条目。

24.3.3.3 WeakMap.prototype.get ( key )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 执行 ? RequireInternalSlot(M, [[WeakMapData]])。
  3. 如果 CanBeHeldWeakly(key) 为 false,返回 undefined
  4. M.[[WeakMapData]] 中每个 Record { [[Key]], [[Value]] } p
    1. 如果 p.[[Key]] 不是 emptySameValue(p.[[Key]], key) 为 true,返回 p.[[Value]]
  5. 返回 undefined

24.3.3.4 WeakMap.prototype.has ( key )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 执行 ? RequireInternalSlot(M, [[WeakMapData]])。
  3. 如果 CanBeHeldWeakly(key) 为 false,返回 false
  4. M.[[WeakMapData]] 中每个 Record { [[Key]], [[Value]] } p
    1. 如果 p.[[Key]] 不是 emptySameValue(p.[[Key]], key) 为 true,返回 true
  5. 返回 false

24.3.3.5 WeakMap.prototype.set ( key, value )

该方法被调用时执行以下步骤:

  1. Mthis 值。
  2. 执行 ? RequireInternalSlot(M, [[WeakMapData]])。
  3. 如果 CanBeHeldWeakly(key) 为 false,抛出 TypeError 异常。
  4. M.[[WeakMapData]] 中每个 Record { [[Key]], [[Value]] } p
    1. 如果 p.[[Key]] 不是 emptySameValue(p.[[Key]], key) 为 true,则
      1. p.[[Value]] 设为 value
      2. 返回 M
  5. p 为记录 { [[Key]]: key, [[Value]]: value }。
  6. p 追加到 M.[[WeakMapData]]
  7. 返回 M

24.3.3.6 WeakMap.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "WeakMap"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

24.3.4 WeakMap 实例的属性

WeakMap 实例是普通对象,从 WeakMap 原型对象继承属性。WeakMap 实例还具有 [[WeakMapData]] 内部槽。

24.4 WeakSet 对象

WeakSet 是对象和/或符号的集合。一个特定对象或符号在 WeakSet 的集合中只能出现一次。可以查询 WeakSet 是否包含一个特定值,但没有枚举其持有值的机制。在特定条件下,非存活的值会作为 WeakSet 元素被移除,详见 9.9.3

实现可以在 WeakSet 中的一个值变得不可访问与其被移除之间施加任意决定的延迟。若该延迟对 ECMAScript 程序可观察,将导致不确定性并影响程序执行。因此,实现不得提供不需要观察者出示被观察值就能判断 WeakSet 是否包含该值的方式。

WeakSet 必须使用哈希表或其他平均情况下提供次线性访问时间的机制实现。本规范使用的数据结构仅用于描述 WeakSet 所需的可观察语义,并非可行实现模型。

Note

参见 24.3 中的注。

24.4.1 WeakSet 构造函数

WeakSet 构造函数

  • %WeakSet%
  • 是全局对象 "WeakSet" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 WeakSet。
  • 不应作为普通函数调用;若以此方式调用将抛出异常。
  • 可作为类定义 extends 子句的值。希望继承指定 WeakSet 行为的子类构造函数必须包含对 WeakSet 构造函数super 调用,以创建并初始化具有支持 WeakSet.prototype 内置方法所需内部状态的子类实例。

24.4.1.1 WeakSet ( [ iterable ] )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 是 undefined,抛出 TypeError 异常。
  2. set 为 ? OrdinaryCreateFromConstructor(NewTarget, "%WeakSet.prototype%", « [[WeakSetData]] »)。
  3. set.[[WeakSetData]] 设为一个新的空 List
  4. 如果 iterableundefinednull,返回 set
  5. adder 为 ? Get(set, "add")。
  6. 如果 IsCallable(adder) 为 false,抛出 TypeError 异常。
  7. iteratorRecord 为 ? GetIterator(iterable, sync)。
  8. 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,返回 set
    3. statusCompletion(Call(adder, set, « next »))。
    4. IfAbruptCloseIterator(status, iteratorRecord)。

24.4.2 WeakSet 构造函数的属性

WeakSet 构造函数

24.4.2.1 WeakSet.prototype

WeakSet.prototype 的初始值是 WeakSet 原型对象

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

24.4.3 WeakSet 原型对象的属性

WeakSet 原型对象

  • %WeakSet.prototype%
  • 有一个 [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 是一个普通对象
  • 没有 [[WeakSetData]] 内部槽。

24.4.3.1 WeakSet.prototype.add ( value )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 执行 ? RequireInternalSlot(S, [[WeakSetData]])。
  3. 如果 CanBeHeldWeakly(value) 为 false,抛出 TypeError 异常。
  4. S.[[WeakSetData]] 中每个元素 e
    1. 如果 e 不是 emptySameValue(e, value) 为 true,则
      1. 返回 S
  5. value 追加到 S.[[WeakSetData]]
  6. 返回 S

24.4.3.2 WeakSet.prototype.constructor

WeakSet.prototype.constructor 的初始值是 %WeakSet%

24.4.3.3 WeakSet.prototype.delete ( value )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 执行 ? RequireInternalSlot(S, [[WeakSetData]])。
  3. 如果 CanBeHeldWeakly(value) 为 false,返回 false
  4. S.[[WeakSetData]] 中每个元素 e
    1. 如果 e 不是 emptySameValue(e, value) 为 true,则
      1. 用值为 empty 的元素替换 S.[[WeakSetData]] 中值为 e 的元素。
      2. 返回 true
  5. 返回 false
Note

empty 用作规范设备指示条目已删除。实际实现可能物理移除该条目。

24.4.3.4 WeakSet.prototype.has ( value )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 执行 ? RequireInternalSlot(S, [[WeakSetData]])。
  3. 如果 CanBeHeldWeakly(value) 为 false,返回 false
  4. S.[[WeakSetData]] 中每个元素 e
    1. 如果 e 不是 emptySameValue(e, value) 为 true,返回 true
  5. 返回 false

24.4.3.5 WeakSet.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "WeakSet"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

24.4.4 WeakSet 实例的属性

WeakSet 实例是普通对象,从 WeakSet 原型对象继承属性。WeakSet 实例还具有 [[WeakSetData]] 内部槽。

24.5 键控集合的抽象操作

24.5.1 CanonicalizeKeyedCollectionKey ( key )

The abstract operation CanonicalizeKeyedCollectionKey takes argument key (an ECMAScript language value) and returns an ECMAScript language value. It performs the following steps when called:

  1. 如果 key-0𝔽,返回 +0𝔽
  2. 返回 key

25 结构化数据(Structured Data)

25.1 ArrayBuffer 对象

25.1.1 记号(Notation)

本小节、25.4 以及 29 中的下述描述使用 “读-改-写 修改函数(read-modify-write modification function)” 内部数据结构。

读-改-写 修改函数 是一种数学函数,以抽象闭包形式表示,接受两个字节值List 作为参数并返回一个字节值List。这些抽象闭包满足以下全部性质:

  • 它们以原子方式执行其全部算法步骤。
  • 其各个算法步骤不可被观察。
Note

为帮助验证读-改-写 修改函数的算法步骤构成一个纯粹的数学函数,建议遵循以下编辑约定:

25.1.2 固定长度与可调整大小(Resizable)的 ArrayBuffer 对象

固定长度 ArrayBuffer(fixed-length ArrayBuffer) 是创建后其字节长度不可改变的 ArrayBuffer。

可调整大小 ArrayBuffer(resizable ArrayBuffer) 是创建后其字节长度可通过调用 ArrayBuffer.prototype.resize ( newLength ) 改变的 ArrayBuffer。

创建何种 ArrayBuffer 对象取决于传递给 ArrayBuffer ( length [ , options ] ) 的参数。

25.1.3 ArrayBuffer 对象的抽象操作

25.1.3.1 AllocateArrayBuffer ( constructor, byteLength [ , maxByteLength ] )

The abstract operation AllocateArrayBuffer takes arguments constructor (a constructor) and byteLength (a non-negative integer) and optional argument maxByteLength (a non-negative integer or empty) and returns 要么是包含一个 ArrayBuffer 的正常完成要么是抛出完成. 用于创建一个 ArrayBuffer。 It performs the following steps when called:

  1. slots 为 « [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferDetachKey]] »。
  2. 如果存在 maxByteLength 且其不为 empty,令 allocatingResizableBuffertrue;否则令其为 false
  3. allocatingResizableBuffertrue,则
    1. byteLength > maxByteLength,抛出 RangeError 异常。
    2. [[ArrayBufferMaxByteLength]] 追加到 slots
  4. obj 为 ? OrdinaryCreateFromConstructor(constructor, "%ArrayBuffer.prototype%", slots)。
  5. block 为 ? CreateByteDataBlock(byteLength)。
  6. obj.[[ArrayBufferData]]block
  7. obj.[[ArrayBufferByteLength]]byteLength
  8. allocatingResizableBuffertrue,则
    1. 若无法创建一个由 maxByteLength 个字节组成的 Data Block block,抛出 RangeError 异常。
    2. 注:可调整大小 ArrayBuffer 设计为可原地增长。实现可在例如无法预先保留虚拟内存时抛出。
    3. obj.[[ArrayBufferMaxByteLength]]maxByteLength
  9. 返回 obj

25.1.3.2 ArrayBufferByteLength ( arrayBuffer, order )

The abstract operation ArrayBufferByteLength takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer) and order (seq-cst or unordered) and returns a non-negative integer. It performs the following steps when called:

  1. IsSharedArrayBuffer(arrayBuffer) 为 truearrayBuffer 具有内部槽 [[ArrayBufferByteLengthData]],则
    1. bufferByteLengthBlockarrayBuffer.[[ArrayBufferByteLengthData]]
    2. rawLengthGetRawBytesFromSharedBlock(bufferByteLengthBlock, 0, biguint64, true, order)。
    3. isLittleEndian 为外层 agent 的 Agent Record[[LittleEndian]] 字段的值。
    4. 返回 (RawBytesToNumeric(biguint64, rawLength, isLittleEndian))。
  2. 断言:IsDetachedBuffer(arrayBuffer) 为 false
  3. 返回 arrayBuffer.[[ArrayBufferByteLength]]

25.1.3.3 ArrayBufferCopyAndDetach ( arrayBuffer, newLength, preserveResizability )

The abstract operation ArrayBufferCopyAndDetach takes arguments arrayBuffer (an ECMAScript language value), newLength (an ECMAScript language value), and preserveResizability (preserve-resizability or fixed-length) and returns 要么是包含一个 ArrayBuffer 的正常完成要么是抛出完成. It performs the following steps when called:

  1. 执行 ? RequireInternalSlot(arrayBuffer, [[ArrayBufferData]])。
  2. IsSharedArrayBuffer(arrayBuffer) 为 true,抛出 TypeError 异常。
  3. newLengthundefined,则
    1. newByteLengtharrayBuffer.[[ArrayBufferByteLength]]
  4. 否则,
    1. newByteLength 为 ? ToIndex(newLength)。
  5. IsDetachedBuffer(arrayBuffer) 为 true,抛出 TypeError 异常。
  6. preserveResizabilitypreserve-resizabilityIsFixedLengthArrayBuffer(arrayBuffer) 为 false,则
    1. newMaxByteLengtharrayBuffer.[[ArrayBufferMaxByteLength]]
  7. 否则,
    1. newMaxByteLengthempty
  8. arrayBuffer.[[ArrayBufferDetachKey]] 不为 undefined,抛出 TypeError 异常。
  9. newBuffer 为 ? AllocateArrayBuffer(%ArrayBuffer%, newByteLength, newMaxByteLength)。
  10. copyLengthmin(newByteLength, arrayBuffer.[[ArrayBufferByteLength]])。
  11. fromBlockarrayBuffer.[[ArrayBufferData]]
  12. toBlocknewBuffer.[[ArrayBufferData]]
  13. 执行 CopyDataBlockBytes(toBlock, 0, fromBlock, 0, copyLength)。
  14. 注:新旧 Data Block 的创建与拷贝均不可观察。实现可用零拷贝移动或 realloc
  15. 执行 ! DetachArrayBuffer(arrayBuffer)。
  16. 返回 newBuffer

25.1.3.4 IsDetachedBuffer ( arrayBuffer )

The abstract operation IsDetachedBuffer takes argument arrayBuffer (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It performs the following steps when called:

  1. arrayBuffer.[[ArrayBufferData]]null,返回 true
  2. 返回 false

25.1.3.5 DetachArrayBuffer ( arrayBuffer [ , key ] )

The abstract operation DetachArrayBuffer takes argument arrayBuffer (an ArrayBuffer) and optional argument key (anything) and returns 要么是包含 unused正常完成要么是抛出完成. It performs the following steps when called:

  1. 断言:IsSharedArrayBuffer(arrayBuffer) 为 false
  2. key 不存在,设 keyundefined
  3. arrayBuffer.[[ArrayBufferDetachKey]] 不为 key,抛出 TypeError 异常。
  4. arrayBuffer.[[ArrayBufferData]]null
  5. arrayBuffer.[[ArrayBufferByteLength]] 为 0。
  6. 返回 unused
Note

分离一个 ArrayBuffer 实例会将其用作后备存储的 Data Block 与该实例解除关联,并将其字节长度设为 0。

25.1.3.6 CloneArrayBuffer ( srcBuffer, srcByteOffset, srcLength )

The abstract operation CloneArrayBuffer takes arguments srcBuffer (an ArrayBuffer or a SharedArrayBuffer), srcByteOffset (a non-negative integer), and srcLength (a non-negative integer) and returns 要么是包含一个 ArrayBuffer 的正常完成要么是抛出完成. 创建一个新的 ArrayBuffer,其数据为 srcBuffersrcByteOffsetsrcLength 字节范围内数据的拷贝。 It performs the following steps when called:

  1. 断言:IsDetachedBuffer(srcBuffer) 为 false
  2. targetBuffer 为 ? AllocateArrayBuffer(%ArrayBuffer%, srcLength)。
  3. srcBlocksrcBuffer.[[ArrayBufferData]]
  4. targetBlocktargetBuffer.[[ArrayBufferData]]
  5. 执行 CopyDataBlockBytes(targetBlock, 0, srcBlock, srcByteOffset, srcLength)。
  6. 返回 targetBuffer

25.1.3.7 GetArrayBufferMaxByteLengthOption ( options )

The abstract operation GetArrayBufferMaxByteLengthOption takes argument options (an ECMAScript language value) and returns 要么是包含非负整数或 empty正常完成要么是抛出完成. It performs the following steps when called:

  1. options 不是 Object,返回 empty
  2. maxByteLength 为 ? Get(options, "maxByteLength")。
  3. maxByteLengthundefined,返回 empty
  4. 返回 ? ToIndex(maxByteLength)。

25.1.3.8 HostResizeArrayBuffer ( buffer, newByteLength )

The host-defined abstract operation HostResizeArrayBuffer takes arguments buffer (an ArrayBuffer) and newByteLength (a non-negative integer) and returns 要么是包含 handledunhandled正常完成要么是抛出完成. 给予宿主机会对 buffer 进行实现自定义的调整大小。若宿主选择不处理,可返回 unhandled 以使用默认行为。

HostResizeArrayBuffer 的实现必须符合以下要求:

  • 抽象操作不会分离 buffer
  • 正常完成并返回 handled,则 buffer.[[ArrayBufferByteLength]]newByteLength

默认实现返回 NormalCompletion(unhandled)。

25.1.3.9 IsFixedLengthArrayBuffer ( arrayBuffer )

The abstract operation IsFixedLengthArrayBuffer takes argument arrayBuffer (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It performs the following steps when called:

  1. arrayBuffer 具有内部槽 [[ArrayBufferMaxByteLength]],返回 false
  2. 返回 true

25.1.3.10 IsUnsignedElementType ( type )

The abstract operation IsUnsignedElementType takes argument type (a TypedArray element type) and returns a Boolean. 验证参数 type 是否为无符号的 TypedArray 元素类型。 It performs the following steps when called:

  1. typeuint8, uint8clamped, uint16, uint32, 或 biguint64 之一,返回 true
  2. 返回 false

25.1.3.11 IsUnclampedIntegerElementType ( type )

The abstract operation IsUnclampedIntegerElementType takes argument type (a TypedArray element type) and returns a Boolean. 验证参数 type 是否为不包含 uint8clamped 的整数 TypedArray 元素类型。 It performs the following steps when called:

  1. typeint8, uint8, int16, uint16, int32, 或 uint32 之一,返回 true
  2. 返回 false

25.1.3.12 IsBigIntElementType ( type )

The abstract operation IsBigIntElementType takes argument type (a TypedArray element type) and returns a Boolean. 验证参数 type 是否为 BigInt TypedArray 元素类型。 It performs the following steps when called:

  1. typebiguint64bigint64,返回 true
  2. 返回 false

25.1.3.13 IsNoTearConfiguration ( type, order )

The abstract operation IsNoTearConfiguration takes arguments type (a TypedArray element type) and order (seq-cst, unordered, or init) and returns a Boolean. It performs the following steps when called:

  1. IsUnclampedIntegerElementType(type) 为 true,返回 true
  2. IsBigIntElementType(type) 为 trueorder 既不是 init 也不是 unordered,返回 true
  3. 返回 false

25.1.3.14 RawBytesToNumeric ( type, rawBytes, isLittleEndian )

The abstract operation RawBytesToNumeric takes arguments type (a TypedArray element type), rawBytes (a List of byte values), and isLittleEndian (a Boolean) and returns a Number or a BigInt. It performs the following steps when called:

  1. elementSizeTable 73 中元素类型 type 指定的元素大小值。
  2. isLittleEndianfalse,反转 rawBytes 的元素顺序。
  3. typefloat16,则
    1. value 为将 rawBytes 字节元素拼接并按 IEEE 754-2019 binary16 小端位串编码解释的结果。
    2. value 是 NaN,返回 NaN
    3. 返回与 value 对应的 Number 值。
  4. typefloat32,则
    1. 同上以 binary32 方式处理。
  5. typefloat64,则
    1. 同上以 binary64 方式处理。
  6. IsUnsignedElementType(type) 为 true,则
    1. intValuerawBytes 按小端无符号二进制数的位串编码解释的结果。
  7. 否则,
    1. intValuerawBytes 按小端二补数、位长 elementSize × 8 的位串编码解释的结果。
  8. IsBigIntElementType(type) 为 true,返回与 intValue 对应的 BigInt。
  9. 否则,返回与 intValue 对应的 Number。

25.1.3.15 GetRawBytesFromSharedBlock ( block, byteIndex, type, isTypedArray, order )

The abstract operation GetRawBytesFromSharedBlock takes arguments block (a Shared Data Block), byteIndex (a non-negative integer), type (a TypedArray element type), isTypedArray (a Boolean), and order (seq-cst or unordered) and returns a List of byte values. It performs the following steps when called:

  1. elementSizeTable 73 中元素类型 type 指定的元素大小值。
  2. execution 为外层 agent 的 Agent Record[[CandidateExecution]] 字段。
  3. eventsRecordexecution.[[EventsRecords]][[AgentSignifier]]AgentSignifier() 的 Agent Events Record
  4. isTypedArraytrueIsNoTearConfiguration(type, order) 为 true,令 noTeartrue;否则为 false
  5. rawValue 为长度 elementSize、元素为非确定性选择字节值List
  6. 注:在实现中,rawValue 是底层硬件非原子或原子读取指令的结果;该非确定性是内存模型对弱一致硬件可观察行为的语义规定。
  7. readEventReadSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize }。
  8. readEvent 追加到 eventsRecord.[[EventList]]
  9. Chosen Value Record { [[Event]]: readEvent, [[ChosenValue]]: rawValue } 追加到 execution.[[ChosenValues]]
  10. 返回 rawValue

25.1.3.16 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isTypedArray, order [ , isLittleEndian ] )

The abstract operation GetValueFromBuffer takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer), byteIndex (a non-negative integer), type (a TypedArray element type), isTypedArray (a Boolean), and order (seq-cst or unordered) and optional argument isLittleEndian (a Boolean) and returns a Number or a BigInt. It performs the following steps when called:

  1. 断言:IsDetachedBuffer(arrayBuffer) 为 false
  2. 断言:arrayBuffer 中自 byteIndex 起有足够字节表示 type 的一个值。
  3. blockarrayBuffer.[[ArrayBufferData]]
  4. elementSizeTable 73 中元素类型 type 的元素大小值。
  5. IsSharedArrayBuffer(arrayBuffer) 为 true,则
    1. 断言:blockShared Data Block
    2. rawValueGetRawBytesFromSharedBlock(block, byteIndex, type, isTypedArray, order)。
  6. 否则,
    1. rawValueblock 中索引区间 [byteIndex, byteIndex + elementSize) 的字节组成的 List
  7. 断言:rawValue 元素个数为 elementSize
  8. isLittleEndian 不存在,设其为外层 agent 的 Agent Record[[LittleEndian]] 字段值。
  9. 返回 RawBytesToNumeric(type, rawValue, isLittleEndian)。

25.1.3.17 NumericToRawBytes ( type, value, isLittleEndian )

The abstract operation NumericToRawBytes takes arguments type (a TypedArray element type), value (a Number or a BigInt), and isLittleEndian (a Boolean) and returns a List of byte values. It performs the following steps when called:

  1. typefloat16,则
    1. rawBytes 为长度 2 的 List,为将 value 以 roundTiesToEven 模式转换为 IEEE 754-2019 binary16 格式的结果字节(小端序)。若 valueNaNrawBytes 可为实现选择的任一 binary16 NaN 编码;实现对每个可区分 NaN 必须始终选择同一编码。
  2. Else if typefloat32,同理生成 4 字节(binary32)。
  3. Else if typefloat64,同理生成 8 字节(binary64)。
  4. 否则,
    1. nTable 73 中元素类型 type 的元素大小值。
    2. conversionOperation 为同表中该元素类型的 Conversion Operation 列命名的抽象操作
    3. intValue(! conversionOperation(value))。
    4. intValue ≥ 0,则
      1. rawBytes 为按小端序排列的 intValuen 字节二进制编码。
    5. 否则,
      1. rawBytes 为按小端序排列的 intValuen 字节二进制二补数编码。
  5. isLittleEndianfalse,反转 rawBytes 的元素顺序。
  6. 返回 rawBytes

25.1.3.18 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isTypedArray, order [ , isLittleEndian ] )

The abstract operation SetValueInBuffer takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer), byteIndex (a non-negative integer), type (a TypedArray element type), value (a Number or a BigInt), isTypedArray (a Boolean), and order (seq-cst, unordered, or init) and optional argument isLittleEndian (a Boolean) and returns unused. It performs the following steps when called:

  1. 断言:IsDetachedBuffer(arrayBuffer) 为 false
  2. 断言:arrayBuffer 中自 byteIndex 起有足够字节表示 type 的一个值。
  3. 断言:若 IsBigIntElementType(type) 为 truevalue 为 BigInt;否则为 Number。
  4. blockarrayBuffer.[[ArrayBufferData]]
  5. elementSizeTable 73 中元素类型 type 的元素大小值。
  6. isLittleEndian 不存在,设其为外层 agent 的 Agent Record[[LittleEndian]] 字段值。
  7. rawBytesNumericToRawBytes(type, value, isLittleEndian)。
  8. IsSharedArrayBuffer(arrayBuffer) 为 true,则
    1. execution 为外层 agent 的 Agent Record[[CandidateExecution]] 字段。
    2. eventsRecordexecution.[[EventsRecords]][[AgentSignifier]]AgentSignifier() 的 Agent Events Record
    3. isTypedArraytrueIsNoTearConfiguration(type, order) 为 true,令 noTeartrue;否则为 false
    4. WriteSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes } 追加到 eventsRecord.[[EventList]]
  9. 否则,
    1. rawBytes 的各字节存入 block,起始于 block[byteIndex]。
  10. 返回 unused

25.1.3.19 GetModifySetValueInBuffer ( arrayBuffer, byteIndex, type, value, op )

The abstract operation GetModifySetValueInBuffer takes arguments arrayBuffer (an ArrayBuffer or a SharedArrayBuffer), byteIndex (a non-negative integer), type (a TypedArray element type), value (a Number or a BigInt), and op (a read-modify-write modification function) and returns a Number or a BigInt. It performs the following steps when called:

  1. 断言:IsDetachedBuffer(arrayBuffer) 为 false
  2. 断言:arrayBuffer 中自 byteIndex 起有足够字节表示 type 的一个值。
  3. 断言:若 IsBigIntElementType(type) 为 truevalue 为 BigInt;否则为 Number。
  4. blockarrayBuffer.[[ArrayBufferData]]
  5. elementSizeTable 73 中元素类型 type 的元素大小值。
  6. isLittleEndian 为外层 agent 的 Agent Record[[LittleEndian]] 字段值。
  7. rawBytesNumericToRawBytes(type, value, isLittleEndian)。
  8. IsSharedArrayBuffer(arrayBuffer) 为 true,则
    1. execution 为外层 agent 的 Agent Record[[CandidateExecution]] 字段。
    2. eventsRecordexecution.[[EventsRecords]][[AgentSignifier]]AgentSignifier() 的 Agent Events Record
    3. rawBytesRead 为长度 elementSize、元素为非确定性选择字节值List
    4. 注:在实现中,rawBytesRead 来自底层硬件的 load-link、load-exclusive 或读-改-写指令操作数;非确定性用于描述弱一致硬件的可观察行为。
    5. rmwEventReadModifyWriteSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes, [[ModifyOp]]: op }。
    6. rmwEvent 追加到 eventsRecord.[[EventList]]
    7. Chosen Value Record { [[Event]]: rmwEvent, [[ChosenValue]]: rawBytesRead } 追加到 execution.[[ChosenValues]]
  9. 否则,
    1. rawBytesRead 为长度 elementSizeList,其元素为自 block[byteIndex] 起的 elementSize 个字节。
    2. rawBytesModifiedop(rawBytesRead, rawBytes)。
    3. rawBytesModified 的字节存入 block,起始于 block[byteIndex]。
  10. 返回 RawBytesToNumeric(type, rawBytesRead, isLittleEndian)。

25.1.4 ArrayBuffer 构造函数

ArrayBuffer 构造函数

  • %ArrayBuffer%
  • 是全局对象 "ArrayBuffer" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 ArrayBuffer。
  • 不应作为函数调用;若如此调用将抛出异常。
  • 可作为类定义 extends 子句的值。继承该指定行为的子类构造函数必须在内部包含对 ArrayBuffer 构造函数super 调用,以创建并初始化具有支持 ArrayBuffer.prototype 内置方法所需内部状态的子类实例。

25.1.4.1 ArrayBuffer ( length [ , options ] )

该函数被调用时执行以下步骤:

  1. 若 NewTarget 为 undefined,抛出 TypeError 异常。
  2. byteLength 为 ? ToIndex(length)。
  3. requestedMaxByteLength 为 ? GetArrayBufferMaxByteLengthOption(options)。
  4. 返回 ? AllocateArrayBuffer(NewTarget, byteLength, requestedMaxByteLength)。

25.1.5 ArrayBuffer 构造函数的属性

ArrayBuffer 构造函数

25.1.5.1 ArrayBuffer.isView ( arg )

该函数被调用时执行以下步骤:

  1. arg 不是 Object,返回 false
  2. arg 具有内部槽 [[ViewedArrayBuffer]],返回 true
  3. 返回 false

25.1.5.2 ArrayBuffer.prototype

ArrayBuffer.prototype 的初始值是 ArrayBuffer 原型对象

该属性的特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

25.1.5.3 get ArrayBuffer [ %Symbol.species% ]

ArrayBuffer[%Symbol.species%] 是一个存取器属性,其 set 访问器为 undefined。其 get 访问器被调用时执行:

  1. 返回 this 值。

该函数 "name" 属性的值为 "get [Symbol.species]"

Note

ArrayBuffer.prototype.slice ( start, end ) 通常使用其 this 值的构造函数创建派生对象。然而,子类构造函数可通过重定义其 %Symbol.species% 属性来覆盖该方法(ArrayBuffer.prototype.slice ( start, end ))的默认行为。

25.1.6 ArrayBuffer 原型对象的属性

ArrayBuffer 原型对象

  • %ArrayBuffer.prototype%
  • [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 普通对象
  • 没有 [[ArrayBufferData]][[ArrayBufferByteLength]] 内部槽。

25.1.6.1 get ArrayBuffer.prototype.byteLength

ArrayBuffer.prototype.byteLength 是一个存取器属性,其 set 访问器为 undefined。其 get 访问器被调用时执行:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) 为 true,抛出 TypeError 异常。
  4. IsDetachedBuffer(O) 为 true,返回 +0𝔽
  5. lengthO.[[ArrayBufferByteLength]]
  6. 返回 𝔽(length)。

25.1.6.2 ArrayBuffer.prototype.constructor

ArrayBuffer.prototype.constructor 的初始值是 %ArrayBuffer%

25.1.6.3 get ArrayBuffer.prototype.detached

ArrayBuffer.prototype.detached 是一个存取器属性,其 set 访问器为 undefined。其 get 访问器被调用时执行:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) 为 true,抛出 TypeError 异常。
  4. 返回 IsDetachedBuffer(O)。

25.1.6.4 get ArrayBuffer.prototype.maxByteLength

ArrayBuffer.prototype.maxByteLength 是一个存取器属性,其 set 访问器为 undefined。其 get 访问器被调用时执行:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) 为 true,抛出 TypeError 异常。
  4. IsDetachedBuffer(O) 为 true,返回 +0𝔽
  5. IsFixedLengthArrayBuffer(O) 为 true,则
    1. lengthO.[[ArrayBufferByteLength]]
  6. 否则,
    1. lengthO.[[ArrayBufferMaxByteLength]]
  7. 返回 𝔽(length)。

25.1.6.5 get ArrayBuffer.prototype.resizable

ArrayBuffer.prototype.resizable 是一个存取器属性,其 set 访问器为 undefined。其 get 访问器被调用时执行:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) 为 true,抛出 TypeError 异常。
  4. IsFixedLengthArrayBuffer(O) 为 false,返回 true;否则返回 false

25.1.6.6 ArrayBuffer.prototype.resize ( newLength )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[ArrayBufferMaxByteLength]])。
  3. IsSharedArrayBuffer(O) 为 true,抛出 TypeError 异常。
  4. newByteLength 为 ? ToIndex(newLength)。
  5. IsDetachedBuffer(O) 为 true,抛出 TypeError 异常。
  6. newByteLength > O.[[ArrayBufferMaxByteLength]],抛出 RangeError 异常。
  7. hostHandled 为 ? HostResizeArrayBuffer(O, newByteLength)。
  8. hostHandledhandled,返回 undefined
  9. oldBlockO.[[ArrayBufferData]]
  10. newBlock 为 ? CreateByteDataBlock(newByteLength)。
  11. copyLengthmin(newByteLength, O.[[ArrayBufferByteLength]])。
  12. 执行 CopyDataBlockBytes(newBlock, 0, oldBlock, 0, copyLength)。
  13. 注:新 Data Block 的创建与旧 Data Block 的拷贝均不可观察。实现可原地增长或收缩。
  14. O.[[ArrayBufferData]]newBlock
  15. O.[[ArrayBufferByteLength]]newByteLength
  16. 返回 undefined

25.1.6.7 ArrayBuffer.prototype.slice ( start, end )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) 为 true,抛出 TypeError 异常。
  4. IsDetachedBuffer(O) 为 true,抛出 TypeError 异常。
  5. lenO.[[ArrayBufferByteLength]]
  6. relativeStart 为 ? ToIntegerOrInfinity(start)。
  7. relativeStart = -∞,令 first 为 0。
  8. Else if relativeStart < 0,令 firstmax(len + relativeStart, 0)。
  9. Else,令 firstmin(relativeStart, len)。
  10. endundefined,令 relativeEndlen;否则令 relativeEnd 为 ? ToIntegerOrInfinity(end)。
  11. relativeEnd = -∞,令 final 为 0。
  12. Else if relativeEnd < 0,令 finalmax(len + relativeEnd, 0)。
  13. Else,令 finalmin(relativeEnd, len)。
  14. newLenmax(final - first, 0)。
  15. ctor 为 ? SpeciesConstructor(O, %ArrayBuffer%)。
  16. new 为 ? Construct(ctor, « 𝔽(newLen) »)。
  17. 执行 ? RequireInternalSlot(new, [[ArrayBufferData]])。
  18. IsSharedArrayBuffer(new) 为 true,抛出 TypeError 异常。
  19. IsDetachedBuffer(new) 为 true,抛出 TypeError 异常。
  20. SameValue(new, O) 为 true,抛出 TypeError 异常。
  21. new.[[ArrayBufferByteLength]] < newLen,抛出 TypeError 异常。
  22. 注:以上步骤的副作用可能已分离或调整 O 大小。
  23. IsDetachedBuffer(O) 为 true,抛出 TypeError 异常。
  24. fromBufO.[[ArrayBufferData]]
  25. toBufnew.[[ArrayBufferData]]
  26. currentLenO.[[ArrayBufferByteLength]]
  27. first < currentLen,则
    1. countmin(newLen, currentLen - first)。
    2. 执行 CopyDataBlockBytes(toBuf, 0, fromBuf, first, count)。
  28. 返回 new

25.1.6.8 ArrayBuffer.prototype.transfer ( [ newLength ] )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 返回 ? ArrayBufferCopyAndDetach(O, newLength, preserve-resizability)。

25.1.6.9 ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 返回 ? ArrayBufferCopyAndDetach(O, newLength, fixed-length)。

25.1.6.10 ArrayBuffer.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "ArrayBuffer"

该属性特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

25.1.7 ArrayBuffer 实例的属性

ArrayBuffer 实例从 ArrayBuffer 原型对象继承属性。每个实例都有 [[ArrayBufferData]][[ArrayBufferByteLength]][[ArrayBufferDetachKey]] 内部槽。可调整大小的实例还具有 [[ArrayBufferMaxByteLength]] 内部槽。

[[ArrayBufferData]]null 的 ArrayBuffer 实例被视为已分离,对其数据的访问或修改操作均会失败。

[[ArrayBufferDetachKey]] 设为非 undefined 值的 ArrayBuffer 实例,在所有 DetachArrayBuffer 调用中必须传递相同的 “detach key” 作为参数,否则将产生 TypeError。该内部槽仅由某些嵌入环境设置,而非本规范算法。

25.1.8 可调整大小 ArrayBuffer 指南

Note 1

以下是供 ECMAScript 程序员在使用可调整大小 ArrayBuffer 时的指南。

建议在部署环境中(如果可能)对程序进行测试。不同硬件设备的可用物理内存差异很大;虚拟内存子系统也因硬件设备与操作系统不同而差异明显。一个在 64 位桌面浏览器中无内存不足错误的应用,可能在 32 位移动浏览器中耗尽内存。

为可调整大小 ArrayBuffer 选择 "maxByteLength" 选项值时,建议选择应用所需的最小可能值。建议 "maxByteLength" 不超过 1,073,741,824(230 字节或 1GiB)。

请注意:成功构造一个指定最大值的可调整大小 ArrayBuffer 并不保证未来的扩展一定成功。

Note 2

以下是供实现可调整大小 ArrayBuffer 的 ECMAScript 实现者的指南。

Resizable ArrayBuffer 可实现为在调整时复制、通过预留虚拟内存的原地增长、或针对构造函数 "maxByteLength" 选项不同取值的上述方案组合。

宿主是多租户(同时运行许多 ECMAScript 应用),例如 Web 浏览器,并选择通过预留虚拟内存实现原地增长,建议 32 位与 64 位实现对 "maxByteLength" ≥ 1GiB 到 1.5GiB 的值抛出异常。其目的是减少单一应用耗尽虚拟地址空间的可能性并降低互操作风险。

宿主无虚拟内存(例如无 MMU 的嵌入式设备),或宿主仅通过复制实现调整大小,则可接受 "maxByteLength" 选项的任意 Number value for 值。然而,建议当请求的大小永远无法分配时抛出 RangeError。例如请求大小大于设备可用的最大可用内存时。

25.2 SharedArrayBuffer 对象

25.2.1 固定长度与可增长的 SharedArrayBuffer 对象

固定长度 SharedArrayBuffer 是创建后其字节长度不可改变的 SharedArrayBuffer。

可增长 SharedArrayBuffer 是创建后其字节长度可通过调用 SharedArrayBuffer.prototype.grow ( newLength ) 增加的 SharedArrayBuffer。

创建哪种 SharedArrayBuffer 对象取决于传递给 SharedArrayBuffer ( length [ , options ] ) 的参数。

25.2.2 SharedArrayBuffer 对象的抽象操作

25.2.2.1 AllocateSharedArrayBuffer ( constructor, byteLength [ , maxByteLength ] )

The abstract operation AllocateSharedArrayBuffer takes arguments constructor (a constructor) and byteLength (a non-negative integer) and optional argument maxByteLength (a non-negative integer or empty) and returns 要么是包含一个 SharedArrayBuffer 的正常完成要么是抛出完成. 用于创建一个 SharedArrayBuffer。 It performs the following steps when called:

  1. slots 为 « [[ArrayBufferData]] »。
  2. 若存在 maxByteLength 且其不为 empty,令 allocatingGrowableBuffertrue;否则令其为 false
  3. allocatingGrowableBuffertrue,则
    1. byteLength > maxByteLength,抛出 RangeError 异常。
    2. [[ArrayBufferByteLengthData]][[ArrayBufferMaxByteLength]] 追加到 slots
  4. 否则,
    1. [[ArrayBufferByteLength]] 追加到 slots
  5. obj 为 ? OrdinaryCreateFromConstructor(constructor, "%SharedArrayBuffer.prototype%", slots)。
  6. allocatingGrowableBuffertrue,令 allocLengthmaxByteLength;否则令 allocLengthbyteLength
  7. block 为 ? CreateSharedByteDataBlock(allocLength)。
  8. obj.[[ArrayBufferData]]block
  9. allocatingGrowableBuffertrue,则
    1. 断言:byteLengthmaxByteLength
    2. byteLengthBlock 为 ? CreateSharedByteDataBlock(8)。
    3. 执行 SetValueInBuffer(byteLengthBlock, 0, biguint64, (byteLength), true, seq-cst)。
    4. obj.[[ArrayBufferByteLengthData]]byteLengthBlock
    5. obj.[[ArrayBufferMaxByteLength]]maxByteLength
  10. 否则,
    1. obj.[[ArrayBufferByteLength]]byteLength
  11. 返回 obj

25.2.2.2 IsSharedArrayBuffer ( obj )

The abstract operation IsSharedArrayBuffer takes argument obj (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. 测试一个对象是否是 ArrayBuffer、SharedArrayBuffer,或它们的子类型。 It performs the following steps when called:

  1. bufferDataobj.[[ArrayBufferData]]
  2. bufferDatanull,返回 false
  3. bufferDataData Block,返回 false
  4. 断言:bufferDataShared Data Block
  5. 返回 true

25.2.2.3 HostGrowSharedArrayBuffer ( buffer, newByteLength )

The host-defined abstract operation HostGrowSharedArrayBuffer takes arguments buffer (a SharedArrayBuffer) and newByteLength (a non-negative integer) and returns 要么是包含 handledunhandled正常完成要么是抛出完成. 给予宿主机会对 buffer 进行实现自定义的增长。若宿主选择不处理增长,可返回 unhandled 以使用默认行为。

HostGrowSharedArrayBuffer 的实现必须符合以下要求:

  • 若该抽象操作未以 unhandled 正常完成,且 newByteLength < 当前 buffer 的字节长度,或 newByteLength > buffer.[[ArrayBufferMaxByteLength]],抛出 RangeError 异常。
  • isLittleEndian 为外层 agent 的 Agent Record[[LittleEndian]] 字段的值。若该抽象操作handled 正常完成,则一个 WriteSharedMemoryReadModifyWriteSharedMemory 事件被加入外层 agent 的候选执行,其 [[Order]]seq-cst[[Payload]]NumericToRawBytes(biguint64, newByteLength, isLittleEndian),[[Block]]buffer.[[ArrayBufferByteLengthData]][[ByteIndex]] 为 0,[[ElementSize]] 为 8,从而并发竞争的 SharedArrayBuffer.prototype.grow 调用不会“丢失”(即静默不做任何事)。
Note

上面第二个要求有意未明确说明如何或何时读取 buffer 的当前字节长度。由于字节长度必须通过底层硬件的原子读-改-写操作更新,使用 load-link/store-conditional 或 load-exclusive/store-exclusive 指令对的体系结构可能希望将该指令对在指令流中保持紧邻。因此,SharedArrayBuffer.prototype.grow 自身不会在调用 HostGrowSharedArrayBuffer 前对 newByteLength 做边界检查,也不要求何时读取当前字节长度。

这与 HostResizeArrayBuffer 形成对比,后者被保证 newByteLength 值 ≥ 0 且 ≤ buffer.[[ArrayBufferMaxByteLength]]

HostGrowSharedArrayBuffer 的默认实现是返回 NormalCompletion(unhandled)。

25.2.3 SharedArrayBuffer 构造函数

SharedArrayBuffer 构造函数

  • %SharedArrayBuffer%
  • 若全局对象存在该属性,则为其 "SharedArrayBuffer" 属性的初始值(见下文)。
  • 作为构造函数调用时创建并初始化一个新的 SharedArrayBuffer。
  • 不应作为函数调用;若如此调用将抛出异常。
  • 可作为类定义 extends 子句的值。欲继承指定 SharedArrayBuffer 行为的子类构造函数必须包含对 SharedArrayBuffer 构造函数super 调用,以创建并初始化具有支持 SharedArrayBuffer.prototype 内置方法所需内部状态的子类实例。

宿主不提供对 SharedArrayBuffers 的并发访问时,可以省略全局对象的 "SharedArrayBuffer" 属性。

Note

不同于 ArrayBufferSharedArrayBuffer 不会被分离,其内部 [[ArrayBufferData]] 槽永不为 null

25.2.3.1 SharedArrayBuffer ( length [ , options ] )

该函数被调用时执行以下步骤:

  1. 若 NewTarget 为 undefined,抛出 TypeError 异常。
  2. byteLength 为 ? ToIndex(length)。
  3. requestedMaxByteLength 为 ? GetArrayBufferMaxByteLengthOption(options)。
  4. 返回 ? AllocateSharedArrayBuffer(NewTarget, byteLength, requestedMaxByteLength)。

25.2.4 SharedArrayBuffer 构造函数的属性

SharedArrayBuffer 构造函数

25.2.4.1 SharedArrayBuffer.prototype

SharedArrayBuffer.prototype 的初始值是 SharedArrayBuffer 原型对象

该属性特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

25.2.4.2 get SharedArrayBuffer [ %Symbol.species% ]

SharedArrayBuffer[%Symbol.species%] 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. 返回 this 值。

该函数 "name" 属性的值为 "get [Symbol.species]"

25.2.5 SharedArrayBuffer 原型对象的属性

SharedArrayBuffer 原型对象

  • %SharedArrayBuffer.prototype%
  • 具有 [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 是一个普通对象
  • 没有 [[ArrayBufferData]][[ArrayBufferByteLength]] 内部槽。

25.2.5.1 get SharedArrayBuffer.prototype.byteLength

SharedArrayBuffer.prototype.byteLength 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) 为 false,抛出 TypeError 异常。
  4. lengthArrayBufferByteLength(O, seq-cst)。
  5. 返回 𝔽(length)。

25.2.5.2 SharedArrayBuffer.prototype.constructor

SharedArrayBuffer.prototype.constructor 的初始值是 %SharedArrayBuffer%

25.2.5.3 SharedArrayBuffer.prototype.grow ( newLength )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[ArrayBufferMaxByteLength]])。
  3. IsSharedArrayBuffer(O) 为 false,抛出 TypeError 异常。
  4. newByteLength 为 ? ToIndex(newLength)。
  5. hostHandled 为 ? HostGrowSharedArrayBuffer(O, newByteLength)。
  6. hostHandledhandled,返回 undefined
  7. isLittleEndian 为外层 agent 的 Agent Record[[LittleEndian]] 字段的值。
  8. byteLengthBlockO.[[ArrayBufferByteLengthData]]
  9. currentByteLengthRawBytesGetRawBytesFromSharedBlock(byteLengthBlock, 0, biguint64, true, seq-cst)。
  10. newByteLengthRawBytesNumericToRawBytes(biguint64, (newByteLength), isLittleEndian)。
  11. 重复,
    1. 注:这是一个比较并交换循环,确保对同一缓冲区的并行竞争增长是全序的,不会丢失,也不会静默不执行。循环在能够无竞争地尝试增长时退出。
    2. currentByteLength(RawBytesToNumeric(biguint64, currentByteLengthRawBytes, isLittleEndian))。
    3. newByteLength = currentByteLength,返回 undefined
    4. newByteLength < currentByteLengthnewByteLength > O.[[ArrayBufferMaxByteLength]],抛出 RangeError 异常。
    5. byteLengthDeltanewByteLength - currentByteLength
    6. 若无法创建由 byteLengthDelta 个字节组成的新 Shared Data Block 值,抛出 RangeError 异常。
    7. 注:此处未构造并使用新的 Shared Data Block。对可增长 SharedArrayBuffer 的可观察行为通过在构造时分配最大尺寸 Shared Data Block 指定,此步体现实现若内存不足必须抛出 RangeError 的要求。
    8. readByteLengthRawBytesAtomicCompareExchangeInSharedBlock(byteLengthBlock, 0, 8, currentByteLengthRawBytes, newByteLengthRawBytes)。
    9. ByteListEqual(readByteLengthRawBytes, currentByteLengthRawBytes) 为 true,返回 undefined
    10. currentByteLengthRawBytesreadByteLengthRawBytes
Note

禁止比较交换更新长度的虚假失败。若新长度的边界检查通过且实现未耗尽内存,则总会向候选执行添加一个 ReadModifyWriteSharedMemory 事件(即成功的比较交换)。

对 SharedArrayBuffer.prototype.grow 的并行调用是全序的。例如并发的 sab.grow(10)sab.grow(20),二者之一必定赢得竞争。sab.grow(10) 不会在 sab.grow(20) 先发生时收缩 sab;在那种情况下它将抛出 RangeError。

25.2.5.4 get SharedArrayBuffer.prototype.growable

SharedArrayBuffer.prototype.growable 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) 为 false,抛出 TypeError 异常。
  4. IsFixedLengthArrayBuffer(O) 为 false,返回 true;否则返回 false

25.2.5.5 get SharedArrayBuffer.prototype.maxByteLength

SharedArrayBuffer.prototype.maxByteLength 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) 为 false,抛出 TypeError 异常。
  4. IsFixedLengthArrayBuffer(O) 为 true,则
    1. lengthO.[[ArrayBufferByteLength]]
  5. 否则,
    1. lengthO.[[ArrayBufferMaxByteLength]]
  6. 返回 𝔽(length)。

25.2.5.6 SharedArrayBuffer.prototype.slice ( start, end )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) 为 false,抛出 TypeError 异常。
  4. lenArrayBufferByteLength(O, seq-cst)。
  5. relativeStart 为 ? ToIntegerOrInfinity(start)。
  6. relativeStart = -∞,令 first 为 0。
  7. Else if relativeStart < 0,令 firstmax(len + relativeStart, 0)。
  8. Else,令 firstmin(relativeStart, len)。
  9. endundefined,令 relativeEndlen;否则令 relativeEnd 为 ? ToIntegerOrInfinity(end)。
  10. relativeEnd = -∞,令 final 为 0。
  11. Else if relativeEnd < 0,令 finalmax(len + relativeEnd, 0)。
  12. Else,令 finalmin(relativeEnd, len)。
  13. newLenmax(final - first, 0)。
  14. ctor 为 ? SpeciesConstructor(O, %SharedArrayBuffer%)。
  15. new 为 ? Construct(ctor, « 𝔽(newLen) »)。
  16. 执行 ? RequireInternalSlot(new, [[ArrayBufferData]])。
  17. IsSharedArrayBuffer(new) 为 false,抛出 TypeError 异常。
  18. new.[[ArrayBufferData]]O.[[ArrayBufferData]],抛出 TypeError 异常。
  19. ArrayBufferByteLength(new, seq-cst) < newLen,抛出 TypeError 异常。
  20. fromBufO.[[ArrayBufferData]]
  21. toBufnew.[[ArrayBufferData]]
  22. 执行 CopyDataBlockBytes(toBuf, 0, fromBuf, first, newLen)。
  23. 返回 new

25.2.5.7 SharedArrayBuffer.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "SharedArrayBuffer"

该属性特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

25.2.6 SharedArrayBuffer 实例的属性

SharedArrayBuffer 实例从 SharedArrayBuffer 原型对象继承属性。每个 SharedArrayBuffer 实例都有一个 [[ArrayBufferData]] 内部槽。不可增长的 SharedArrayBuffer 实例各自具有一个 [[ArrayBufferByteLength]] 内部槽。可增长的 SharedArrayBuffer 实例各自具有一个 [[ArrayBufferByteLengthData]] 内部槽和一个 [[ArrayBufferMaxByteLength]] 内部槽。

Note

SharedArrayBuffer 实例与 ArrayBuffer 实例不同,永远不会被分离。

25.2.7 可增长 SharedArrayBuffer 指南

Note 1

以下是供使用可增长 SharedArrayBuffer 的 ECMAScript 程序员的指南。

建议在部署环境中(若可行)对程序进行测试。不同硬件设备的可用物理内存差异巨大;虚拟内存子系统同样因硬件与操作系统不同而显著差异。一个在 64 位桌面浏览器中无内存耗尽错误的应用,可能在 32 位移动浏览器中耗尽内存。

可增长 SharedArrayBuffer 选择 "maxByteLength" 选项时,建议选择应用所需的最小可能值。建议 "maxByteLength" 不超过 1073741824(即 1GiB)。

请注意:成功构造一个指定最大值的可增长 SharedArrayBuffer 并不保证后续的增长操作一定成功。

可增长 SharedArrayBuffer 的长度的所有读取并非都是同步的 seq-cst 读取。用于整数索引属性访问(如 u8[idx])的边界检查中的长度读取不是同步的。一般而言,在缺乏显式同步的情况下,一个属性访问在边界内并不意味着同一 agent 中后续的另一个属性访问也在边界内。相比之下,通过 SharedArrayBuffer、%TypedArray%.prototype 和 DataView.prototype 上的 lengthbyteLength getter 对长度的显式读取是同步的。内置方法为检查 TypedArray 是否完全越界而执行的长度读取也是同步的。

Note 2

以下是实现可增长 SharedArrayBuffer 的 ECMAScript 实现者的指南。

建议将可增长 SharedArrayBuffer 实现为通过预留虚拟内存的原地增长。

由于增长操作可与对可增长 SharedArrayBuffer 的内存访问并行发生,内存模型的约束要求即便是无序访问也不得“撕裂”(其值的比特不会混杂)。实际上,这意味着可增长 SharedArrayBuffer 的底层数据块不能在不停顿世界的情况下通过复制来增长。我们不建议以停顿世界作为实现策略,因为它引入串行化点且速度慢。

被增长的内存在创建时必须表现为已归零,包括对任何并行的竞争访问。这可通过按需零填充的虚拟内存页实现,或在手动清零内存时使用谨慎的同步。

针对可增长 SharedArrayBufferTypedArray 视图的整数索引属性访问,旨在可与针对不可增长 SharedArrayBufferTypedArray 视图访问类似地优化,因为整数索引属性读取在底层缓冲区长度上不是同步操作(见上面的程序员指南)。例如,属性访问的边界检查仍可被提升出循环。

在没有虚拟内存的宿主(例如无 MMU 的嵌入式设备)上通过复制实现可增长 SharedArrayBuffer 在实践中很困难。此类宿主可增长 SharedArrayBuffer 的内存使用行为可能与具备虚拟内存的宿主显著不同。这些宿主应清晰地向用户传达内存使用期望。

25.3 DataView 对象

25.3.1 DataView 对象的抽象操作

25.3.1.1 具有缓冲区见证记录的 DataView

具有缓冲区见证记录的 DataView 是一个 Record 值,用于封装一个 DataView 以及已查看缓冲区的缓存字节长度。当被查看缓冲区是可增长 SharedArrayBuffers 时,它用于帮助确保对字节长度数据块只有一次共享内存读取事件。

具有缓冲区见证记录的 DataView 拥有 Table 75 中列出的字段。

Table 75: 具有缓冲区见证记录的 DataView 字段
字段名 含义
[[Object]] a DataView 其缓冲区字节长度被加载的 DataView 对象。
[[CachedBufferByteLength]] a non-negative integer or detached Record 创建时对象的 [[ViewedArrayBuffer]] 的字节长度。

25.3.1.2 MakeDataViewWithBufferWitnessRecord ( obj, order )

The abstract operation MakeDataViewWithBufferWitnessRecord takes arguments obj (a DataView) and order (seq-cst or unordered) and returns a DataView With Buffer Witness Record. It performs the following steps when called:

  1. bufferobj.[[ViewedArrayBuffer]]
  2. IsDetachedBuffer(buffer) 为 true,则
    1. byteLengthdetached
  3. 否则,
    1. byteLengthArrayBufferByteLength(buffer, order)。
  4. 返回 DataView With Buffer Witness Record { [[Object]]: obj, [[CachedBufferByteLength]]: byteLength }。

25.3.1.3 GetViewByteLength ( viewRecord )

The abstract operation GetViewByteLength takes argument viewRecord (a DataView With Buffer Witness Record) and returns a non-negative integer. It performs the following steps when called:

  1. 断言:IsViewOutOfBounds(viewRecord) 为 false
  2. viewviewRecord.[[Object]]
  3. view.[[ByteLength]] 不为 auto,返回 view.[[ByteLength]]
  4. 断言:IsFixedLengthArrayBuffer(view.[[ViewedArrayBuffer]]) 为 false
  5. byteOffsetview.[[ByteOffset]]
  6. byteLengthviewRecord.[[CachedBufferByteLength]]
  7. 断言:byteLength 不为 detached
  8. 返回 byteLength - byteOffset

25.3.1.4 IsViewOutOfBounds ( viewRecord )

The abstract operation IsViewOutOfBounds takes argument viewRecord (a DataView With Buffer Witness Record) and returns a Boolean. It performs the following steps when called:

  1. viewviewRecord.[[Object]]
  2. bufferByteLengthviewRecord.[[CachedBufferByteLength]]
  3. 断言:IsDetachedBuffer(view.[[ViewedArrayBuffer]]) 为 true 当且仅当 bufferByteLengthdetached
  4. bufferByteLengthdetached,返回 true
  5. byteOffsetStartview.[[ByteOffset]]
  6. view.[[ByteLength]]auto,则
    1. byteOffsetEndbufferByteLength
  7. 否则,
    1. byteOffsetEndbyteOffsetStart + view.[[ByteLength]]
  8. byteOffsetStart > bufferByteLengthbyteOffsetEnd > bufferByteLength,返回 true
  9. 注:长度为 0 的 DataView 不被视为越界。
  10. 返回 false

25.3.1.5 GetViewValue ( view, requestIndex, isLittleEndian, type )

The abstract operation GetViewValue takes arguments view (an ECMAScript language value), requestIndex (an ECMAScript language value), isLittleEndian (an ECMAScript language value), and type (a TypedArray element type) and returns 要么是包含 Number 或 BigInt 的正常完成要么是抛出完成. 供 DataView 实例上的函数使用以从其视图缓冲区读取值。 It performs the following steps when called:

  1. 执行 ? RequireInternalSlot(view, [[DataView]])。
  2. 断言:view 具有 [[ViewedArrayBuffer]] 内部槽。
  3. getIndex 为 ? ToIndex(requestIndex)。
  4. isLittleEndianToBoolean(isLittleEndian)。
  5. viewOffsetview.[[ByteOffset]]
  6. viewRecordMakeDataViewWithBufferWitnessRecord(view, unordered)。
  7. 注:当 view 的后备缓冲区是可增长 SharedArrayBuffer 时,边界检查不是同步操作。
  8. IsViewOutOfBounds(viewRecord) 为 true,抛出 TypeError 异常。
  9. viewSizeGetViewByteLength(viewRecord)。
  10. elementSizeTable 73 中元素类型 type 指定的元素大小值。
  11. getIndex + elementSize > viewSize,抛出 RangeError 异常。
  12. bufferIndexgetIndex + viewOffset
  13. 返回 GetValueFromBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, false, unordered, isLittleEndian)。

25.3.1.6 SetViewValue ( view, requestIndex, isLittleEndian, type, value )

The abstract operation SetViewValue takes arguments view (an ECMAScript language value), requestIndex (an ECMAScript language value), isLittleEndian (an ECMAScript language value), type (a TypedArray element type), and value (an ECMAScript language value) and returns 要么是包含 undefined正常完成要么是抛出完成. 供 DataView 实例上的函数使用以向其视图缓冲区存储值。 It performs the following steps when called:

  1. 执行 ? RequireInternalSlot(view, [[DataView]])。
  2. 断言:view 具有 [[ViewedArrayBuffer]] 内部槽。
  3. getIndex 为 ? ToIndex(requestIndex)。
  4. IsBigIntElementType(type) 为 true,令 numberValue 为 ? ToBigInt(value)。
  5. 否则,令 numberValue 为 ? ToNumber(value)。
  6. isLittleEndianToBoolean(isLittleEndian)。
  7. viewOffsetview.[[ByteOffset]]
  8. viewRecordMakeDataViewWithBufferWitnessRecord(view, unordered)。
  9. 注:当 view 的后备缓冲区是可增长 SharedArrayBuffer 时,边界检查不是同步操作。
  10. IsViewOutOfBounds(viewRecord) 为 true,抛出 TypeError 异常。
  11. viewSizeGetViewByteLength(viewRecord)。
  12. elementSizeTable 73 中元素类型 type 指定的元素大小值。
  13. getIndex + elementSize > viewSize,抛出 RangeError 异常。
  14. bufferIndexgetIndex + viewOffset
  15. 执行 SetValueInBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, numberValue, false, unordered, isLittleEndian)。
  16. 返回 undefined

25.3.2 DataView 构造函数

DataView 构造函数

  • %DataView%
  • 是全局对象 "DataView" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 DataView。
  • 不应作为函数调用;若如此调用将抛出异常。
  • 可作为类定义 extends 子句的值。欲继承指定 DataView 行为的子类构造函数必须包含对 DataView 构造函数super 调用,以创建并初始化具有支持 DataView.prototype 内置方法所需内部状态的子类实例。

25.3.2.1 DataView ( buffer [ , byteOffset [ , byteLength ] ] )

该函数被调用时执行以下步骤:

  1. 若 NewTarget 为 undefined,抛出 TypeError 异常。
  2. 执行 ? RequireInternalSlot(buffer, [[ArrayBufferData]])。
  3. offset 为 ? ToIndex(byteOffset)。
  4. IsDetachedBuffer(buffer) 为 true,抛出 TypeError 异常。
  5. bufferByteLengthArrayBufferByteLength(buffer, seq-cst)。
  6. offset > bufferByteLength,抛出 RangeError 异常。
  7. bufferIsFixedLengthIsFixedLengthArrayBuffer(buffer)。
  8. byteLengthundefined,则
    1. bufferIsFixedLengthtrue,则
      1. viewByteLengthbufferByteLength - offset
    2. 否则,
      1. viewByteLengthauto
  9. 否则,
    1. viewByteLength 为 ? ToIndex(byteLength)。
    2. offset + viewByteLength > bufferByteLength,抛出 RangeError 异常。
  10. O 为 ? OrdinaryCreateFromConstructor(NewTarget, "%DataView.prototype%", « [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] »)。
  11. IsDetachedBuffer(buffer) 为 true,抛出 TypeError 异常。
  12. bufferByteLengthArrayBufferByteLength(buffer, seq-cst)。
  13. offset > bufferByteLength,抛出 RangeError 异常。
  14. byteLength 不为 undefined,则
    1. offset + viewByteLength > bufferByteLength,抛出 RangeError 异常。
  15. O.[[ViewedArrayBuffer]]buffer
  16. O.[[ByteLength]]viewByteLength
  17. O.[[ByteOffset]]offset
  18. 返回 O

25.3.3 DataView 构造函数的属性

DataView 构造函数

25.3.3.1 DataView.prototype

DataView.prototype 的初始值是 DataView 原型对象

该属性特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

25.3.4 DataView 原型对象的属性

DataView 原型对象

  • %DataView.prototype%
  • 具有 [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 是一个普通对象
  • 没有 [[DataView]][[ViewedArrayBuffer]][[ByteLength]][[ByteOffset]] 内部槽。

25.3.4.1 get DataView.prototype.buffer

DataView.prototype.buffer 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[DataView]])。
  3. 断言:O 具有 [[ViewedArrayBuffer]] 内部槽。
  4. bufferO.[[ViewedArrayBuffer]]
  5. 返回 buffer

25.3.4.2 get DataView.prototype.byteLength

DataView.prototype.byteLength 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[DataView]])。
  3. 断言:O 具有 [[ViewedArrayBuffer]] 内部槽。
  4. viewRecordMakeDataViewWithBufferWitnessRecord(O, seq-cst)。
  5. IsViewOutOfBounds(viewRecord) 为 true,抛出 TypeError 异常。
  6. sizeGetViewByteLength(viewRecord)。
  7. 返回 𝔽(size)。

25.3.4.3 get DataView.prototype.byteOffset

DataView.prototype.byteOffset 是一个存取器属性,其 set 访问器函数为 undefined。其 get 访问器函数被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[DataView]])。
  3. 断言:O 具有 [[ViewedArrayBuffer]] 内部槽。
  4. viewRecordMakeDataViewWithBufferWitnessRecord(O, seq-cst)。
  5. IsViewOutOfBounds(viewRecord) 为 true,抛出 TypeError 异常。
  6. offsetO.[[ByteOffset]]
  7. 返回 𝔽(offset)。

25.3.4.4 DataView.prototype.constructor

DataView.prototype.constructor 的初始值是 %DataView%

25.3.4.5 DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. 返回 ? GetViewValue(view, byteOffset, littleEndian, bigint64)。

25.3.4.6 DataView.prototype.getBigUint64 ( byteOffset [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. 返回 ? GetViewValue(view, byteOffset, littleEndian, biguint64)。

25.3.4.7 DataView.prototype.getFloat16 ( byteOffset [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? GetViewValue(view, byteOffset, littleEndian, float16)。

25.3.4.8 DataView.prototype.getFloat32 ( byteOffset [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? GetViewValue(view, byteOffset, littleEndian, float32)。

25.3.4.9 DataView.prototype.getFloat64 ( byteOffset [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? GetViewValue(view, byteOffset, littleEndian, float64)。

25.3.4.10 DataView.prototype.getInt8 ( byteOffset )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. 返回 ? GetViewValue(view, byteOffset, true, int8)。

25.3.4.11 DataView.prototype.getInt16 ( byteOffset [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? GetViewValue(view, byteOffset, littleEndian, int16)。

25.3.4.12 DataView.prototype.getInt32 ( byteOffset [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? GetViewValue(view, byteOffset, littleEndian, int32)。

25.3.4.13 DataView.prototype.getUint8 ( byteOffset )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. 返回 ? GetViewValue(view, byteOffset, true, uint8)。

25.3.4.14 DataView.prototype.getUint16 ( byteOffset [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? GetViewValue(view, byteOffset, littleEndian, uint16)。

25.3.4.15 DataView.prototype.getUint32 ( byteOffset [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? GetViewValue(view, byteOffset, littleEndian, uint32)。

25.3.4.16 DataView.prototype.setBigInt64 ( byteOffset, value [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. 返回 ? SetViewValue(view, byteOffset, littleEndian, bigint64, value)。

25.3.4.17 DataView.prototype.setBigUint64 ( byteOffset, value [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. 返回 ? SetViewValue(view, byteOffset, littleEndian, biguint64, value)。

25.3.4.18 DataView.prototype.setFloat16 ( byteOffset, value [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? SetViewValue(view, byteOffset, littleEndian, float16, value)。

25.3.4.19 DataView.prototype.setFloat32 ( byteOffset, value [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? SetViewValue(view, byteOffset, littleEndian, float32, value)。

25.3.4.20 DataView.prototype.setFloat64 ( byteOffset, value [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? SetViewValue(view, byteOffset, littleEndian, float64, value)。

25.3.4.21 DataView.prototype.setInt8 ( byteOffset, value )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. 返回 ? SetViewValue(view, byteOffset, true, int8, value)。

25.3.4.22 DataView.prototype.setInt16 ( byteOffset, value [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? SetViewValue(view, byteOffset, littleEndian, int16, value)。

25.3.4.23 DataView.prototype.setInt32 ( byteOffset, value [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? SetViewValue(view, byteOffset, littleEndian, int32, value)。

25.3.4.24 DataView.prototype.setUint8 ( byteOffset, value )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. 返回 ? SetViewValue(view, byteOffset, true, uint8, value)。

25.3.4.25 DataView.prototype.setUint16 ( byteOffset, value [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? SetViewValue(view, byteOffset, littleEndian, uint16, value)。

25.3.4.26 DataView.prototype.setUint32 ( byteOffset, value [ , littleEndian ] )

该方法被调用时执行以下步骤:

  1. viewthis 值。
  2. littleEndian 不存在,设 littleEndianfalse
  3. 返回 ? SetViewValue(view, byteOffset, littleEndian, uint32, value)。

25.3.4.27 DataView.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "DataView"

该属性特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

25.3.5 DataView 实例的属性

DataView 实例是从 DataView 原型对象继承属性的普通对象。每个 DataView 实例具有 [[DataView]][[ViewedArrayBuffer]][[ByteLength]][[ByteOffset]] 内部槽。

Note

[[DataView]] 内部槽的值不在本规范中使用。该内部槽的简单存在用于在规范中识别由 DataView 构造函数创建的对象。

25.4 Atomics 对象

Atomics 对象:

  • %Atomics%
  • 是全局对象 "Atomics" 属性的初始值。
  • 是一个普通对象
  • 有一个 [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 没有 [[Construct]] 内部方法;不能与 new 运算符一起作为构造函数使用。
  • 没有 [[Call]] 内部方法;不能作为函数调用。

Atomics 对象提供在共享内存数组单元上不可分割(原子)操作的函数,以及让 agent 等待和派发原始事件(primitive events)的函数。正确使用 Atomics 函数,可以让通过共享内存通信的多 agent 程序即便在并行 CPU 上也按照可理解的顺序执行。共享内存通信的规则由下文定义的内存模型提供。

Note

关于在 ECMAScript 中编程与实现共享内存的说明性指南,请参见内存模型章节末尾的注释。

25.4.1 Waiter Record

Waiter Record 是一个 Record 值,用于表示一次对 Atomics.waitAtomics.waitAsync 的特定调用。

Waiter Record 拥有 Table 76 中列出的字段。

Table 76: Waiter Record 字段
字段名 取值 含义
[[AgentSignifier]] 一个 agent 标识符 调用 Atomics.waitAtomics.waitAsync 的 agent。
[[PromiseCapability]] 一个 PromiseCapability Recordblocking 若表示一次对 Atomics.waitAsync 的调用,则为生成的 promise,否则为 blocking
[[TimeoutTime]] 一个非负扩展数学值 可能触发超时的最早时间;使用时间值计算。
[[Result]] "ok""timed-out" 调用的返回值。

25.4.2 WaiterList Records

WaiterList Record 用于解释通过 Atomics.waitAtomics.waitAsyncAtomics.notify 进行的等待与通知。

WaiterList Record 拥有 Table 77 中列出的字段。

Table 77: WaiterList Record 字段
字段名 取值 含义
[[Waiters]] 一个 Waiter RecordList 等待与该 WaiterList 关联的位置的 Atomics.waitAtomics.waitAsync 调用。
[[MostRecentLeaveEvent]] 一个 Synchronize 事件empty 最近一次离开其临界区的事件;若从未进入过其临界区则为 empty

在一个 WaiterList 中可以有多个具有相同 agent 标识符的 Waiter Record

agent 集群拥有一个 WaiterList Record 的存储;该存储由 (block, i) 索引,其中 block 是一个 Shared Data Blockiblock 内存中的字节偏移。WaiterList Record 与 agent 无关:在集群中任一 agent 中按 (block, i) 查找都会得到同一 WaiterList Record。

每个 WaiterList Record 有一个 临界区(critical section),控制在求值期间对该 WaiterList Record 的独占访问。一次只能有一个 agent 进入该临界区。进入和离开临界区由抽象操作 EnterCriticalSectionLeaveCriticalSection 控制。对 WaiterList Record 的操作——添加和移除等待的 agent、遍历 agent 列表、挂起与通知列表中的 agent、设置与获取 Synchronize 事件——只能由已进入该临界区的 agent 执行。

25.4.3 Atomics 的抽象操作

25.4.3.1 ValidateIntegerTypedArray ( typedArray, waitable )

The abstract operation ValidateIntegerTypedArray takes arguments typedArray (an ECMAScript language value) and waitable (a Boolean) and returns 要么是包含一个 TypedArray With Buffer Witness Record正常完成,要么是抛出完成. It performs the following steps when called:

  1. taRecord 为 ? ValidateTypedArray(typedArray, unordered)。
  2. 注:当 typedArray 的后备缓冲区是可增长 SharedArrayBuffer 时,边界检查不是同步操作。
  3. waitabletrue,则
    1. typedArray.[[TypedArrayName]] 既不是 "Int32Array" 也不是 "BigInt64Array",抛出 TypeError 异常。
  4. 否则,
    1. typeTypedArrayElementType(typedArray)。
    2. IsUnclampedIntegerElementType(type) 为 falseIsBigIntElementType(type) 为 false,抛出 TypeError 异常。
  5. 返回 taRecord

25.4.3.2 ValidateAtomicAccess ( taRecord, requestIndex )

The abstract operation ValidateAtomicAccess takes arguments taRecord (a TypedArray With Buffer Witness Record) and requestIndex (an ECMAScript language value) and returns 要么是包含一个整数的正常完成要么是抛出完成. It performs the following steps when called:

  1. lengthTypedArrayLength(taRecord)。
  2. accessIndex 为 ? ToIndex(requestIndex)。
  3. 断言:accessIndex ≥ 0。
  4. accessIndexlength,抛出 RangeError 异常。
  5. typedArraytaRecord.[[Object]]
  6. elementSizeTypedArrayElementSize(typedArray)。
  7. offsettypedArray.[[ByteOffset]]
  8. 返回 (accessIndex × elementSize) + offset

25.4.3.3 ValidateAtomicAccessOnIntegerTypedArray ( typedArray, requestIndex )

The abstract operation ValidateAtomicAccessOnIntegerTypedArray takes arguments typedArray (an ECMAScript language value) and requestIndex (an ECMAScript language value) and returns 要么是包含一个整数的正常完成要么是抛出完成. It performs the following steps when called:

  1. taRecord 为 ? ValidateIntegerTypedArray(typedArray, false)。
  2. 返回 ? ValidateAtomicAccess(taRecord, requestIndex)。

25.4.3.4 RevalidateAtomicAccess ( typedArray, byteIndexInBuffer )

The abstract operation RevalidateAtomicAccess takes arguments typedArray (a TypedArray) and byteIndexInBuffer (an integer) and returns 要么是包含 unused正常完成要么是抛出完成. 该操作在 Atomics 方法中所有参数强制类型转换完成后对底层缓冲区中的索引重新验证,因为参数转换可能有任意副作用,会导致缓冲区变为越界。当 typedArray 的后备缓冲区是 SharedArrayBuffer 时该操作不会抛出。 It performs the following steps when called:

  1. taRecordMakeTypedArrayWithBufferWitnessRecord(typedArray, unordered)。
  2. 注:当 typedArray 的后备缓冲区是可增长 SharedArrayBuffer 时,边界检查不是同步操作。
  3. IsTypedArrayOutOfBounds(taRecord) 为 true,抛出 TypeError 异常。
  4. 断言:byteIndexInBuffertypedArray.[[ByteOffset]]
  5. byteIndexInBuffertaRecord.[[CachedBufferByteLength]],抛出 RangeError 异常。
  6. 返回 unused

25.4.3.5 GetWaiterList ( block, i )

The abstract operation GetWaiterList takes arguments block (a Shared Data Block) and i (a non-negative integer that is evenly divisible by 4) and returns a WaiterList Record. It performs the following steps when called:

  1. 断言:ii + 3 均是 block 内存中的有效字节偏移。
  2. 返回由 (block, i) 对引用的 WaiterList Record

25.4.3.6 EnterCriticalSection ( WL )

The abstract operation EnterCriticalSection takes argument WL (a WaiterList Record) and returns unused. It performs the following steps when called:

  1. 断言:外层 agent 不在任何 WaiterList Record 的临界区中。
  2. 等待直到没有 agent 在 WL 的临界区中,然后进入 WL 的临界区(期间不允许其他 agent 进入)。
  3. WL.[[MostRecentLeaveEvent]] 不为 empty,则
    1. 注:至少进入过一次临界区的 WL 有由 LeaveCriticalSection 设置的 Synchronize 事件
    2. execution 为外层 agent 的 Agent Record[[CandidateExecution]] 字段。
    3. eventsRecordexecution.[[EventsRecords]][[AgentSignifier]]AgentSignifier() 的 Agent Events Record
    4. enterEvent 为一个新的 Synchronize 事件
    5. enterEvent 追加到 eventsRecord.[[EventList]]
    6. 将 (WL.[[MostRecentLeaveEvent]], enterEvent) 追加到 eventsRecord.[[AgentSynchronizesWith]]
  4. 返回 unused

当尝试进入临界区的 agent 必须等待另一个 agent 离开时,EnterCriticalSection 存在 争用(contention)。无争用时,EnterCriticalSection 调用的 FIFO 顺序是可观察的;有争用时,实现可选择任意顺序,但不能导致某个 agent 无限期等待。

25.4.3.7 LeaveCriticalSection ( WL )

The abstract operation LeaveCriticalSection takes argument WL (a WaiterList Record) and returns unused. It performs the following steps when called:

  1. 断言:外层 agent 正在 WL 的临界区中。
  2. execution 为外层 agent 的 Agent Record[[CandidateExecution]] 字段。
  3. eventsRecordexecution.[[EventsRecords]][[AgentSignifier]]AgentSignifier() 的 Agent Events Record
  4. leaveEvent 为一个新的 Synchronize 事件
  5. leaveEvent 追加到 eventsRecord.[[EventList]]
  6. WL.[[MostRecentLeaveEvent]]leaveEvent
  7. 离开 WL 的临界区。
  8. 返回 unused

25.4.3.8 AddWaiter ( WL, waiterRecord )

The abstract operation AddWaiter takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. 断言:外层 agent 在 WL 的临界区中。
  2. 断言:WL.[[Waiters]] 中不存在其 [[PromiseCapability]] 字段为 waiterRecord.[[PromiseCapability]][[AgentSignifier]] 字段为 waiterRecord.[[AgentSignifier]]Waiter Record
  3. waiterRecord 追加到 WL.[[Waiters]]
  4. 返回 unused

25.4.3.9 RemoveWaiter ( WL, waiterRecord )

The abstract operation RemoveWaiter takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. 断言:外层 agent 在 WL 的临界区中。
  2. 断言:WL.[[Waiters]] 包含 waiterRecord
  3. WL.[[Waiters]] 移除 waiterRecord
  4. 返回 unused

25.4.3.10 RemoveWaiters ( WL, c )

The abstract operation RemoveWaiters takes arguments WL (a WaiterList Record) and c (a non-negative integer or +∞) and returns a List of Waiter Records. It performs the following steps when called:

  1. 断言:外层 agent 在 WL 的临界区中。
  2. lenWL.[[Waiters]] 中元素数量。
  3. nmin(c, len)。
  4. L 为一个 List,其元素为 WL.[[Waiters]] 的前 n 个元素。
  5. 移除 WL.[[Waiters]] 的前 n 个元素。
  6. 返回 L

25.4.3.11 SuspendThisAgent ( WL, waiterRecord )

The abstract operation SuspendThisAgent takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. 断言:外层 agent 在 WL 的临界区中。
  2. 断言:WL.[[Waiters]] 包含 waiterRecord
  3. thisAgentAgentSignifier()。
  4. 断言:waiterRecord.[[AgentSignifier]]thisAgent
  5. 断言:waiterRecord.[[PromiseCapability]]blocking
  6. 断言:AgentCanSuspend() 为 true
  7. 执行 LeaveCriticalSection(WL) 并挂起外层 agent 直到时间到达 waiterRecord.[[TimeoutTime]],以一种方式组合操作:使得离开临界区后到挂起生效前到来的通知不会丢失。外层 agent 只能因超时或另一个 agent 使用参数 WLthisAgent 调用 NotifyWaiter(即通过调用 Atomics.notify)而被唤醒。
  8. 执行 EnterCriticalSection(WL)。
  9. 返回 unused

25.4.3.12 NotifyWaiter ( WL, waiterRecord )

The abstract operation NotifyWaiter takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. 断言:外层 agent 在 WL 的临界区中。
  2. waiterRecord.[[PromiseCapability]]blocking,则
    1. 唤醒其标识符为 waiterRecord.[[AgentSignifier]] 的 agent。
    2. 注:这会使该 agent 在 SuspendThisAgent 中恢复执行。
  3. 否则若 AgentSignifier() 是 waiterRecord.[[AgentSignifier]],则
    1. promiseCapabilitywaiterRecord.[[PromiseCapability]]
    2. 执行 ! Call(promiseCapability.[[Resolve]], undefined, « waiterRecord.[[Result]] »)。
  4. 否则,
    1. 执行 EnqueueResolveInAgentJob(waiterRecord.[[AgentSignifier]], waiterRecord.[[PromiseCapability]], waiterRecord.[[Result]])。
  5. 返回 unused
Note

一个 agent 不得以除传递给宿主之外的任何方式访问另一个 agent 的 promise capability。

25.4.3.13 EnqueueResolveInAgentJob ( agentSignifier, promiseCapability, resolution )

The abstract operation EnqueueResolveInAgentJob takes arguments agentSignifier (an agent signifier), promiseCapability (a PromiseCapability Record), and resolution ("ok" or "timed-out") and returns unused. It performs the following steps when called:

  1. resolveJob 为一个无参数的新 Job 抽象闭包,捕获 agentSignifierpromiseCapabilityresolution,被调用时执行:
    1. 断言:AgentSignifier() 是 agentSignifier
    2. 执行 ! Call(promiseCapability.[[Resolve]], undefined, « resolution »)。
    3. 返回 unused
  2. realmInTargetAgent 为 ! GetFunctionRealm(promiseCapability.[[Resolve]])。
  3. 断言:agentSignifierrealmInTargetAgent.[[AgentSignifier]]
  4. 执行 HostEnqueueGenericJob(resolveJob, realmInTargetAgent)。
  5. 返回 unused

25.4.3.14 DoWait ( mode, typedArray, index, value, timeout )

The abstract operation DoWait takes arguments mode (sync or async), typedArray (an ECMAScript language value), index (an ECMAScript language value), value (an ECMAScript language value), and timeout (an ECMAScript language value) and returns 要么是包含一个 Object、"not-equal""timed-out""ok"正常完成,要么是抛出完成. It performs the following steps when called:

  1. taRecord 为 ? ValidateIntegerTypedArray(typedArray, true)。
  2. buffertaRecord.[[Object]].[[ViewedArrayBuffer]]
  3. IsSharedArrayBuffer(buffer) 为 false,抛出 TypeError 异常。
  4. i 为 ? ValidateAtomicAccess(taRecord, index)。
  5. arrayTypeNametypedArray.[[TypedArrayName]]
  6. arrayTypeName"BigInt64Array",令 v 为 ? ToBigInt64(value)。
  7. 否则,令 v 为 ? ToInt32(value)。
  8. q 为 ? ToNumber(timeout)。
  9. qNaN+∞𝔽,令 t 为 +∞;否则若 q-∞𝔽,令 t 为 0;否则令 tmax((q), 0)。
  10. modesyncAgentCanSuspend() 为 false,抛出 TypeError 异常。
  11. blockbuffer.[[ArrayBufferData]]
  12. offsettypedArray.[[ByteOffset]]
  13. byteIndexInBuffer 为 (i × 4) + offset
  14. WLGetWaiterList(block, byteIndexInBuffer)。
  15. modesync,则
    1. promiseCapabilityblocking
    2. resultObjectundefined
  16. 否则,
    1. promiseCapability 为 ! NewPromiseCapability(%Promise%)。
    2. resultObjectOrdinaryObjectCreate(%Object.prototype%)。
  17. 执行 EnterCriticalSection(WL)。
  18. elementTypeTypedArrayElementType(typedArray)。
  19. wGetValueFromBuffer(buffer, byteIndexInBuffer, elementType, true, seq-cst)。
  20. vw,则
    1. 执行 LeaveCriticalSection(WL)。
    2. modesync,返回 "not-equal"
    3. 执行 ! CreateDataPropertyOrThrow(resultObject, "async", false)。
    4. 执行 ! CreateDataPropertyOrThrow(resultObject, "value", "not-equal")。
    5. 返回 resultObject
  21. t = 0 且 modeasync,则
    1. 注:对同步的立即超时没有特殊处理;异步立即超时被特殊处理以快速失败并避免不必要的 Promise 作业。
    2. 执行 LeaveCriticalSection(WL)。
    3. 执行 ! CreateDataPropertyOrThrow(resultObject, "async", false)。
    4. 执行 ! CreateDataPropertyOrThrow(resultObject, "value", "timed-out")。
    5. 返回 resultObject
  22. thisAgentAgentSignifier()。
  23. now 为标识当前时间的时间值 (UTC)。
  24. additionalTimeout 为实现定义的非负数学值
  25. timeoutTime(now) + t + additionalTimeout
  26. 注:当 t 为 +∞ 时,timeoutTime 亦为 +∞。
  27. waiterRecord 为一个新 Waiter Record { [[AgentSignifier]]: thisAgent, [[PromiseCapability]]: promiseCapability, [[TimeoutTime]]: timeoutTime, [[Result]]: "ok" }。
  28. 执行 AddWaiter(WL, waiterRecord)。
  29. modesync,则
    1. 执行 SuspendThisAgent(WL, waiterRecord)。
  30. 否则若 timeoutTime有限的,则
    1. 执行 EnqueueAtomicsWaitAsyncTimeoutJob(WL, waiterRecord)。
  31. 执行 LeaveCriticalSection(WL)。
  32. modesync,返回 waiterRecord.[[Result]]
  33. 执行 ! CreateDataPropertyOrThrow(resultObject, "async", true)。
  34. 执行 ! CreateDataPropertyOrThrow(resultObject, "value", promiseCapability.[[Promise]])。
  35. 返回 resultObject
Note

additionalTimeout 允许实现按需填充超时,例如用于降低能耗或粗化计时器分辨率以缓解计时攻击。该值在不同 DoWait 调用间可能不同。

25.4.3.15 EnqueueAtomicsWaitAsyncTimeoutJob ( WL, waiterRecord )

The abstract operation EnqueueAtomicsWaitAsyncTimeoutJob takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. timeoutJob 为一个无参数的新 Job 抽象闭包,捕获 WLwaiterRecord,被调用时执行:
    1. 执行 EnterCriticalSection(WL)。
    2. WL.[[Waiters]] 包含 waiterRecord,则
      1. timeOfJobExecution 为标识当前时间的时间值 (UTC)。
      2. 断言:(timeOfJobExecution) ≥ waiterRecord.[[TimeoutTime]](忽略时间值可能的非单调性)。
      3. waiterRecord.[[Result]]"timed-out"
      4. 执行 RemoveWaiter(WL, waiterRecord)。
      5. 执行 NotifyWaiter(WL, waiterRecord)。
    3. 执行 LeaveCriticalSection(WL)。
    4. 返回 unused
  2. now 为标识当前时间的时间值 (UTC)。
  3. currentRealm当前 Realm Record
  4. 执行 HostEnqueueTimeoutJob(timeoutJob, currentRealm, 𝔽(waiterRecord.[[TimeoutTime]]) - now)。
  5. 返回 unused

25.4.3.16 AtomicCompareExchangeInSharedBlock ( block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes )

The abstract operation AtomicCompareExchangeInSharedBlock takes arguments block (a Shared Data Block), byteIndexInBuffer (an integer), elementSize (a non-negative integer), expectedBytes (a List of byte values), and replacementBytes (a List of byte values) and returns a List of byte values. It performs the following steps when called:

  1. execution 为外层 agent 的 Agent Record[[CandidateExecution]] 字段。
  2. eventsRecordexecution.[[EventsRecords]][[AgentSignifier]]AgentSignifier() 的 Agent Events Record
  3. rawBytesRead 为长度 elementSizeList,其元素为非确定性选择的字节值
  4. 注:在实现中,rawBytesRead 是底层硬件 load-link、load-exclusive 或读-改-写指令操作数的结果;该非确定性是内存模型对弱一致硬件可观察行为的语义描述。
  5. 注:期望值与读值的比较在读-改-写修改函数之外执行,以避免当期望值不等于读值时产生不必要的强同步。
  6. ByteListEqual(rawBytesRead, expectedBytes) 为 true,则
    1. second 为一个具有参数 (oldBytes, newBytes) 的新读-改-写修改函数,不捕获任何内容,被调用时原子地执行:
      1. 返回 newBytes
    2. eventReadModifyWriteSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize, [[Payload]]: replacementBytes, [[ModifyOp]]: second }。
  7. 否则,
    1. eventReadSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize }。
  8. event 追加到 eventsRecord.[[EventList]]
  9. Chosen Value Record { [[Event]]: event, [[ChosenValue]]: rawBytesRead } 追加到 execution.[[ChosenValues]]
  10. 返回 rawBytesRead

25.4.3.17 AtomicReadModifyWrite ( typedArray, index, value, op )

The abstract operation AtomicReadModifyWrite takes arguments typedArray (an ECMAScript language value), index (an ECMAScript language value), value (an ECMAScript language value), and op (a read-modify-write modification function) and returns 要么是包含 Number 或 BigInt 的正常完成要么是抛出完成. op 接受两个字节值 List 参数并返回一个字节值 List。该操作原子地加载一个值,将其与另一个值组合并存储组合结果。它返回被加载的值。 It performs the following steps when called:

  1. byteIndexInBuffer 为 ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index)。
  2. typedArray.[[ContentType]]bigint,令 v 为 ? ToBigInt(value)。
  3. 否则,令 v𝔽(? ToIntegerOrInfinity(value))。
  4. 执行 ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer)。
  5. buffertypedArray.[[ViewedArrayBuffer]]
  6. elementTypeTypedArrayElementType(typedArray)。
  7. 返回 GetModifySetValueInBuffer(buffer, byteIndexInBuffer, elementType, v, op)。

25.4.3.18 ByteListBitwiseOp ( op, xBytes, yBytes )

The abstract operation ByteListBitwiseOp takes arguments op (&, ^, or |), xBytes (a List of byte values), and yBytes (a List of byte values) and returns a List of byte values. 该操作对参数的所有字节值执行按位运算并返回一个字节值 List。 It performs the following steps when called:

  1. 断言:xBytesyBytes 拥有相同数量的元素。
  2. result 为新空 List
  3. i 为 0。
  4. xBytes 的每个元素 xByte,执行
    1. yByteyBytes[i]。
    2. op&,则
      1. resultByte 为对 xByteyByte 执行按位与的结果。
    3. 否则若 op^,则
      1. resultByte 为按位异或结果。
    4. 否则,
      1. 断言:op|
      2. resultByte 为按位或结果。
    5. ii + 1。
    6. resultByte 追加到 result
  5. 返回 result

25.4.3.19 ByteListEqual ( xBytes, yBytes )

The abstract operation ByteListEqual takes arguments xBytes (a List of byte values) and yBytes (a List of byte values) and returns a Boolean. It performs the following steps when called:

  1. xBytesyBytes 的元素数量不同,返回 false
  2. i 为 0。
  3. xBytes 的每个元素 xByte,执行
    1. yByteyBytes[i]。
    2. xByteyByte,返回 false
    3. ii + 1。
  4. 返回 true

25.4.4 Atomics.add ( typedArray, index, value )

该函数被调用时执行以下步骤:

  1. add 为一个具有参数 (xBytes, yBytes) 的新读-改-写修改函数,捕获 typedArray,被调用时原子地执行:
    1. typeTypedArrayElementType(typedArray)。
    2. isLittleEndian 为外层 agent 的 Agent Record[[LittleEndian]] 字段的值。
    3. xRawBytesToNumeric(type, xBytes, isLittleEndian)。
    4. yRawBytesToNumeric(type, yBytes, isLittleEndian)。
    5. x 是 Number,则
      1. sumNumber::add(x, y)。
    6. 否则,
      1. 断言:x 是 BigInt
      2. sumBigInt::add(x, y)。
    7. sumBytesNumericToRawBytes(type, sum, isLittleEndian)。
    8. 断言:sumBytesxBytesyBytes 拥有相同数量的元素。
    9. 返回 sumBytes
  2. 返回 ? AtomicReadModifyWrite(typedArray, index, value, add)。

25.4.5 Atomics.and ( typedArray, index, value )

该函数被调用时执行以下步骤:

  1. and 为一个具有参数 (xBytes, yBytes) 的新读-改-写修改函数,不捕获任何内容,被调用时原子地执行:
    1. 返回 ByteListBitwiseOp(&, xBytes, yBytes)。
  2. 返回 ? AtomicReadModifyWrite(typedArray, index, value, and)。

25.4.6 Atomics.compareExchange ( typedArray, index, expectedValue, replacementValue )

该函数被调用时执行以下步骤:

  1. byteIndexInBuffer 为 ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index)。
  2. buffertypedArray.[[ViewedArrayBuffer]]
  3. blockbuffer.[[ArrayBufferData]]
  4. typedArray.[[ContentType]]bigint,则
    1. expected 为 ? ToBigInt(expectedValue)。
    2. replacement 为 ? ToBigInt(replacementValue)。
  5. 否则,
    1. expected𝔽(? ToIntegerOrInfinity(expectedValue))。
    2. replacement𝔽(? ToIntegerOrInfinity(replacementValue))。
  6. 执行 ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer)。
  7. elementTypeTypedArrayElementType(typedArray)。
  8. elementSizeTypedArrayElementSize(typedArray)。
  9. isLittleEndian 为外层 agent 的 Agent Record[[LittleEndian]] 字段的值。
  10. expectedBytesNumericToRawBytes(elementType, expected, isLittleEndian)。
  11. replacementBytesNumericToRawBytes(elementType, replacement, isLittleEndian)。
  12. IsSharedArrayBuffer(buffer) 为 true,则
    1. rawBytesReadAtomicCompareExchangeInSharedBlock(block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes)。
  13. 否则,
    1. rawBytesRead 为长度 elementSizeList,其元素为自 block[byteIndexInBuffer] 起的 elementSize 个字节。
    2. ByteListEqual(rawBytesRead, expectedBytes) 为 true,则
      1. replacementBytes 的各字节写入 block,起始于 block[byteIndexInBuffer]。
  14. 返回 RawBytesToNumeric(elementType, rawBytesRead, isLittleEndian)。

25.4.7 Atomics.exchange ( typedArray, index, value )

该函数被调用时执行以下步骤:

  1. second 为一个具有参数 (oldBytes, newBytes) 的新读-改-写修改函数,不捕获任何内容,被调用时原子地执行:
    1. 返回 newBytes
  2. 返回 ? AtomicReadModifyWrite(typedArray, index, value, second)。

25.4.8 Atomics.isLockFree ( size )

该函数被调用时执行以下步骤:

  1. n 为 ? ToIntegerOrInfinity(size)。
  2. AR 为外层 agent 的 Agent Record
  3. n = 1,返回 AR.[[IsLockFree1]]
  4. n = 2,返回 AR.[[IsLockFree2]]
  5. n = 4,返回 true
  6. n = 8,返回 AR.[[IsLockFree8]]
  7. 返回 false
Note

此函数是一个优化原语。直觉是:如果大小为 n 字节的数据上的原子原语(compareExchangeloadstoreaddsubandorxorexchange)的原子步骤会在不获取该数据之外的锁的情况下执行,则 Atomics.isLockFree(n) 返回 true。高性能算法将利用该函数决定是否在临界区使用锁或原子操作。若原子原语不是无锁的,算法自行提供锁常常更高效。

Atomics.isLockFree(4) 总是返回 true,因为所有已知相关硬件都能支持。可假定此点通常简化程序。

无论此函数返回何值,所有原子操作都保证原子性。例如,它们不会在操作中间出现可见操作(如“撕裂”)。

25.4.9 Atomics.load ( typedArray, index )

该函数被调用时执行以下步骤:

  1. byteIndexInBuffer 为 ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index)。
  2. 执行 ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer)。
  3. buffertypedArray.[[ViewedArrayBuffer]]
  4. elementTypeTypedArrayElementType(typedArray)。
  5. 返回 GetValueFromBuffer(buffer, byteIndexInBuffer, elementType, true, seq-cst)。

25.4.10 Atomics.or ( typedArray, index, value )

该函数被调用时执行以下步骤:

  1. or 为一个具有参数 (xBytes, yBytes) 的新读-改-写修改函数,不捕获任何内容,被调用时原子地执行:
    1. 返回 ByteListBitwiseOp(|, xBytes, yBytes)。
  2. 返回 ? AtomicReadModifyWrite(typedArray, index, value, or)。

25.4.11 Atomics.store ( typedArray, index, value )

该函数被调用时执行以下步骤:

  1. byteIndexInBuffer 为 ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index)。
  2. typedArray.[[ContentType]]bigint,令 v 为 ? ToBigInt(value)。
  3. 否则,令 v𝔽(? ToIntegerOrInfinity(value))。
  4. 执行 ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer)。
  5. buffertypedArray.[[ViewedArrayBuffer]]
  6. elementTypeTypedArrayElementType(typedArray)。
  7. 执行 SetValueInBuffer(buffer, byteIndexInBuffer, elementType, v, true, seq-cst)。
  8. 返回 v

25.4.12 Atomics.sub ( typedArray, index, value )

该函数被调用时执行以下步骤:

  1. subtract 为一个具有参数 (xBytes, yBytes) 的新读-改-写修改函数,捕获 typedArray,被调用时原子地执行:
    1. typeTypedArrayElementType(typedArray)。
    2. isLittleEndian 为外层 agent 的 Agent Record[[LittleEndian]] 字段的值。
    3. xRawBytesToNumeric(type, xBytes, isLittleEndian)。
    4. yRawBytesToNumeric(type, yBytes, isLittleEndian)。
    5. x 是 Number,则
      1. differenceNumber::subtract(x, y)。
    6. 否则,
      1. 断言:x 是 BigInt
      2. differenceBigInt::subtract(x, y)。
    7. differenceBytesNumericToRawBytes(type, difference, isLittleEndian)。
    8. 断言:differenceBytesxBytesyBytes 拥有相同数量的元素。
    9. 返回 differenceBytes
  2. 返回 ? AtomicReadModifyWrite(typedArray, index, value, subtract)。

25.4.13 Atomics.wait ( typedArray, index, value, timeout )

该函数将外层 agent 置于等待队列并挂起,直到被通知或等待超时,返回区分这些情形的字符串。

调用时执行以下步骤:

  1. 返回 ? DoWait(sync, typedArray, index, value, timeout)。

25.4.14 Atomics.waitAsync ( typedArray, index, value, timeout )

该函数返回一个 Promise,当调用者 agent 被通知或超时到达时 resolve。

调用时执行以下步骤:

  1. 返回 ? DoWait(async, typedArray, index, value, timeout)。

25.4.15 Atomics.notify ( typedArray, index, count )

该函数通知一些在等待队列中休眠的 agent。

调用时执行以下步骤:

  1. taRecord 为 ? ValidateIntegerTypedArray(typedArray, true)。
  2. byteIndexInBuffer 为 ? ValidateAtomicAccess(taRecord, index)。
  3. countundefined,则
    1. c 为 +∞。
  4. 否则,
    1. intCount 为 ? ToIntegerOrInfinity(count)。
    2. cmax(intCount, 0)。
  5. buffertypedArray.[[ViewedArrayBuffer]]
  6. blockbuffer.[[ArrayBufferData]]
  7. IsSharedArrayBuffer(buffer) 为 false,返回 +0𝔽
  8. WLGetWaiterList(block, byteIndexInBuffer)。
  9. 执行 EnterCriticalSection(WL)。
  10. SRemoveWaiters(WL, c)。
  11. S 的每个元素 W,执行
    1. 执行 NotifyWaiter(WL, W)。
  12. 执行 LeaveCriticalSection(WL)。
  13. nS 中元素数量。
  14. 返回 𝔽(n)。

25.4.16 Atomics.xor ( typedArray, index, value )

该函数被调用时执行以下步骤:

  1. xor 为一个具有参数 (xBytes, yBytes) 的新读-改-写修改函数,不捕获任何内容,被调用时原子地执行:
    1. 返回 ByteListBitwiseOp(^, xBytes, yBytes)。
  2. 返回 ? AtomicReadModifyWrite(typedArray, index, value, xor)。

25.4.17 Atomics [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "Atomics"

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

25.5 JSON 对象

JSON 对象:

  • %JSON%
  • 是全局对象 "JSON" 属性的初始值。
  • 是一个普通对象
  • 包含两个函数 parsestringify,用于解析与构造 JSON 文本。
  • 有一个 [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 没有 [[Construct]] 内部方法;不能与 new 运算符一起作为构造函数使用。
  • 没有 [[Call]] 内部方法;不能作为函数调用。

JSON 数据交换格式在 ECMA-404 中定义。本规范使用的 JSON 交换格式完全与 ECMA-404 所描述一致。JSON.parseJSON.stringify 的一致实现必须支持 ECMA-404 规范所描述的精确交换格式,不得删除或扩展该格式。

25.5.1 JSON.parse ( text [ , reviver ] )

该函数解析一个 JSON 文本(JSON 格式的字符串)并生成一个 ECMAScript 语言值。JSON 格式以类似 ECMAScript 字面量、数组初始值与对象初始值的语法表示字面量、数组与对象。解析后,JSON 对象被实现为 ECMAScript 对象;JSON 数组被实现为 ECMAScript Array 实例;JSON 字符串、数字、布尔与 null 分别实现为 ECMAScript 的 String、Number、Boolean 与 null

可选参数 reviver 是一个带两个参数 keyvalue 的函数。它可以过滤并转换结果。解析产生的每个 key/value 对都会调用它,其返回值将替代原始值。若返回收到的值,结构不变;若返回 undefined 则该属性从结果中删除。

  1. jsonString 为 ? ToString(text)。
  2. unfiltered 为 ? ParseJSON(jsonString)。
  3. IsCallable(reviver) 为 true,则
    1. rootOrdinaryObjectCreate(%Object.prototype%)。
    2. rootName 为空字符串。
    3. 执行 ! CreateDataPropertyOrThrow(root, rootName, unfiltered)。
    4. 返回 ? InternalizeJSONProperty(root, rootName, reviver)。
  4. 否则,
    1. 返回 unfiltered

该函数的 "length" 属性为 2𝔽

25.5.1.1 ParseJSON ( text )

The abstract operation ParseJSON takes argument text (a String) and returns 要么是包含一个 ECMAScript 语言值正常完成要么是抛出完成. It performs the following steps when called:

  1. 若 StringToCodePoints(text) 不是 ECMA-404 所规定的有效 JSON 文本,抛出 SyntaxError 异常。
  2. scriptString"("text");" 的字符串连接。
  3. script 为 ParseText(scriptString, Script)。
  4. 注:13.2.5.1 定义的早期错误规则对上述 ParseText 调用有特殊处理。
  5. 断言:script 是一个 Parse Node。
  6. result 为 ! Evaluation of script
  7. 注:13.2.5.5 定义的 PropertyDefinitionEvaluation 语义对上述求值有特殊处理。
  8. 断言:result 不是 String、Number、Boolean、由 ArrayLiteralObjectLiteral 定义的 Object、就是 null
  9. 返回 result

一致实现的 JSON.parse 不允许扩展 JSON 语法。若实现希望支持修改或扩展的 JSON 交换格式,必须定义不同的解析函数。

Note 1

有效 JSON 文本是 ECMAScript PrimaryExpression 语法的子集。步骤 1 验证 jsonString 是否符合该子集,步骤 8 断言求值返回一个适当类型的值。

然而,由于 13.2.5.5 在 ParseJSON 期间行为不同,同一源文本作为 PrimaryExpression 求值与作为 JSON 求值可能产生不同结果。此外,对对象字面量中重复 "__proto__" 属性的 Early Error 在 ParseJSON 中不适用,这意味着尽管语法匹配,并非所有 ParseJSON 接受的文本都可作为 PrimaryExpression 有效。

Note 2

当对象中存在重复名称字符串时,词法上先出现的同键值将被覆盖

25.5.1.2 InternalizeJSONProperty ( holder, name, reviver )

The abstract operation InternalizeJSONProperty takes arguments holder (an Object), name (a String), and reviver (a function object) and returns 要么是包含一个 ECMAScript 语言值正常完成要么是抛出完成.

Note

该算法故意不在 [[Delete]]CreateDataProperty 返回 false 时抛出异常。

调用时执行以下步骤:

  1. val 为 ? Get(holder, name)。
  2. val 是 Object,则
    1. isArray 为 ? IsArray(val)。
    2. isArraytrue,则
      1. len 为 ? LengthOfArrayLike(val)。
      2. I 为 0。
      3. I < len 重复,
        1. prop 为 ! ToString(𝔽(I))。
        2. newElement 为 ? InternalizeJSONProperty(val, prop, reviver)。
        3. newElementundefined,则
          1. 执行 ? val.[[Delete]](prop)。
        4. 否则,
          1. 执行 ? CreateDataProperty(val, prop, newElement)。
        5. II + 1。
    3. 否则,
      1. keys 为 ? EnumerableOwnProperties(val, key)。
      2. keys 的每个 String P,执行
        1. newElement 为 ? InternalizeJSONProperty(val, P, reviver)。
        2. newElementundefined,则
          1. 执行 ? val.[[Delete]](P)。
        3. 否则,
          1. 执行 ? CreateDataProperty(val, P, newElement)。
  3. 返回 ? Call(reviver, holder, « name, val »)。

25.5.2 JSON.stringify ( value [ , replacer [ , space ] ] )

该函数返回一个 UTF-16 编码的 JSON 格式字符串表示一个 ECMAScript 语言值,或 undefined。它可接受三个参数。参数 valueECMAScript 语言值,通常是对象或数组,也可以是 String、Boolean、Number 或 null。可选参数 replacer 要么是函数,改变对象与数组的字符串化方式;要么是由 String 与 Number 组成的数组,充当包含列表,选择会被字符串化的对象属性。可选参数 space 是 String 或 Number,用于在结果中注入空白以提升可读性。

调用时执行以下步骤:

  1. stack 为新空 List
  2. indent 为空字符串。
  3. PropertyListundefined
  4. ReplacerFunctionundefined
  5. replacer 是 Object,则
    1. IsCallable(replacer) 为 true,则
      1. ReplacerFunctionreplacer
    2. 否则,
      1. isArray 为 ? IsArray(replacer)。
      2. isArraytrue,则
        1. PropertyList 为新空 List
        2. len 为 ? LengthOfArrayLike(replacer)。
        3. k 为 0。
        4. k < len 重复,
          1. prop 为 ! ToString(𝔽(k))。
          2. v 为 ? Get(replacer, prop)。
          3. itemundefined
          4. v 是 String,则
            1. itemv
          5. 否则若 v 是 Number,则
            1. item 为 ! ToString(v)。
          6. 否则若 v 是 Object,则
            1. v 具有 [[StringData]][[NumberData]] 内部槽,设 item 为 ? ToString(v)。
          7. item 不为 undefinedPropertyList 不包含 item,则
            1. item 追加到 PropertyList
          8. kk + 1。
  6. space 是 Object,则
    1. space 具有 [[NumberData]] 内部槽,则
      1. space 为 ? ToNumber(space)。
    2. 否则若 space 具有 [[StringData]] 内部槽,则
      1. space 为 ? ToString(space)。
  7. space 是 Number,则
    1. spaceMV 为 ! ToIntegerOrInfinity(space)。
    2. spaceMVmin(10, spaceMV)。
    3. spaceMV < 1,令 gap 为空字符串;否则令 gap 为包含 spaceMV 个代码单元 0x0020 (SPACE) 的字符串。
  8. 否则若 space 是 String,则
    1. space 长度 ≤ 10,令 gapspace;否则令 gapspace 的前 10 个代码单元子串。
  9. 否则,
    1. gap 为空字符串。
  10. wrapperOrdinaryObjectCreate(%Object.prototype%)。
  11. 执行 ! CreateDataPropertyOrThrow(wrapper, 空字符串, value)。
  12. stateJSON Serialization Record { [[ReplacerFunction]]: ReplacerFunction, [[Stack]]: stack, [[Indent]]: indent, [[Gap]]: gap, [[PropertyList]]: PropertyList }。
  13. 返回 ? SerializeJSONProperty(state, 空字符串, wrapper)。

该函数的 "length" 属性为 3𝔽

Note 1

JSON 结构允许任意深度嵌套,但必须非循环。若 value 是或包含循环结构,则该函数必须抛出 TypeError 异常。如下是一个不可字符串化的值示例:

a = [];
a[0] = a;
my_text = JSON.stringify(a); // 必须抛出 TypeError。
Note 2

符号化的原始值呈现如下:

  • null 在 JSON 文本中呈现为字符串值 "null"
  • undefined 不呈现。
  • true 在 JSON 文本中呈现为字符串值 "true"
  • false 在 JSON 文本中呈现为字符串值 "false"
Note 3

字符串值以 QUOTATION MARK (") 代码单元包裹。代码单元 "\\ 前缀转义。控制字符代码单元替换为 \uHHHH 转义序列,或更短形式 \b(BACKSPACE)、\f(FORM FEED)、\n(LINE FEED)、\r(CARRIAGE RETURN)、\t(CHARACTER TABULATION)。

Note 4

有限数字按调用 ToString(number) 的方式字符串化。NaN 与任意符号的 Infinity 表示为字符串值 "null"

Note 5

没有 JSON 表示的值(如 undefined 与函数)不产生字符串,而产生 undefined 值。在数组中这些值表示为字符串值 "null";在对象中不可表示的值会使该属性被排除。

Note 6

对象呈现为 U+007B (LEFT CURLY BRACKET) 后跟零个或多个属性,以 U+002C (COMMA) 分隔,以 U+007D (RIGHT CURLY BRACKET) 结束。属性由表示属性名的带引号字符串、一个 U+003A (COLON) 与字符串化的属性值组成。数组呈现为 U+005B (LEFT SQUARE BRACKET) 开头,零个或多个值以 U+002C (COMMA) 分隔,以 U+005D (RIGHT SQUARE BRACKET) 结束。

25.5.2.1 JSON Serialization Record

JSON Serialization Record 是一个 Record 值,用于实现向 JSON 格式的序列化。

JSON Serialization Record 拥有 Table 78 中列出的字段。

Table 78: JSON Serialization Record 字段
字段名 取值 含义
[[ReplacerFunction]] 一个函数对象undefined 可为对象属性提供替换值的函数(来自 JSON.stringify 的 replacer 参数)。
[[PropertyList]] 一个 String 的 Listundefined 序列化非数组对象时包含的属性名(来自 replacer 参数)。
[[Gap]] 一个 String 缩进单元(来自 space 参数)。
[[Stack]] 一个对象的 List 正在序列化的嵌套对象集合,用于检测循环结构。
[[Indent]] 一个 String 当前缩进。

25.5.2.2 SerializeJSONProperty ( state, key, holder )

The abstract operation SerializeJSONProperty takes arguments state (a JSON Serialization Record), key (a String), and holder (an Object) and returns 要么是包含一个 String 或 undefined正常完成要么是抛出完成. It performs the following steps when called:

  1. value 为 ? Get(holder, key)。
  2. value 是 Objectvalue 是 BigInt,则
    1. toJSON 为 ? GetV(value, "toJSON")。
    2. IsCallable(toJSON) 为 true,则
      1. value 为 ? Call(toJSON, value, « key »)。
  3. state.[[ReplacerFunction]] 不为 undefined,则
    1. value 为 ? Call(state.[[ReplacerFunction]], holder, « key, value »)。
  4. value 是 Object,则
    1. value[[NumberData]] 内部槽,则
      1. value 为 ? ToNumber(value)。
    2. 否则若有 [[StringData]] 内部槽,则
      1. value 为 ? ToString(value)。
    3. 否则若有 [[BooleanData]] 内部槽,则
      1. valuevalue.[[BooleanData]]
    4. 否则若有 [[BigIntData]] 内部槽,则
      1. valuevalue.[[BigIntData]]
  5. valuenull,返回 "null"
  6. valuetrue,返回 "true"
  7. valuefalse,返回 "false"
  8. value 为 String,返回 QuoteJSONString(value)。
  9. value 为 Number,则
    1. value 有限,返回 ! ToString(value)。
    2. 返回 "null"
  10. value 为 BigInt,抛出 TypeError 异常。
  11. value 是 ObjectIsCallable(value) 为 false,则
    1. isArray 为 ? IsArray(value)。
    2. isArraytrue,返回 ? SerializeJSONArray(state, value)。
    3. 返回 ? SerializeJSONObject(state, value)。
  12. 返回 undefined

25.5.2.3 QuoteJSONString ( value )

The abstract operation QuoteJSONString takes argument value (a String) and returns a String. 将 value 用 0x0022 (QUOTATION MARK) 代码单元包裹并对其中某些代码单元转义。该操作将 value 视作 UTF-16 编码的代码点序列,详见 6.1.4。 It performs the following steps when called:

  1. product 为仅由代码单元 0x0022 (QUOTATION MARK) 组成的字符串值。
  2. 对 StringToCodePoints(value) 的每个代码点 C,执行
    1. C 列于 Table 79 “Code Point” 列,则
      1. productproduct 与该行 “Escape Sequence” 列中转义序列的连接。
    2. 否则若 C 数值小于 0x0020 (SPACE) 或与某前导代理后导代理数值相同,则
      1. unit 为数值等于 C 数值的代码单元。
      2. productproductUnicodeEscape(unit) 的连接。
    3. 否则,
      1. productproduct 与 UTF16EncodeCodePoint(C) 的连接。
  3. productproduct 与代码单元 0x0022 (QUOTATION MARK) 的连接。
  4. 返回 product
Table 79: JSON 单字符转义序列
Code Point Unicode 字符名称 转义序列
U+0008 BACKSPACE \b
U+0009 CHARACTER TABULATION \t
U+000A LINE FEED (LF) \n
U+000C FORM FEED (FF) \f
U+000D CARRIAGE RETURN (CR) \r
U+0022 QUOTATION MARK \"
U+005C REVERSE SOLIDUS \\

25.5.2.4 UnicodeEscape ( C )

The abstract operation UnicodeEscape takes argument C (a code unit) and returns a String. 以 Unicode 转义序列表示 C。 It performs the following steps when called:

  1. nC 的数值。
  2. 断言:n ≤ 0xFFFF。
  3. hexn 的字符串表示,按小写十六进制格式。
  4. 返回代码单元 0x005C (REVERSE SOLIDUS)、"u"StringPad(hex, 4, "0", start) 的字符串连接。

25.5.2.5 SerializeJSONObject ( state, value )

The abstract operation SerializeJSONObject takes arguments state (a JSON Serialization Record) and value (an Object) and returns 要么是包含一个 String 的正常完成要么是抛出完成. 序列化一个对象。 It performs the following steps when called:

  1. state.[[Stack]] 包含 value,抛出 TypeError 异常(结构循环)。
  2. value 追加到 state.[[Stack]]
  3. stepBackstate.[[Indent]]
  4. state.[[Indent]]state.[[Indent]]state.[[Gap]] 的连接。
  5. state.[[PropertyList]] 不为 undefined,则
    1. Kstate.[[PropertyList]]
  6. 否则,
    1. K 为 ? EnumerableOwnProperties(value, key)。
  7. partial 为新空 List
  8. K 的每个元素 P,执行
    1. strP 为 ? SerializeJSONProperty(state, P, value)。
    2. strP 不为 undefined,则
      1. memberQuoteJSONString(P)。
      2. membermember":" 的连接。
      3. state.[[Gap]] 非空字符串,则
        1. membermember 与代码单元 0x0020 (SPACE) 的连接。
      4. membermemberstrP 的连接。
      5. member 追加到 partial
  9. partial 为空,则
    1. final"{}"
  10. 否则,
    1. state.[[Gap]] 为空字符串,则
      1. properties 为以代码单元 0x002C (COMMA) 分隔连接 partial 中所有元素字符串的结果(不在首尾插入逗号)。
      2. final"{"properties"}" 的连接。
    2. 否则,
      1. separator 为代码单元 0x002C (COMMA)、代码单元 0x000A (LINE FEED) 与 state.[[Indent]] 的连接。
      2. properties 为以 separator 分隔连接 partial 所有元素字符串的结果(不在首尾插入分隔符)。
      3. final"{"、代码单元 0x000A (LINE FEED)、state.[[Indent]]properties、代码单元 0x000A (LINE FEED)、stepBack"}" 的连接。
  11. 移除 state.[[Stack]] 的最后一个元素。
  12. state.[[Indent]]stepBack
  13. 返回 final

25.5.2.6 SerializeJSONArray ( state, value )

The abstract operation SerializeJSONArray takes arguments state (a JSON Serialization Record) and value (an ECMAScript language value) and returns 要么是包含一个 String 的正常完成要么是抛出完成. 序列化一个数组。 It performs the following steps when called:

  1. state.[[Stack]] 包含 value,抛出 TypeError 异常(结构循环)。
  2. value 追加到 state.[[Stack]]
  3. stepBackstate.[[Indent]]
  4. state.[[Indent]]state.[[Indent]]state.[[Gap]] 的连接。
  5. partial 为新空 List
  6. len 为 ? LengthOfArrayLike(value)。
  7. index 为 0。
  8. index < len 重复,
    1. strP 为 ? SerializeJSONProperty(state, ! ToString(𝔽(index)), value)。
    2. strPundefined,则
      1. "null" 追加到 partial
    3. 否则,
      1. strP 追加到 partial
    4. indexindex + 1。
  9. partial 为空,则
    1. final"[]"
  10. 否则,
    1. state.[[Gap]] 为空字符串,则
      1. properties 为以代码单元 0x002C (COMMA) 分隔连接 partial 所有元素字符串的结果(不在首尾插入逗号)。
      2. final"["properties"]" 的连接。
    2. 否则,
      1. separator 为代码单元 0x002C (COMMA)、代码单元 0x000A (LINE FEED) 与 state.[[Indent]] 的连接。
      2. properties 为以 separator 分隔连接 partial 所有元素字符串的结果(不在首尾插入分隔符)。
      3. final"["、代码单元 0x000A (LINE FEED)、state.[[Indent]]properties、代码单元 0x000A (LINE FEED)、stepBack"]" 的连接。
  11. 移除 state.[[Stack]] 的最后一个元素。
  12. state.[[Indent]]stepBack
  13. 返回 final
Note

数组表示仅包含从 +0𝔽(含)到 array.length(不含)的元素。键不是数组索引的属性被排除。数组字符串化为左方括号、元素(以逗号分隔)与右方括号。

25.5.3 JSON [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "JSON"

该属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

26 内存管理(Managing Memory)

26.1 WeakRef 对象

WeakRef 是一种对象,用于引用一个目标对象或 symbol,同时不阻止其被垃圾回收。如果目标尚未被垃圾回收,WeakRef 可以被解引用以访问该目标值。

26.1.1 WeakRef 构造函数

WeakRef 构造函数

  • %WeakRef%
  • 是全局对象 "WeakRef" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 WeakRef。
  • 不应作为普通函数调用;若以此方式调用将抛出异常。
  • 可作为类定义 extends 子句中的值。希望继承指定 WeakRef 行为的子类构造函数必须包含对 WeakRef 构造函数super 调用,以创建并初始化具有支持 WeakRef.prototype 内置方法所需内部状态的子类实例。

26.1.1.1 WeakRef ( target )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 是 undefined,抛出 TypeError 异常。
  2. 如果 CanBeHeldWeakly(target) 为 false,抛出 TypeError 异常。
  3. weakRef 为 ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRef.prototype%", « [[WeakRefTarget]] »)。
  4. 执行 AddToKeptObjects(target)。
  5. weakRef.[[WeakRefTarget]] 设为 target
  6. 返回 weakRef

26.1.2 WeakRef 构造函数的属性

WeakRef 构造函数

26.1.2.1 WeakRef.prototype

WeakRef.prototype 的初始值是 WeakRef 原型对象

该属性的特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

26.1.3 WeakRef 原型对象的属性

WeakRef 原型对象

  • %WeakRef.prototype%
  • 有一个 [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 是一个普通对象
  • 没有 [[WeakRefTarget]] 内部槽。
Normative Optional

26.1.3.1 WeakRef.prototype.constructor

WeakRef.prototype.constructor 的初始值是 %WeakRef%

26.1.3.2 WeakRef.prototype.deref ( )

该方法被调用时执行以下步骤:

  1. weakRefthis 值。
  2. 执行 ? RequireInternalSlot(weakRef, [[WeakRefTarget]])。
  3. 返回 WeakRefDeref(weakRef)。
Note

如果 WeakRef 返回的 target 值不是 undefined,那么该 target 值在当前这次 ECMAScript 代码执行完成之前不应被垃圾回收。AddToKeptObjects 操作用于确保读取一致性。

let target = { foo() {} };
let weakRef = new WeakRef(target);

// ... 稍后 ...

if (weakRef.deref()) {
  weakRef.deref().foo();
}

在上述示例中,如果第一次 deref 的结果不是 undefined,则第二次 deref 的结果也不可能是 undefined

26.1.3.3 WeakRef.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "WeakRef"

该属性的特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

26.1.4 WeakRef 抽象操作

26.1.4.1 WeakRefDeref ( weakRef )

The abstract operation WeakRefDeref takes argument weakRef (a WeakRef) and returns an ECMAScript language value. It performs the following steps when called:

  1. targetweakRef.[[WeakRefTarget]]
  2. 如果 target 不为 empty,则
    1. 执行 AddToKeptObjects(target)。
    2. 返回 target
  3. 返回 undefined
Note

抽象操作与 WeakRef.prototype.deref 分开定义,仅是为了能简洁地定义存活性。

26.1.5 WeakRef 实例的属性

WeakRef 实例是从 WeakRef 原型对象继承属性的普通对象WeakRef 实例还具有 [[WeakRefTarget]] 内部槽。

26.2 FinalizationRegistry 对象

FinalizationRegistry 是一个对象,用于管理目标对象与 symbol 被垃圾回收时执行的清理操作的注册与取消注册。

26.2.1 FinalizationRegistry 构造函数

FinalizationRegistry 构造函数

  • %FinalizationRegistry%
  • 是全局对象 "FinalizationRegistry" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 FinalizationRegistry。
  • 不应作为普通函数调用;若以此方式调用将抛出异常。
  • 可作为类定义 extends 子句中的值。希望继承指定 FinalizationRegistry 行为的子类构造函数必须包含对 FinalizationRegistry 构造函数super 调用,以创建并初始化具有支持 FinalizationRegistry.prototype 内置方法所需内部状态的子类实例。

26.2.1.1 FinalizationRegistry ( cleanupCallback )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 是 undefined,抛出 TypeError 异常。
  2. 如果 IsCallable(cleanupCallback) 为 false,抛出 TypeError 异常。
  3. finalizationRegistry 为 ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationRegistry.prototype%", « [[Realm]], [[CleanupCallback]], [[Cells]] »)。
  4. fn 为活动函数对象
  5. finalizationRegistry.[[Realm]] 设为 fn.[[Realm]]
  6. finalizationRegistry.[[CleanupCallback]] 设为 HostMakeJobCallback(cleanupCallback)。
  7. finalizationRegistry.[[Cells]] 设为一个新的空 List
  8. 返回 finalizationRegistry

26.2.2 FinalizationRegistry 构造函数的属性

FinalizationRegistry 构造函数

26.2.2.1 FinalizationRegistry.prototype

FinalizationRegistry.prototype 的初始值是 FinalizationRegistry 原型对象

该属性的特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

26.2.3 FinalizationRegistry 原型对象的属性

FinalizationRegistry 原型对象

  • %FinalizationRegistry.prototype%
  • 有一个 [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 是一个普通对象
  • 没有 [[Cells]][[CleanupCallback]] 内部槽。

26.2.3.1 FinalizationRegistry.prototype.constructor

FinalizationRegistry.prototype.constructor 的初始值是 %FinalizationRegistry%

26.2.3.2 FinalizationRegistry.prototype.register ( target, heldValue [ , unregisterToken ] )

该方法被调用时执行以下步骤:

  1. finalizationRegistrythis 值。
  2. 执行 ? RequireInternalSlot(finalizationRegistry, [[Cells]])。
  3. 如果 CanBeHeldWeakly(target) 为 false,抛出 TypeError 异常。
  4. 如果 SameValue(target, heldValue) 为 true,抛出 TypeError 异常。
  5. 如果 CanBeHeldWeakly(unregisterToken) 为 false,则
    1. 如果 unregisterToken 不是 undefined,抛出 TypeError 异常。
    2. unregisterToken 设为 empty
  6. cellRecord { [[WeakRefTarget]]: target, [[HeldValue]]: heldValue, [[UnregisterToken]]: unregisterToken }。
  7. cell 追加到 finalizationRegistry.[[Cells]]
  8. 返回 undefined
Note

基于本规范中的算法与定义,当 finalizationRegistry.[[Cells]] 包含 cell 时,cell.[[HeldValue]] 是存活的;然而这并不一定意味着 cell.[[UnregisterToken]]cell.[[Target]] 是存活的。例如,用对象自身作为其注销标记(unregister token)进行注册并不会使该对象永久存活。

26.2.3.3 FinalizationRegistry.prototype.unregister ( unregisterToken )

该方法被调用时执行以下步骤:

  1. finalizationRegistrythis 值。
  2. 执行 ? RequireInternalSlot(finalizationRegistry, [[Cells]])。
  3. 如果 CanBeHeldWeakly(unregisterToken) 为 false,抛出 TypeError 异常。
  4. removedfalse
  5. finalizationRegistry.[[Cells]] 中的每个 Record { [[WeakRefTarget]], [[HeldValue]], [[UnregisterToken]] } cell,执行
    1. 如果 cell.[[UnregisterToken]] 不为 emptySameValue(cell.[[UnregisterToken]], unregisterToken) 为 true,则
      1. finalizationRegistry.[[Cells]] 中移除 cell
      2. removed 设为 true
  6. 返回 removed

26.2.3.4 FinalizationRegistry.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "FinalizationRegistry"

该属性的特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

26.2.4 FinalizationRegistry 实例的属性

FinalizationRegistry 实例是从 FinalizationRegistry 原型对象继承属性的普通对象FinalizationRegistry 实例还具有 [[Cells]][[CleanupCallback]] 内部槽。

27 控制抽象对象

27.1 迭代

27.1.1 通用迭代接口

接口是其关联值符合特定规范的一组属性键。任何对象只要提供了接口规范中描述的全部属性,就符合该接口。一个接口不由单独的对象来表示。可能存在许多独立实现且符合同一接口的对象。单个对象也可以同时符合多个接口。

27.1.1.1 Iterable 接口

iterable interface 包含 Table 80 中描述的属性:

Table 80: Iterable 接口所需属性
属性 要求
%Symbol.iterator% 一个返回迭代器对象的函数 返回的对象必须符合 iterator 接口。

27.1.1.2 Iterator 接口

实现 iterator interface 的对象必须包含 Table 81 中的属性。此类对象也可以实现 Table 82 中的可选属性。

Table 81: Iterator 接口所需属性
属性 要求
"next" 一个返回 IteratorResult 对象的函数 返回的对象必须符合 IteratorResult 接口。如果之前对该迭代器的 next 方法的一次调用返回了 "done" 属性为 true 的 IteratorResult 对象,则后续对此对象的所有 next 调用也应当返回 "done" 属性为 true 的 IteratorResult 对象。然而,该要求不强制执行。
Note 1

可以向 next 函数传递参数,但其含义与合法性取决于目标迭代器。for-of 语句及其他常见迭代器使用者不会传递任何参数,所以期望以这种方式使用的迭代器对象必须准备好在无参数情况下被调用。

Table 82: Iterator 接口可选属性
属性 要求
"return" 一个返回 IteratorResult 对象的函数 返回的对象必须符合 IteratorResult 接口。调用此方法通知迭代器对象调用方不打算再进行任何 next 方法调用。返回的 IteratorResult 对象通常具有 "done" 属性值为 true,并且 "value" 属性为传给 return 方法的参数值。然而,这一要求不强制执行。
"throw" 一个返回 IteratorResult 对象的函数 返回的对象必须符合 IteratorResult 接口。调用此方法通知迭代器对象调用方检测到错误条件。该参数可用于标识错误条件,通常会是一个异常对象。典型响应是 throw 传入的参数值。如果该方法未 throw,返回的 IteratorResult 对象通常具有 "done" 属性值为 true
Note 2

通常这些方法的调用方在调用前应检查其是否存在。包括 for-ofyield* 和数组解构在内的某些 ECMAScript 语言特性会在进行存在性检查后调用这些方法。大多数接受 iterable 对象作为参数的 ECMAScript 库函数也会有条件地调用它们。

27.1.1.3 Async Iterable 接口

async iterable interface 包含 Table 83 中描述的属性:

Table 83: Async Iterable 接口所需属性
属性 要求
%Symbol.asyncIterator% 一个返回 async 迭代器对象的函数 返回的对象必须符合 async iterator 接口。

27.1.1.4 Async Iterator 接口

实现 async iterator interface 的对象必须包含 Table 84 中的属性。此类对象也可以实现 Table 85 中的属性。

Table 84: Async Iterator 接口所需属性
属性 要求
"next" 一个返回 Promise(兑现为 IteratorResult 对象)的函数

返回的 promise 在兑现时,必须以符合 IteratorResult 接口的对象兑现。如果之前对某 async 迭代器的 next 方法的一次调用返回了一个其 "done" 属性为 true 的 IteratorResult 对象的 promise,则后续对该对象的所有 next 调用也应返回 "done" 属性为 true 的 IteratorResult 对象的 promise。然而,该要求不强制执行。

另外,作为兑现值的 IteratorResult 对象的 "value" 属性的值应当不是一个 promise(或 “thenable”)。不过,这一要求同样不强制执行。

Note 1

可以向 next 函数传递参数,但其解释与有效性取决于目标 async 迭代器。for-await-of 语句及其他常见 async 迭代器使用者不会传递任何参数,因此期望这样使用的 async 迭代器对象必须准备好在无参数情况下被调用。

Table 85: Async Iterator 接口可选属性
属性 要求
"return" 一个返回 Promise(兑现为 IteratorResult 对象)的函数

返回的 promise 在兑现时,必须以符合 IteratorResult 接口的对象兑现。调用此方法通知 async 迭代器对象调用方不打算再对该 async 迭代器进行更多 next 调用。返回的 promise 将兑现为 IteratorResult 对象,该对象通常具有 "done" 属性值为 true,以及 "value" 属性为传给 return 方法的参数值。然而,这一要求不强制执行。

另外,作为兑现值的 IteratorResult 对象的 "value" 属性应当不是一个 promise(或 “thenable”)。如果参数值按典型方式使用,且其为一个被拒绝的 promise,则应返回一个以相同原因拒绝的 promise;如果其为一个已兑现的 promise,则其兑现值应作为返回 promise 的 IteratorResult 对象的 "value" 属性。然而,这些要求同样不强制执行。

"throw" 一个返回 Promise(兑现为 IteratorResult 对象)的函数

返回的 promise 在兑现时,必须以符合 IteratorResult 接口的对象兑现。调用此方法通知 async 迭代器对象调用方已检测到错误条件。参数可用于标识该错误条件,并且通常为一个异常对象。典型响应是返回一个以该参数值拒绝的被拒绝 promise。

如果返回的 promise 被兑现,IteratorResult 对象兑现值通常具有 "done" 属性值为 true。此外,它应当具有 "value" 属性,其值不是一个 promise(或 “thenable”),但该要求不强制执行。

Note 2

通常这些方法的调用方在调用前应检查其是否存在。包括 for-await-ofyield* 在内的某些 ECMAScript 语言特性会在进行存在性检查后调用这些方法。

27.1.1.5 IteratorResult 接口

IteratorResult interface 包含 Table 86 中列出的属性:

Table 86: IteratorResult 接口属性
属性 要求
"done" 一个 Boolean 这是迭代器 next 方法调用的结果状态。如果已到达迭代器末尾,"done"true。如果未到达末尾,"done"false 且存在一个可用的值。如果不存在(自有或继承的)"done" 属性,则视为其值为 false
"value" 一个 ECMAScript 语言值 如果 done 为 false,这是当前迭代元素值。如果 done 为 true,这是迭代器的返回值(如果提供)。若迭代器没有返回值,"value"undefined。在此情况下,如果对象未继承显式的 "value" 属性,则可从符合规范的对象中省略该 "value" 属性。

27.1.2 迭代器辅助(Iterator Helper)对象

Iterator Helper object 是一个普通对象,表示对某个特定源迭代器对象的惰性转换。Iterator Helper 对象没有具名构造函数。相反,它们通过调用 Iterator 实例对象的特定方法创建。

27.1.2.1 %IteratorHelperPrototype% 对象

%IteratorHelperPrototype% 对象:

27.1.2.1.1 %IteratorHelperPrototype%.next ( )

  1. Return ? GeneratorResume(this value, undefined, "Iterator Helper").

27.1.2.1.2 %IteratorHelperPrototype%.return ( )

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[UnderlyingIterator]]).
  3. 断言:O 具有 [[GeneratorState]] 内部槽。
  4. O.[[GeneratorState]]suspended-start,则
    1. O.[[GeneratorState]]completed
    2. 注:一旦生成器进入 completed 状态,它将不再离开该状态,且其关联的执行上下文不再被恢复。与 O 关联的任何执行状态此时都可被丢弃。
    3. 执行 ? IteratorClose(O.[[UnderlyingIterator]], NormalCompletion(unused)).
    4. 返回 CreateIteratorResultObject(undefined, true)。
  5. CReturnCompletion(undefined)。
  6. 返回 ? GeneratorResumeAbrupt(O, C, "Iterator Helper").

27.1.2.1.3 %IteratorHelperPrototype% [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串值 "Iterator Helper"

此属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.1.3 迭代器对象

27.1.3.1 Iterator 构造函数

Iterator 构造函数

  • %Iterator%
  • 是全局对象 "Iterator" 属性的初始值。
  • 被设计为可子类化。它可用作类定义的 extends 子句的值。

27.1.3.1.1 Iterator ( )

当调用此函数时,执行以下步骤:

  1. 若 NewTarget 为 undefined 或为活动函数对象,抛出一个 TypeError 异常。
  2. 返回 ? OrdinaryCreateFromConstructor(NewTarget, "%Iterator.prototype%")。

27.1.3.2 Iterator 构造函数的属性

Iterator 构造函数

27.1.3.2.1 Iterator.from ( O )

  1. iteratorRecord 为 ? GetIteratorFlattenable(O, iterate-string-primitives)。
  2. hasInstance 为 ? OrdinaryHasInstance(%Iterator%, iteratorRecord.[[Iterator]])。
  3. hasInstancetrue,则
    1. 返回 iteratorRecord.[[Iterator]]
  4. wrapperOrdinaryObjectCreate(%WrapForValidIteratorPrototype%, « [[Iterated]] »)。
  5. wrapper.[[Iterated]]iteratorRecord
  6. 返回 wrapper

27.1.3.2.1.1 %WrapForValidIteratorPrototype% 对象

%WrapForValidIteratorPrototype% 对象:

27.1.3.2.1.1.1 %WrapForValidIteratorPrototype%.next ( )

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[Iterated]]).
  3. iteratorRecordO.[[Iterated]]
  4. 返回 ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]])。

27.1.3.2.1.1.2 %WrapForValidIteratorPrototype%.return ( )

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[Iterated]]).
  3. iteratorO.[[Iterated]].[[Iterator]]
  4. 断言:iterator 是一个 Object。
  5. returnMethod 为 ? GetMethod(iterator, "return")。
  6. returnMethodundefined,则
    1. 返回 CreateIteratorResultObject(undefined, true)。
  7. 返回 ? Call(returnMethod, iterator)。

27.1.3.2.2 Iterator.prototype

Iterator.prototype 的初始值是 Iterator 原型对象

此属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

27.1.4 Iterator 原型对象的属性

Iterator 原型对象

Note

本规范中所有实现 iterator 接口的对象也都从 %Iterator.prototype% 继承。ECMAScript 代码也可以定义从 %Iterator.prototype% 继承的对象。%Iterator.prototype% 为可对所有迭代器对象适用的额外方法提供一个位置。

以下表达式是 ECMAScript 代码访问 %Iterator.prototype% 对象的一种方式:

Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))

27.1.4.1 Iterator.prototype.constructor

Iterator.prototype.constructor 是一个访问器属性,具有特性 { [[Enumerable]]: false, [[Configurable]]: true }。其 [[Get]][[Set]] 属性定义如下:

27.1.4.1.1 get Iterator.prototype.constructor

[[Get]] 属性的值是一个不需要参数的内置函数。被调用时执行以下步骤:

  1. 返回 %Iterator%

27.1.4.1.2 set Iterator.prototype.constructor

[[Set]] 属性的值是一个接受参数 v 的内置函数。被调用时执行以下步骤:

  1. 执行 ? SetterThatIgnoresPrototypeProperties(this value, %Iterator.prototype%, "constructor", v)。
  2. 返回 undefined
Note

与大多数内置原型上的 "constructor" 属性不同,出于 web 兼容性原因,此属性必须是访问器。

27.1.4.2 Iterator.prototype.drop ( limit )

当调用此方法时,执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是一个 Object,抛出一个 TypeError 异常。
  3. iteratedIterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }。
  4. numLimitCompletion(ToNumber(limit))。
  5. IfAbruptCloseIterator(numLimit, iterated)。
  6. numLimitNaN,则
    1. errorThrowCompletion(一个新建的 RangeError 对象)。
    2. 返回 ? IteratorClose(iterated, error)。
  7. integerLimit 为 ! ToIntegerOrInfinity(numLimit)。
  8. integerLimit < 0,则
    1. errorThrowCompletion(一个新建的 RangeError 对象)。
    2. 返回 ? IteratorClose(iterated, error)。
  9. iterated 为 ? GetIteratorDirect(O)。
  10. closure 为一个新的无参数抽象闭包,捕获 iteratedintegerLimit,调用时执行:
    1. remainingintegerLimit
    2. 重复,当 remaining > 0,
      1. remaining ≠ +∞,则
        1. remainingremaining - 1。
      2. next 为 ? IteratorStep(iterated)。
      3. nextdone,返回 ReturnCompletion(undefined)。
    3. 重复,
      1. value 为 ? IteratorStepValue(iterated)。
      2. valuedone,返回 ReturnCompletion(undefined)。
      3. completionCompletion(Yield(value))。
      4. IfAbruptCloseIterator(completion, iterated)。
  11. resultCreateIteratorFromClosure(closure, "Iterator Helper", %IteratorHelperPrototype%, « [[UnderlyingIterator]] »)。
  12. result.[[UnderlyingIterator]]iterated
  13. 返回 result

27.1.4.3 Iterator.prototype.every ( predicate )

当调用此方法时,执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是一个 Object,抛出一个 TypeError 异常。
  3. iteratedIterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }。
  4. IsCallable(predicate) 为 false,则
    1. errorThrowCompletion(一个新建的 TypeError 对象)。
    2. 返回 ? IteratorClose(iterated, error)。
  5. iterated 为 ? GetIteratorDirect(O)。
  6. counter 为 0。
  7. 重复,
    1. value 为 ? IteratorStepValue(iterated)。
    2. valuedone,返回 true
    3. resultCompletion(Call(predicate, undefined, « value, 𝔽(counter) »))。
    4. IfAbruptCloseIterator(result, iterated)。
    5. ToBoolean(result) 为 false,返回 ? IteratorClose(iterated, NormalCompletion(false))。
    6. countercounter + 1。

27.1.4.4 Iterator.prototype.filter ( predicate )

当调用此方法时,执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是一个 Object,抛出一个 TypeError 异常。
  3. iteratedIterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }。
  4. IsCallable(predicate) 为 false,则
    1. errorThrowCompletion(一个新建的 TypeError 对象)。
    2. 返回 ? IteratorClose(iterated, error)。
  5. iterated 为 ? GetIteratorDirect(O)。
  6. closure 为一个新的无参数抽象闭包,捕获 iteratedpredicate,调用时执行:
    1. counter 为 0。
    2. 重复,
      1. value 为 ? IteratorStepValue(iterated)。
      2. valuedone,返回 ReturnCompletion(undefined)。
      3. selectedCompletion(Call(predicate, undefined, « value, 𝔽(counter) »))。
      4. IfAbruptCloseIterator(selected, iterated)。
      5. ToBoolean(selected) 为 true,则
        1. completionCompletion(Yield(value))。
        2. IfAbruptCloseIterator(completion, iterated)。
      6. countercounter + 1。
  7. resultCreateIteratorFromClosure(closure, "Iterator Helper", %IteratorHelperPrototype%, « [[UnderlyingIterator]] »)。
  8. result.[[UnderlyingIterator]]iterated
  9. 返回 result

27.1.4.5 Iterator.prototype.find ( predicate )

当调用此方法时,执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是一个 Object,抛出一个 TypeError 异常。
  3. iteratedIterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }。
  4. IsCallable(predicate) 为 false,则
    1. errorThrowCompletion(一个新建的 TypeError 对象)。
    2. 返回 ? IteratorClose(iterated, error)。
  5. iterated 为 ? GetIteratorDirect(O)。
  6. counter 为 0。
  7. 重复,
    1. value 为 ? IteratorStepValue(iterated)。
    2. valuedone,返回 undefined
    3. resultCompletion(Call(predicate, undefined, « value, 𝔽(counter) »))。
    4. IfAbruptCloseIterator(result, iterated)。
    5. ToBoolean(result) 为 true,返回 ? IteratorClose(iterated, NormalCompletion(value))。
    6. countercounter + 1。

27.1.4.6 Iterator.prototype.flatMap ( mapper )

当调用此方法时,执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是一个 Object,抛出一个 TypeError 异常。
  3. iteratedIterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }。
  4. IsCallable(mapper) 为 false,则
    1. errorThrowCompletion(一个新建的 TypeError 对象)。
    2. 返回 ? IteratorClose(iterated, error)。
  5. iterated 为 ? GetIteratorDirect(O)。
  6. closure 为一个新的无参数抽象闭包,捕获 iteratedmapper,调用时执行:
    1. counter 为 0。
    2. 重复,
      1. value 为 ? IteratorStepValue(iterated)。
      2. valuedone,返回 ReturnCompletion(undefined)。
      3. mappedCompletion(Call(mapper, undefined, « value, 𝔽(counter) »))。
      4. IfAbruptCloseIterator(mapped, iterated)。
      5. innerIteratorCompletion(GetIteratorFlattenable(mapped, reject-primitives))。
      6. IfAbruptCloseIterator(innerIterator, iterated)。
      7. innerAlivetrue
      8. 重复,当 innerAlivetrue
        1. innerValueCompletion(IteratorStepValue(innerIterator))。
        2. IfAbruptCloseIterator(innerValue, iterated)。
        3. innerValuedone,则
          1. innerAlivefalse
        4. 否则,
          1. completionCompletion(Yield(innerValue))。
          2. completion 是一个 abrupt completion,则
            1. backupCompletionCompletion(IteratorClose(innerIterator, completion))。
            2. IfAbruptCloseIterator(backupCompletion, iterated)。
            3. 返回 ? IteratorClose(iterated, completion)。
      9. countercounter + 1。
  7. resultCreateIteratorFromClosure(closure, "Iterator Helper", %IteratorHelperPrototype%, « [[UnderlyingIterator]] »)。
  8. result.[[UnderlyingIterator]]iterated
  9. 返回 result

27.1.4.7 Iterator.prototype.forEach ( procedure )

当调用此方法时,执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是一个 Object,抛出一个 TypeError 异常。
  3. iteratedIterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }。
  4. IsCallable(procedure) 为 false,则
    1. errorThrowCompletion(一个新建的 TypeError 对象)。
    2. 返回 ? IteratorClose(iterated, error)。
  5. iterated 为 ? GetIteratorDirect(O)。
  6. counter 为 0。
  7. 重复,
    1. value 为 ? IteratorStepValue(iterated)。
    2. valuedone,返回 undefined
    3. resultCompletion(Call(procedure, undefined, « value, 𝔽(counter) »))。
    4. IfAbruptCloseIterator(result, iterated)。
    5. countercounter + 1。

27.1.4.8 Iterator.prototype.map ( mapper )

当调用此方法时,执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是一个 Object,抛出一个 TypeError 异常。
  3. iteratedIterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }。
  4. IsCallable(mapper) 为 false,则
    1. errorThrowCompletion(一个新建的 TypeError 对象)。
    2. 返回 ? IteratorClose(iterated, error)。
  5. iterated 为 ? GetIteratorDirect(O)。
  6. closure 为一个新的无参数抽象闭包,捕获 iteratedmapper,调用时执行:
    1. counter 为 0。
    2. 重复,
      1. value 为 ? IteratorStepValue(iterated)。
      2. valuedone,返回 ReturnCompletion(undefined)。
      3. mappedCompletion(Call(mapper, undefined, « value, 𝔽(counter) »))。
      4. IfAbruptCloseIterator(mapped, iterated)。
      5. completionCompletion(Yield(mapped))。
      6. IfAbruptCloseIterator(completion, iterated)。
      7. countercounter + 1。
  7. resultCreateIteratorFromClosure(closure, "Iterator Helper", %IteratorHelperPrototype%, « [[UnderlyingIterator]] »)。
  8. result.[[UnderlyingIterator]]iterated
  9. 返回 result

27.1.4.9 Iterator.prototype.reduce ( reducer [ , initialValue ] )

当调用此方法时,执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是一个 Object,抛出一个 TypeError 异常。
  3. iteratedIterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }。
  4. IsCallable(reducer) 为 false,则
    1. errorThrowCompletion(一个新建的 TypeError 对象)。
    2. 返回 ? IteratorClose(iterated, error)。
  5. iterated 为 ? GetIteratorDirect(O)。
  6. initialValue 不存在,则
    1. accumulator 为 ? IteratorStepValue(iterated)。
    2. accumulatordone,抛出一个 TypeError 异常。
    3. counter 为 1。
  7. 否则,
    1. accumulatorinitialValue
    2. counter 为 0。
  8. 重复,
    1. value 为 ? IteratorStepValue(iterated)。
    2. valuedone,返回 accumulator
    3. resultCompletion(Call(reducer, undefined, « accumulator, value, 𝔽(counter) »))。
    4. IfAbruptCloseIterator(result, iterated)。
    5. accumulatorresult
    6. countercounter + 1。

27.1.4.10 Iterator.prototype.some ( predicate )

当调用此方法时,执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是一个 Object,抛出一个 TypeError 异常。
  3. iteratedIterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }。
  4. IsCallable(predicate) 为 false,则
    1. errorThrowCompletion(一个新建的 TypeError 对象)。
    2. 返回 ? IteratorClose(iterated, error)。
  5. iterated 为 ? GetIteratorDirect(O)。
  6. counter 为 0。
  7. 重复,
    1. value 为 ? IteratorStepValue(iterated)。
    2. valuedone,返回 false
    3. resultCompletion(Call(predicate, undefined, « value, 𝔽(counter) »))。
    4. IfAbruptCloseIterator(result, iterated)。
    5. ToBoolean(result) 为 true,返回 ? IteratorClose(iterated, NormalCompletion(true))。
    6. countercounter + 1。

27.1.4.11 Iterator.prototype.take ( limit )

当调用此方法时,执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是一个 Object,抛出一个 TypeError 异常。
  3. iteratedIterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }。
  4. numLimitCompletion(ToNumber(limit))。
  5. IfAbruptCloseIterator(numLimit, iterated)。
  6. numLimitNaN,则
    1. errorThrowCompletion(一个新建的 RangeError 对象)。
    2. 返回 ? IteratorClose(iterated, error)。
  7. integerLimit 为 ! ToIntegerOrInfinity(numLimit)。
  8. integerLimit < 0,则
    1. errorThrowCompletion(一个新建的 RangeError 对象)。
    2. 返回 ? IteratorClose(iterated, error)。
  9. iterated 为 ? GetIteratorDirect(O)。
  10. closure 为一个新的无参数抽象闭包,捕获 iteratedintegerLimit,调用时执行:
    1. remainingintegerLimit
    2. 重复,
      1. remaining = 0,则
        1. 返回 ? IteratorClose(iterated, ReturnCompletion(undefined))。
      2. remaining ≠ +∞,则
        1. remainingremaining - 1。
      3. value 为 ? IteratorStepValue(iterated)。
      4. valuedone,返回 ReturnCompletion(undefined)。
      5. completionCompletion(Yield(value))。
      6. IfAbruptCloseIterator(completion, iterated)。
  11. resultCreateIteratorFromClosure(closure, "Iterator Helper", %IteratorHelperPrototype%, « [[UnderlyingIterator]] »)。
  12. result.[[UnderlyingIterator]]iterated
  13. 返回 result

27.1.4.12 Iterator.prototype.toArray ( )

当调用此方法时,执行以下步骤:

  1. Othis 值。
  2. 如果 O 不是一个 Object,抛出一个 TypeError 异常。
  3. iterated 为 ? GetIteratorDirect(O)。
  4. items 为一个新的空 List
  5. 重复,
    1. value 为 ? IteratorStepValue(iterated)。
    2. valuedone,返回 CreateArrayFromList(items)。
    3. value 追加至 items

27.1.4.13 Iterator.prototype [ %Symbol.iterator% ] ( )

当调用此函数时,执行以下步骤:

  1. 返回 this 值。

此函数 "name" 属性的值为 "[Symbol.iterator]"

27.1.4.14 Iterator.prototype [ %Symbol.toStringTag% ]

Iterator.prototype[%Symbol.toStringTag%] 是一个访问器属性,具有特性 { [[Enumerable]]: false, [[Configurable]]: true }。其 [[Get]][[Set]] 属性定义如下:

27.1.4.14.1 get Iterator.prototype [ %Symbol.toStringTag% ]

[[Get]] 属性的值是一个不需要参数的内置函数。被调用时执行以下步骤:

  1. 返回 "Iterator"

27.1.4.14.2 set Iterator.prototype [ %Symbol.toStringTag% ]

[[Set]] 属性的值是一个接受参数 v 的内置函数。被调用时执行以下步骤:

  1. 执行 ? SetterThatIgnoresPrototypeProperties(this value, %Iterator.prototype%, %Symbol.toStringTag%, v)。
  2. 返回 undefined
Note

与大多数内置原型上的 %Symbol.toStringTag% 属性不同,出于 web 兼容性原因,此属性必须是访问器。

27.1.5 %AsyncIteratorPrototype% 对象

%AsyncIteratorPrototype% 对象:

Note

本规范中所有实现 async iterator 接口的对象也都从 %AsyncIteratorPrototype% 继承。ECMAScript 代码也可以定义从 %AsyncIteratorPrototype% 继承的对象。%AsyncIteratorPrototype% 对象为可对所有 async 迭代器对象适用的额外方法提供一个位置。

27.1.5.1 %AsyncIteratorPrototype% [ %Symbol.asyncIterator% ] ( )

当调用此函数时,执行以下步骤:

  1. 返回 this 值。

此函数 "name" 属性的值为 "[Symbol.asyncIterator]"

27.1.6 Async-from-Sync 迭代器对象

Async-from-Sync Iterator object 是一个将特定同步迭代器适配为 async 迭代器的对象。Async-from-Sync Iterator 对象永远不会被 ECMAScript 代码直接访问。它们没有具名构造函数,而是按需通过 CreateAsyncFromSyncIterator 抽象操作创建。

27.1.6.1 CreateAsyncFromSyncIterator ( syncIteratorRecord )

The abstract operation CreateAsyncFromSyncIterator takes argument syncIteratorRecord (an Iterator Record) and returns an Iterator Record. 用于从一个同步 Iterator Record 创建一个 async Iterator Record。 It performs the following steps when called:

  1. asyncIteratorOrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »)。
  2. asyncIterator.[[SyncIteratorRecord]]syncIteratorRecord
  3. nextMethod 为 ! Get(asyncIterator, "next")。
  4. iteratorRecordIterator Record { [[Iterator]]: asyncIterator, [[NextMethod]]: nextMethod, [[Done]]: false }。
  5. 返回 iteratorRecord

27.1.6.2 %AsyncFromSyncIteratorPrototype% 对象

%AsyncFromSyncIteratorPrototype% 对象:

  • 具有所有 Async-from-Sync Iterator 对象继承的属性。
  • 是一个普通对象
  • 具有一个 [[Prototype]] 内部槽,其值为 %AsyncIteratorPrototype%
  • 永远不会被 ECMAScript 代码直接访问。
  • 具有以下属性:

27.1.6.2.1 %AsyncFromSyncIteratorPrototype%.next ( [ value ] )

  1. Othis 值。
  2. 断言:O 是一个具有 [[SyncIteratorRecord]] 内部槽的 Object。
  3. promiseCapability 为 ! NewPromiseCapability(%Promise%)。
  4. syncIteratorRecordO.[[SyncIteratorRecord]]
  5. value 存在,则
    1. resultCompletion(IteratorNext(syncIteratorRecord, value))。
  6. 否则,
    1. resultCompletion(IteratorNext(syncIteratorRecord))。
  7. IfAbruptRejectPromise(result, promiseCapability)。
  8. 返回 AsyncFromSyncIteratorContinuation(result, promiseCapability, syncIteratorRecord, true)。

27.1.6.2.2 %AsyncFromSyncIteratorPrototype%.return ( [ value ] )

  1. Othis 值。
  2. 断言:O 是一个具有 [[SyncIteratorRecord]] 内部槽的 Object。
  3. promiseCapability 为 ! NewPromiseCapability(%Promise%)。
  4. syncIteratorRecordO.[[SyncIteratorRecord]]
  5. syncIteratorsyncIteratorRecord.[[Iterator]]
  6. returnCompletion(GetMethod(syncIterator, "return")).
  7. IfAbruptRejectPromise(return, promiseCapability)。
  8. returnundefined,则
    1. iteratorResultCreateIteratorResultObject(value, true)。
    2. 执行 ! Call(promiseCapability.[[Resolve]], undefined, « iteratorResult »)。
    3. 返回 promiseCapability.[[Promise]]
  9. value 存在,则
    1. resultCompletion(Call(return, syncIterator, « value »))。
  10. 否则,
    1. resultCompletion(Call(return, syncIterator))。
  11. IfAbruptRejectPromise(result, promiseCapability)。
  12. result 不是一个 Object,则
    1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « 一个新建的 TypeError 对象 »)。
    2. 返回 promiseCapability.[[Promise]]
  13. 返回 AsyncFromSyncIteratorContinuation(result, promiseCapability, syncIteratorRecord, false)。

27.1.6.2.3 %AsyncFromSyncIteratorPrototype%.throw ( [ value ] )

Note
在本规范中,value 总是被提供,但为与 %AsyncFromSyncIteratorPrototype%.return ( [ value ] ) 保持一致而保留为可选。
  1. Othis 值。
  2. 断言:O 是一个具有 [[SyncIteratorRecord]] 内部槽的 Object。
  3. promiseCapability 为 ! NewPromiseCapability(%Promise%)。
  4. syncIteratorRecordO.[[SyncIteratorRecord]]
  5. syncIteratorsyncIteratorRecord.[[Iterator]]
  6. throwCompletion(GetMethod(syncIterator, "throw"))。
  7. IfAbruptRejectPromise(throw, promiseCapability)。
  8. throwundefined,则
    1. 注:如果 syncIterator 没有 throw 方法,在我们拒绝该 capability 前关闭它以便其有机会清理。
    2. closeCompletionNormalCompletion(empty)。
    3. resultCompletion(IteratorClose(syncIteratorRecord, closeCompletion))。
    4. IfAbruptRejectPromise(result, promiseCapability)。
    5. 注:下一步抛出一个 TypeError 以指示存在协议违规:syncIterator 没有 throw 方法。
    6. 注:如果关闭 syncIterator 不抛出,则忽略该操作的结果,即使其产生了一个被拒绝的 promise。
    7. 执行 ! Call(promiseCapability.[[Reject]], undefined, « 一个新建的 TypeError 对象 »)。
    8. 返回 promiseCapability.[[Promise]]
  9. value 存在,则
    1. resultCompletion(Call(throw, syncIterator, « value »))。
  10. 否则,
    1. resultCompletion(Call(throw, syncIterator))。
  11. IfAbruptRejectPromise(result, promiseCapability)。
  12. result 不是一个 Object,则
    1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « 一个新建的 TypeError 对象 »)。
    2. 返回 promiseCapability.[[Promise]]
  13. 返回 AsyncFromSyncIteratorContinuation(result, promiseCapability, syncIteratorRecord, true)。

27.1.6.3 Async-from-Sync 迭代器实例的属性

Async-from-Sync 迭代器实例是从 %AsyncFromSyncIteratorPrototype% 内在对象继承属性的普通对象。它们最初以 Table 87 中列出的内部槽创建。

Table 87: Async-from-Sync 迭代器实例的内部槽
内部槽 类型 描述
[[SyncIteratorRecord]] an Iterator Record 表示正在被适配的原始同步迭代器。

27.1.6.4 AsyncFromSyncIteratorContinuation ( result, promiseCapability, syncIteratorRecord, closeOnRejection )

The abstract operation AsyncFromSyncIteratorContinuation takes arguments result (an Object), promiseCapability (a PromiseCapability Record for an intrinsic %Promise%), syncIteratorRecord (an Iterator Record), and closeOnRejection (a Boolean) and returns a Promise. It performs the following steps when called:

  1. 注:由于 promiseCapability 来自内在 %Promise%,下面使用 IfAbruptRejectPromise 所导致对 promiseCapability.[[Reject]] 的调用保证不会抛出。
  2. doneCompletion(IteratorComplete(result))。
  3. IfAbruptRejectPromise(done, promiseCapability)。
  4. valueCompletion(IteratorValue(result))。
  5. IfAbruptRejectPromise(value, promiseCapability)。
  6. valueWrapperCompletion(PromiseResolve(%Promise%, value))。
  7. valueWrapper 是一个 abrupt completion,donefalse,且 closeOnRejectiontrue,则
    1. valueWrapperCompletion(IteratorClose(syncIteratorRecord, valueWrapper))。
  8. IfAbruptRejectPromise(valueWrapper, promiseCapability)。
  9. unwrap 为一个新的具有参数 (v) 且捕获 done 的抽象闭包,调用时执行:
    1. 返回 CreateIteratorResultObject(v, done)。
  10. onFulfilledCreateBuiltinFunction(unwrap, 1, "", « »)。
  11. 注:onFulfilled 用于处理 IteratorResult 对象的 "value" 属性,以便在其值为 promise 时等待,并将结果重新打包为一个新的“解包后的” IteratorResult 对象。
  12. donetrue,或 closeOnRejectionfalse,则
    1. onRejectedundefined
  13. 否则,
    1. closeIterator 为一个新的具有参数 (error) 且捕获 syncIteratorRecord 的抽象闭包,调用时执行:
      1. 返回 ? IteratorClose(syncIteratorRecord, ThrowCompletion(error))。
    2. onRejectedCreateBuiltinFunction(closeIterator, 1, "", « »)。
    3. 注:onRejected 用于在其产生的 IteratorResult 对象的 "value" 属性为一个被拒绝的 promise 时关闭迭代器。
  14. 执行 PerformPromiseThen(valueWrapper, onFulfilled, onRejected, promiseCapability)。
  15. 返回 promiseCapability.[[Promise]]

27.2 Promise 对象

Promise 是一个对象,用作延迟(且可能是异步)计算最终结果的占位符。

任一 Promise 处于三个互斥状态之一:fulfilledrejectedpending

  • 当对一个 promise p 执行 p.then(f, r) 会立即入列一个调用函数 f 的 Job 时,p 为 fulfilled。
  • 当对一个 promise p 执行 p.then(f, r) 会立即入列一个调用函数 r 的 Job 时,p 为 rejected。
  • 当一个 promise 既不是 fulfilled 也不是 rejected 时,它是 pending。

若一个 promise 不是 pending(即已 fulfilled 或 rejected),则称其为 settled

一个 promise 若已 settled 或被“锁定”与另一个 promise 的状态匹配,则称其为 resolved。试图 resolve 或 reject 一个已 resolved 的 promise 不产生任何效果。一个 promise 若未 resolved 则为 unresolved。未 resolved 的 promise 始终处于 pending 状态。一个已 resolved 的 promise 可能是 pending、fulfilled 或 rejected。

27.2.1 Promise 抽象操作

27.2.1.1 PromiseCapability 记录

PromiseCapability Record 是一个 Record 值,用来封装一个 Promise 或类 Promise 对象及其可用于 resolve 或 reject 该 promise 的函数。PromiseCapability 记录由 NewPromiseCapability 抽象操作产生。

PromiseCapability 记录具有 Table 88 中列出的字段。

Table 88: PromiseCapability Record 字段
字段名 含义
[[Promise]] 一个 Object 可用作 promise 的对象。
[[Resolve]] 一个函数对象 用于 resolve 给定 promise 的函数。
[[Reject]] 一个函数对象 用于 reject 给定 promise 的函数。

27.2.1.1.1 IfAbruptRejectPromise ( value, capability )

IfAbruptRejectPromise 是一组使用 PromiseCapability Record 的算法步骤的简写。形如:

  1. IfAbruptRejectPromise(value, capability)。

等价于:

  1. 断言:value 是一个 Completion Record
  2. value 是一个 abrupt completion,则
    1. 执行 ? Call(capability.[[Reject]], undefined, « value.[[Value]] »)。
    2. 返回 capability.[[Promise]]
  3. 否则,
    1. value 为 ! value

27.2.1.2 PromiseReaction 记录

PromiseReaction Record 是一个 Record 值,用来存储当 promise 以给定值 resolved 或 rejected 时应如何响应的信息。PromiseReaction 记录由 PerformPromiseThen 抽象操作创建,并由 NewPromiseReactionJob 返回的抽象闭包使用。

PromiseReaction 记录具有 Table 89 中列出的字段。

Table 89: PromiseReaction Record 字段
字段名 含义
[[Capability]] 一个 PromiseCapability Recordundefined 该记录为其提供 reaction 处理器的 promise 的能力集合。
[[Type]] fulfillreject [[Handler]]empty 时用于区分针对不同完成类型的行为。
[[Handler]] 一个 JobCallback Recordempty 应对传入值执行的函数,其返回值决定派生 promise 的后续行为。若 [[Handler]]empty,则基于 [[Type]] 的函数将被使用。

27.2.1.3 CreateResolvingFunctions ( promise )

The abstract operation CreateResolvingFunctions takes argument promise (a Promise) and returns 一个具有字段 [[Resolve]] (函数对象) 与 [[Reject]] (函数对象) 的 Record. It performs the following steps when called:

  1. alreadyResolvedRecord { [[Value]]: false }。
  2. stepsResolvePromise Resolve 函数 中定义的算法步骤。
  3. lengthResolvePromise Resolve 函数 中函数定义的非可选参数数量。
  4. resolveCreateBuiltinFunction(stepsResolve, lengthResolve, "", « [[Promise]], [[AlreadyResolved]] »)。
  5. resolve.[[Promise]]promise
  6. resolve.[[AlreadyResolved]]alreadyResolved
  7. stepsRejectPromise Reject 函数 中定义的算法步骤。
  8. lengthRejectPromise Reject 函数 中函数定义的非可选参数数量。
  9. rejectCreateBuiltinFunction(stepsReject, lengthReject, "", « [[Promise]], [[AlreadyResolved]] »)。
  10. reject.[[Promise]]promise
  11. reject.[[AlreadyResolved]]alreadyResolved
  12. 返回 Record { [[Resolve]]: resolve, [[Reject]]: reject }。

27.2.1.3.1 Promise Reject 函数

Promise reject 函数是一个匿名内置函数,具有 [[Promise]][[AlreadyResolved]] 内部槽。

当以参数 reason 调用一个 promise reject 函数时,执行以下步骤:

  1. F 为活动函数对象
  2. 断言:F 具有一个值为 Object 的 [[Promise]] 内部槽。
  3. promiseF.[[Promise]]
  4. alreadyResolvedF.[[AlreadyResolved]]
  5. alreadyResolved.[[Value]]true,返回 undefined
  6. alreadyResolved.[[Value]]true
  7. 执行 RejectPromise(promise, reason)。
  8. 返回 undefined

Promise reject 函数的 "length" 属性为 1𝔽

27.2.1.3.2 Promise Resolve 函数

Promise resolve 函数是一个匿名内置函数,具有 [[Promise]][[AlreadyResolved]] 内部槽。

当以参数 resolution 调用一个 promise resolve 函数时,执行以下步骤:

  1. F 为活动函数对象
  2. 断言:F 具有一个值为 Object 的 [[Promise]] 内部槽。
  3. promiseF.[[Promise]]
  4. alreadyResolvedF.[[AlreadyResolved]]
  5. alreadyResolved.[[Value]]true,返回 undefined
  6. alreadyResolved.[[Value]]true
  7. SameValue(resolution, promise) 为 true,则
    1. selfResolutionError 为一个新建的 TypeError 对象。
    2. 执行 RejectPromise(promise, selfResolutionError)。
    3. 返回 undefined
  8. resolution 不是一个 Object,则
    1. 执行 FulfillPromise(promise, resolution)。
    2. 返回 undefined
  9. thenCompletion(Get(resolution, "then"))。
  10. then 是一个 abrupt completion,则
    1. 执行 RejectPromise(promise, then.[[Value]])。
    2. 返回 undefined
  11. thenActionthen.[[Value]]
  12. IsCallable(thenAction) 为 false,则
    1. 执行 FulfillPromise(promise, resolution)。
    2. 返回 undefined
  13. thenJobCallbackHostMakeJobCallback(thenAction)。
  14. jobNewPromiseResolveThenableJob(promise, resolution, thenJobCallback)。
  15. 执行 HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]])。
  16. 返回 undefined

Promise resolve 函数的 "length" 属性为 1𝔽

27.2.1.4 FulfillPromise ( promise, value )

The abstract operation FulfillPromise takes arguments promise (a Promise) and value (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. 断言:promise.[[PromiseState]]pending
  2. reactionspromise.[[PromiseFulfillReactions]]
  3. promise.[[PromiseResult]]value
  4. promise.[[PromiseFulfillReactions]]undefined
  5. promise.[[PromiseRejectReactions]]undefined
  6. promise.[[PromiseState]]fulfilled
  7. 执行 TriggerPromiseReactions(reactions, value)。
  8. 返回 unused

27.2.1.5 NewPromiseCapability ( C )

The abstract operation NewPromiseCapability takes argument C (an ECMAScript language value) and returns 正常完成(含一个 PromiseCapability Record)或抛出完成. 尝试以与内置 Promise 构造函数相同的方式使用 C 作为构造器来创建一个 promise,并提取其 resolvereject 函数。该 promise 及其 resolvereject 函数用于初始化一个新的 PromiseCapability Record。 It performs the following steps when called:

  1. IsConstructor(C) 为 false,抛出一个 TypeError 异常。
  2. 注:假定 C 是一个支持 Promise 构造函数参数约定的构造函数(见 27.2.3.1)。
  3. resolvingFunctionsRecord { [[Resolve]]: undefined, [[Reject]]: undefined }。
  4. executorClosure 为一个具有参数 (resolve, reject) 且捕获 resolvingFunctions 的新抽象闭包,调用时执行:
    1. resolvingFunctions.[[Resolve]] 不为 undefined,抛出一个 TypeError 异常。
    2. resolvingFunctions.[[Reject]] 不为 undefined,抛出一个 TypeError 异常。
    3. resolvingFunctions.[[Resolve]]resolve
    4. resolvingFunctions.[[Reject]]reject
    5. 返回 NormalCompletion(undefined)。
  5. executorCreateBuiltinFunction(executorClosure, 2, "", « »)。
  6. promise 为 ? Construct(C, « executor »)。
  7. IsCallable(resolvingFunctions.[[Resolve]]) 为 false,抛出一个 TypeError 异常。
  8. IsCallable(resolvingFunctions.[[Reject]]) 为 false,抛出一个 TypeError 异常。
  9. 返回 PromiseCapability Record { [[Promise]]: promise, [[Resolve]]: resolvingFunctions.[[Resolve]], [[Reject]]: resolvingFunctions.[[Reject]] }。
Note

抽象操作支持 Promise 子类化,因为它对任何以与 Promise 构造函数相同方式调用传入 executor 函数参数的构造器都是通用的。它用于将 Promise 构造函数的静态方法泛化到任意子类。

27.2.1.6 IsPromise ( x )

The abstract operation IsPromise takes argument x (an ECMAScript language value) and returns 一个 Boolean. 检查对象上是否具有 promise 品牌标记。 It performs the following steps when called:

  1. x 不是一个 Object,返回 false
  2. x 不具有 [[PromiseState]] 内部槽,返回 false
  3. 返回 true

27.2.1.7 RejectPromise ( promise, reason )

The abstract operation RejectPromise takes arguments promise (a Promise) and reason (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. 断言:promise.[[PromiseState]]pending
  2. reactionspromise.[[PromiseRejectReactions]]
  3. promise.[[PromiseResult]]reason
  4. promise.[[PromiseFulfillReactions]]undefined
  5. promise.[[PromiseRejectReactions]]undefined
  6. promise.[[PromiseState]]rejected
  7. promise.[[PromiseIsHandled]]false,执行 HostPromiseRejectionTracker(promise, "reject")。
  8. 执行 TriggerPromiseReactions(reactions, reason)。
  9. 返回 unused

27.2.1.8 TriggerPromiseReactions ( reactions, argument )

The abstract operation TriggerPromiseReactions takes arguments reactions (a List of PromiseReaction Records) and argument (an ECMAScript language value) and returns unused. 为 reactions 中的每个记录入列一个新的 Job。每个这样的 Job 处理该 PromiseReaction Record[[Type]][[Handler]],若 [[Handler]] 不是 empty,则以给定参数调用它。若 [[Handler]]empty,行为由 [[Type]] 决定。 It performs the following steps when called:

  1. 对于 reactions 的每个元素 reaction,执行
    1. jobNewPromiseReactionJob(reaction, argument)。
    2. 执行 HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]])。
  2. 返回 unused

27.2.1.9 HostPromiseRejectionTracker ( promise, operation )

The host-defined abstract operation HostPromiseRejectionTracker takes arguments promise (a Promise) and operation ("reject" or "handle") and returns unused. 允许宿主环境追踪 promise 拒绝。

HostPromiseRejectionTracker 的默认实现是返回 unused

Note 1

HostPromiseRejectionTracker 在两种场景被调用:

  • 当一个 promise 在没有任何处理器的情况下被拒绝时,以 operation 参数为 "reject" 调用。
  • 当首次向一个已拒绝的 promise 添加处理器时,以 operation 参数为 "handle" 调用。

一个典型实现可能尝试通知开发者未处理的拒绝,同时在随后新处理器附加使先前通知失效时再次适当通知。

Note 2

operation"handle",实现不应以影响垃圾回收的方式持有对 promise 的引用。若 operation"reject",实现可以持有引用,因为预期拒绝是少见且不在热点路径上。

27.2.2 Promise 作业

27.2.2.1 NewPromiseReactionJob ( reaction, argument )

The abstract operation NewPromiseReactionJob takes arguments reaction (一个 PromiseReaction Record,) and argument (一个 ECMAScript 语言值) and returns 一个具有字段 [[Job]] (一个 Job 抽象闭包) 和 [[Realm]] (一个 Realm Recordnull) 的 Record. 返回一个新的 Job 抽象闭包,该闭包对传入的值应用合适的处理器,并使用该处理器的返回值来根据该处理器关联的派生 promise 进行 resolve 或 reject。 It performs the following steps when called:

  1. job 为一个无参数的新 Job 抽象闭包,捕获 reactionargument,在被调用时执行下列步骤:
    1. promiseCapabilityreaction.[[Capability]]
    2. typereaction.[[Type]]
    3. handlerreaction.[[Handler]]
    4. 如果 handlerempty,则
      1. 如果 typefulfill,则
        1. handlerResultNormalCompletion(argument)。
      2. 否则,
        1. 断言:typereject
        2. handlerResultThrowCompletion(argument)。
    5. 否则,
      1. handlerResultCompletion(HostCallJobCallback(handler, undefined, « argument »))。
    6. 如果 promiseCapabilityundefined,则
      1. 断言:handlerResult 不是一个 abrupt completion。
      2. 返回 empty
    7. 断言:promiseCapability 是一个 PromiseCapability Record
    8. 如果 handlerResult 是一个 abrupt completion,则
      1. 返回 ? Call(promiseCapability.[[Reject]], undefined, « handlerResult.[[Value]] »)。
    9. 否则,
      1. 返回 ? Call(promiseCapability.[[Resolve]], undefined, « handlerResult.[[Value]] »)。
  2. handlerRealmnull
  3. 如果 reaction.[[Handler]] 不为 empty,则
    1. getHandlerRealmResultCompletion(GetFunctionRealm(reaction.[[Handler]].[[Callback]]))。
    2. 如果 getHandlerRealmResult 是一个 normal completion,则将 handlerRealm 设为 getHandlerRealmResult.[[Value]]
    3. 否则,将 handlerRealm 设为当前 Realm Record
    4. 注:除非处理器是 undefined,否则 handlerRealm 永不为 null。当处理器是已撤销的 Proxy 且没有 ECMAScript 代码运行时,handlerRealm 用来创建错误对象。
  4. 返回 Record { [[Job]]: job, [[Realm]]: handlerRealm }。

27.2.2.2 NewPromiseResolveThenableJob ( promiseToResolve, thenable, then )

The abstract operation NewPromiseResolveThenableJob takes arguments promiseToResolve (一个 Promise), thenable (一个 Object), and then (一个 JobCallback Record) and returns 一个具有字段 [[Job]] (一个 Job 抽象闭包) 和 [[Realm]] (一个 Realm Record) 的 Record. It performs the following steps when called:

  1. job 为一个无参数的新 Job 抽象闭包,捕获 promiseToResolve, thenable, 以及 then,在被调用时执行下列步骤:
    1. resolvingFunctionsCreateResolvingFunctions(promiseToResolve)。
    2. thenCallResultCompletion(HostCallJobCallback(then, thenable, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »))。
    3. 如果 thenCallResult 是一个 abrupt completion,则
      1. 返回 ? Call(resolvingFunctions.[[Reject]], undefined, « thenCallResult.[[Value]] »)。
    4. 返回 ! thenCallResult
  2. getThenRealmResultCompletion(GetFunctionRealm(then.[[Callback]]))。
  3. 如果 getThenRealmResult 是一个 normal completion,令 thenRealmgetThenRealmResult.[[Value]]
  4. 否则,令 thenRealm当前 Realm Record
  5. 注:thenRealm 永不为 null。当 then.[[Callback]] 是一个已撤销的 Proxy 且无代码运行时,thenRealm 用于创建错误对象。
  6. 返回 Record { [[Job]]: job, [[Realm]]: thenRealm }。
Note

该作业使用提供的 thenable 及其 then 方法来 resolve 给定的 promise。此过程必须作为一个 Job 进行,以确保对 then 方法的求值发生在任意外围代码求值完成之后。

27.2.3 Promise 构造函数

Promise 构造函数

  • %Promise%
  • 是全局对象 "Promise" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 Promise。
  • 不应作为普通函数调用,若以那种方式调用将抛出异常。
  • 可用作类定义中 extends 子句的值。意图继承指定 Promise 行为的子类构造函数必须包含对 Promise 构造函数super 调用,以使用支持 PromisePromise.prototype 内建方法所需的内部状态创建并初始化子类实例。

27.2.3.1 Promise ( executor )

此函数在被调用时执行下列步骤:

  1. 如果 NewTarget 是 undefined,抛出 TypeError 异常。
  2. 如果 IsCallable(executor) 是 false,抛出 TypeError 异常。
  3. promise 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Promise.prototype%", « [[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]], [[PromiseIsHandled]] »)。
  4. promise.[[PromiseState]] 设为 pending
  5. promise.[[PromiseResult]] 设为 empty
  6. promise.[[PromiseFulfillReactions]] 设为一个新的空 List
  7. promise.[[PromiseRejectReactions]] 设为一个新的空 List
  8. promise.[[PromiseIsHandled]] 设为 false
  9. resolvingFunctionsCreateResolvingFunctions(promise)。
  10. completionCompletion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »))。
  11. 如果 completion 是一个 abrupt completion,则
    1. 执行 ? Call(resolvingFunctions.[[Reject]], undefined, « completion.[[Value]] »)。
  12. 返回 promise
Note

executor 参数必须是一个函数对象。它被调用以发起并报告该 Promise 所表示的可能延迟动作的完成情况。executor 以两个参数调用:resolvereject。executor 函数可使用这些函数报告延迟计算的最终完成或失败。从 executor 函数返回并不意味着延迟动作已经完成,仅表示执行延迟动作的请求已被接受。

传给 executorresolve 函数接受一个参数。executor 代码最终可以调用 resolve 来表示其希望 resolve 关联的 Promise。传给 resolve 的参数表示延迟动作的最终值,可以是实际的 fulfill 值,也可以是另一个在 fulfill 后提供该值的 promise。

传给 executorreject 函数接受一个参数。executor 代码最终可以调用 reject 来表示关联的 Promise 已被 reject 且永不会 fulfill。传给 reject 的参数用作该 promise 的拒绝值。典型情况下它将是一个 Error 对象。

Promise 构造函数传给 executor 的 resolve 与 reject 函数具有实际 resolve 和 reject 关联 promise 的能力。子类可能有不同的构造函数行为,向 executor 传入自定义的 resolve 与 reject 值。

27.2.4 Promise 构造函数的属性

Promise 构造函数

27.2.4.1 Promise.all ( iterable )

该函数返回一个新的 promise:若传入的各个 promise 全部 fulfill,则以其 fulfill 值数组进行 fulfill;若其中第一个 reject,则以该 reject 原因进行 reject。它在运行本算法时会将传入可迭代对象的所有元素解析为 promise。

  1. Cthis 值。
  2. promiseCapability 为 ? NewPromiseCapability(C)。
  3. promiseResolveCompletion(GetPromiseResolve(C))。
  4. IfAbruptRejectPromise(promiseResolve, promiseCapability)。
  5. iteratorRecordCompletion(GetIterator(iterable, sync))。
  6. IfAbruptRejectPromise(iteratorRecord, promiseCapability)。
  7. resultCompletion(PerformPromiseAll(iteratorRecord, C, promiseCapability, promiseResolve))。
  8. 如果 result 是一个 abrupt completion,则
    1. 如果 iteratorRecord.[[Done]]false,将 result 设为 Completion(IteratorClose(iteratorRecord, result))。
    2. IfAbruptRejectPromise(result, promiseCapability)。
  9. 返回 ! result
Note

该函数要求其 this 值为一个支持 Promise 构造函数参数约定的构造函数

27.2.4.1.1 GetPromiseResolve ( promiseConstructor )

The abstract operation GetPromiseResolve takes argument promiseConstructor (一个 constructor) and returns 要么是包含一个函数对象的 normal completion,要么是一个 throw completion. It performs the following steps when called:

  1. promiseResolve 为 ? Get(promiseConstructor, "resolve")。
  2. 如果 IsCallable(promiseResolve) 是 false,抛出 TypeError 异常。
  3. 返回 promiseResolve

27.2.4.1.2 PerformPromiseAll ( iteratorRecord, constructor, resultCapability, promiseResolve )

The abstract operation PerformPromiseAll takes arguments iteratorRecord (一个 Iterator Record), constructor (一个 constructor), resultCapability (一个 PromiseCapability Record), and promiseResolve (一个函数对象) and returns 要么是包含一个 ECMAScript 语言值的 normal completion,要么是一个 throw completion. It performs the following steps when called:

  1. values 为一个新的空 List
  2. remainingElementsCountRecord { [[Value]]: 1 }。
  3. index 为 0。
  4. 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,则
      1. remainingElementsCount.[[Value]] 设为 remainingElementsCount.[[Value]] - 1。
      2. 如果 remainingElementsCount.[[Value]] = 0,则
        1. valuesArrayCreateArrayFromList(values)。
        2. 执行 ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »)。
      3. 返回 resultCapability.[[Promise]]
    3. undefined 追加到 values
    4. nextPromise 为 ? Call(promiseResolve, constructor, « next »)。
    5. stepsPromise.all Resolve 元素函数 中定义的算法步骤。
    6. lengthPromise.all Resolve 元素函数 中函数定义的非可选参数个数。
    7. onFulfilledCreateBuiltinFunction(steps, length, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »)。
    8. onFulfilled.[[AlreadyCalled]] 设为 false
    9. onFulfilled.[[Index]] 设为 index
    10. onFulfilled.[[Values]] 设为 values
    11. onFulfilled.[[Capability]] 设为 resultCapability
    12. onFulfilled.[[RemainingElements]] 设为 remainingElementsCount
    13. remainingElementsCount.[[Value]] 设为 remainingElementsCount.[[Value]] + 1。
    14. 执行 ? Invoke(nextPromise, "then", « onFulfilled, resultCapability.[[Reject]] »)。
    15. index 设为 index + 1。

27.2.4.1.3 Promise.all Resolve 元素函数

Promise.all resolve 元素函数是一个匿名内建函数,用于 resolve 某个特定的 Promise.all 元素。每个此类函数具有 [[Index]][[Values]][[Capability]][[RemainingElements]][[AlreadyCalled]] 内部槽。

当一个 Promise.all resolve 元素函数以参数 x 被调用时,执行下列步骤:

  1. F 为活动函数对象
  2. 如果 F.[[AlreadyCalled]]true,返回 undefined
  3. F.[[AlreadyCalled]] 设为 true
  4. indexF.[[Index]]
  5. valuesF.[[Values]]
  6. promiseCapabilityF.[[Capability]]
  7. remainingElementsCountF.[[RemainingElements]]
  8. values[index] 设为 x
  9. remainingElementsCount.[[Value]] 设为 remainingElementsCount.[[Value]] - 1。
  10. 如果 remainingElementsCount.[[Value]] = 0,则
    1. valuesArrayCreateArrayFromList(values)。
    2. 返回 ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »)。
  11. 返回 undefined

Promise.all resolve 元素函数的 "length" 属性是 1𝔽

27.2.4.2 Promise.allSettled ( iterable )

该函数返回一个 promise,当所有原始 promise 均已 settle(即变为 fulfilled 或 rejected)后,以包含 promise 状态快照的数组 fulfill。它在运行本算法时将传入可迭代对象的所有元素解析为 promise。

  1. Cthis 值。
  2. promiseCapability 为 ? NewPromiseCapability(C)。
  3. promiseResolveCompletion(GetPromiseResolve(C))。
  4. IfAbruptRejectPromise(promiseResolve, promiseCapability)。
  5. iteratorRecordCompletion(GetIterator(iterable, sync))。
  6. IfAbruptRejectPromise(iteratorRecord, promiseCapability)。
  7. resultCompletion(PerformPromiseAllSettled(iteratorRecord, C, promiseCapability, promiseResolve))。
  8. 如果 result 是一个 abrupt completion,则
    1. 如果 iteratorRecord.[[Done]]false,将 result 设为 Completion(IteratorClose(iteratorRecord, result))。
    2. IfAbruptRejectPromise(result, promiseCapability)。
  9. 返回 ! result
Note

该函数要求其 this 值为一个支持 Promise 构造函数参数约定的构造函数

27.2.4.2.1 PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability, promiseResolve )

The abstract operation PerformPromiseAllSettled takes arguments iteratorRecord (一个 Iterator Record), constructor (一个 constructor), resultCapability (一个 PromiseCapability Record), and promiseResolve (一个函数对象) and returns 要么是包含一个 ECMAScript 语言值的 normal completion,要么是一个 throw completion. It performs the following steps when called:

  1. values 为一个新的空 List
  2. remainingElementsCountRecord { [[Value]]: 1 }。
  3. index 为 0。
  4. 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,则
      1. remainingElementsCount.[[Value]] 设为 remainingElementsCount.[[Value]] - 1。
      2. 如果 remainingElementsCount.[[Value]] = 0,则
        1. valuesArrayCreateArrayFromList(values)。
        2. 执行 ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »)。
      3. 返回 resultCapability.[[Promise]]
    3. undefined 追加到 values
    4. nextPromise 为 ? Call(promiseResolve, constructor, « next »)。
    5. stepsFulfilledPromise.allSettled Resolve 元素函数 中定义的算法步骤。
    6. lengthFulfilledPromise.allSettled Resolve 元素函数 中函数定义的非可选参数个数。
    7. onFulfilledCreateBuiltinFunction(stepsFulfilled, lengthFulfilled, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »)。
    8. alreadyCalledRecord { [[Value]]: false }。
    9. onFulfilled.[[AlreadyCalled]] 设为 alreadyCalled
    10. onFulfilled.[[Index]] 设为 index
    11. onFulfilled.[[Values]] 设为 values
    12. onFulfilled.[[Capability]] 设为 resultCapability
    13. onFulfilled.[[RemainingElements]] 设为 remainingElementsCount
    14. stepsRejectedPromise.allSettled Reject 元素函数 中定义的算法步骤。
    15. lengthRejectedPromise.allSettled Reject 元素函数 中函数定义的非可选参数个数。
    16. onRejectedCreateBuiltinFunction(stepsRejected, lengthRejected, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »)。
    17. onRejected.[[AlreadyCalled]] 设为 alreadyCalled
    18. onRejected.[[Index]] 设为 index
    19. onRejected.[[Values]] 设为 values
    20. onRejected.[[Capability]] 设为 resultCapability
    21. onRejected.[[RemainingElements]] 设为 remainingElementsCount
    22. remainingElementsCount.[[Value]] 设为 remainingElementsCount.[[Value]] + 1。
    23. 执行 ? Invoke(nextPromise, "then", « onFulfilled, onRejected »)。
    24. index 设为 index + 1。

27.2.4.2.2 Promise.allSettled Resolve 元素函数

Promise.allSettled resolve 元素函数是一个匿名内建函数,用于 resolve 某个特定的 Promise.allSettled 元素。每个此类函数具有 [[Index]][[Values]][[Capability]][[RemainingElements]][[AlreadyCalled]] 内部槽。

当一个 Promise.allSettled resolve 元素函数以参数 x 被调用时,执行下列步骤:

  1. F 为活动函数对象
  2. alreadyCalledF.[[AlreadyCalled]]
  3. 如果 alreadyCalled.[[Value]]true,返回 undefined
  4. alreadyCalled.[[Value]] 设为 true
  5. indexF.[[Index]]
  6. valuesF.[[Values]]
  7. promiseCapabilityF.[[Capability]]
  8. remainingElementsCountF.[[RemainingElements]]
  9. objOrdinaryObjectCreate(%Object.prototype%)。
  10. 执行 ! CreateDataPropertyOrThrow(obj, "status", "fulfilled")。
  11. 执行 ! CreateDataPropertyOrThrow(obj, "value", x)。
  12. values[index] 设为 obj
  13. remainingElementsCount.[[Value]] 设为 remainingElementsCount.[[Value]] - 1。
  14. 如果 remainingElementsCount.[[Value]] = 0,则
    1. valuesArrayCreateArrayFromList(values)。
    2. 返回 ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »)。
  15. 返回 undefined

Promise.allSettled resolve 元素函数的 "length" 属性是 1𝔽

27.2.4.2.3 Promise.allSettled Reject 元素函数

Promise.allSettled reject 元素函数是一个匿名内建函数,用于 reject 某个特定的 Promise.allSettled 元素。每个此类函数具有 [[Index]][[Values]][[Capability]][[RemainingElements]][[AlreadyCalled]] 内部槽。

当一个 Promise.allSettled reject 元素函数以参数 x 被调用时,执行下列步骤:

  1. F 为活动函数对象
  2. alreadyCalledF.[[AlreadyCalled]]
  3. 如果 alreadyCalled.[[Value]]true,返回 undefined
  4. alreadyCalled.[[Value]] 设为 true
  5. indexF.[[Index]]
  6. valuesF.[[Values]]
  7. promiseCapabilityF.[[Capability]]
  8. remainingElementsCountF.[[RemainingElements]]
  9. objOrdinaryObjectCreate(%Object.prototype%)。
  10. 执行 ! CreateDataPropertyOrThrow(obj, "status", "rejected")。
  11. 执行 ! CreateDataPropertyOrThrow(obj, "reason", x)。
  12. values[index] 设为 obj
  13. remainingElementsCount.[[Value]] 设为 remainingElementsCount.[[Value]] - 1。
  14. 如果 remainingElementsCount.[[Value]] = 0,则
    1. valuesArrayCreateArrayFromList(values)。
    2. 返回 ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »)。
  15. 返回 undefined

Promise.allSettled reject 元素函数的 "length" 属性是 1𝔽

27.2.4.3 Promise.any ( iterable )

该函数返回一个 promise:由第一个 fulfill 的输入 promise 来 fulfill;如果所有输入 promise 均被 reject,则以一个包含所有拒绝原因的 AggregateError 进行 reject。它在运行本算法时将传入可迭代对象的所有元素解析为 promise。

  1. Cthis 值。
  2. promiseCapability 为 ? NewPromiseCapability(C)。
  3. promiseResolveCompletion(GetPromiseResolve(C))。
  4. IfAbruptRejectPromise(promiseResolve, promiseCapability)。
  5. iteratorRecordCompletion(GetIterator(iterable, sync))。
  6. IfAbruptRejectPromise(iteratorRecord, promiseCapability)。
  7. resultCompletion(PerformPromiseAny(iteratorRecord, C, promiseCapability, promiseResolve))。
  8. 如果 result 是一个 abrupt completion,则
    1. 如果 iteratorRecord.[[Done]]false,将 result 设为 Completion(IteratorClose(iteratorRecord, result))。
    2. IfAbruptRejectPromise(result, promiseCapability)。
  9. 返回 ! result
Note

该函数要求其 this 值为一个支持 Promise 构造函数参数约定的构造函数

27.2.4.3.1 PerformPromiseAny ( iteratorRecord, constructor, resultCapability, promiseResolve )

The abstract operation PerformPromiseAny takes arguments iteratorRecord (一个 Iterator Record), constructor (一个 constructor), resultCapability (一个 PromiseCapability Record), and promiseResolve (一个函数对象) and returns 要么是包含一个 ECMAScript 语言值的 normal completion,要么是一个 throw completion. It performs the following steps when called:

  1. errors 为一个新的空 List
  2. remainingElementsCountRecord { [[Value]]: 1 }。
  3. index 为 0。
  4. 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,则
      1. remainingElementsCount.[[Value]] 设为 remainingElementsCount.[[Value]] - 1。
      2. 如果 remainingElementsCount.[[Value]] = 0,则
        1. error 为一个新创建的 AggregateError 对象。
        2. 执行 ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) })。
        3. 返回 ThrowCompletion(error)。
      3. 返回 resultCapability.[[Promise]]
    3. undefined 追加到 errors
    4. nextPromise 为 ? Call(promiseResolve, constructor, « next »)。
    5. stepsRejectedPromise.any Reject 元素函数 中定义的算法步骤。
    6. lengthRejectedPromise.any Reject 元素函数 中函数定义的非可选参数个数。
    7. onRejectedCreateBuiltinFunction(stepsRejected, lengthRejected, "", « [[AlreadyCalled]], [[Index]], [[Errors]], [[Capability]], [[RemainingElements]] »)。
    8. onRejected.[[AlreadyCalled]] 设为 false
    9. onRejected.[[Index]] 设为 index
    10. onRejected.[[Errors]] 设为 errors
    11. onRejected.[[Capability]] 设为 resultCapability
    12. onRejected.[[RemainingElements]] 设为 remainingElementsCount
    13. remainingElementsCount.[[Value]] 设为 remainingElementsCount.[[Value]] + 1。
    14. 执行 ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], onRejected »)。
    15. index 设为 index + 1。

27.2.4.3.2 Promise.any Reject 元素函数

Promise.any reject 元素函数是一个匿名内建函数,用于 reject 某个特定的 Promise.any 元素。每个此类函数具有 [[Index]][[Errors]][[Capability]][[RemainingElements]][[AlreadyCalled]] 内部槽。

当一个 Promise.any reject 元素函数以参数 x 被调用时,执行下列步骤:

  1. F 为活动函数对象
  2. 如果 F.[[AlreadyCalled]]true,返回 undefined
  3. F.[[AlreadyCalled]] 设为 true
  4. indexF.[[Index]]
  5. errorsF.[[Errors]]
  6. promiseCapabilityF.[[Capability]]
  7. remainingElementsCountF.[[RemainingElements]]
  8. errors[index] 设为 x
  9. remainingElementsCount.[[Value]] 设为 remainingElementsCount.[[Value]] - 1。
  10. 如果 remainingElementsCount.[[Value]] = 0,则
    1. error 为一个新创建的 AggregateError 对象。
    2. 执行 ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) })。
    3. 返回 ? Call(promiseCapability.[[Reject]], undefined, « error »)。
  11. 返回 undefined

Promise.any reject 元素函数的 "length" 属性是 1𝔽

27.2.4.4 Promise.prototype

Promise.prototype 的初始值是 Promise 原型对象

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } 属性。

27.2.4.5 Promise.race ( iterable )

该函数返回一个新的 promise,其 settle 方式与第一个 settle 的传入 promise 相同。它在运行本算法时将传入的 iterable 的所有元素解析为 promise。

  1. Cthis 值。
  2. promiseCapability 为 ? NewPromiseCapability(C)。
  3. promiseResolveCompletion(GetPromiseResolve(C))。
  4. IfAbruptRejectPromise(promiseResolve, promiseCapability)。
  5. iteratorRecordCompletion(GetIterator(iterable, sync))。
  6. IfAbruptRejectPromise(iteratorRecord, promiseCapability)。
  7. resultCompletion(PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve))。
  8. 如果 result 是一个 abrupt completion,则
    1. 如果 iteratorRecord.[[Done]]false,将 result 设为 Completion(IteratorClose(iteratorRecord, result))。
    2. IfAbruptRejectPromise(result, promiseCapability)。
  9. 返回 ! result
Note 1

如果 iterable 参数不产生任何值,或其产生的 promise 都永不 settle,则此方法返回的挂起 promise 将永不 settle。

Note 2

该函数期望其 this 值为一个支持 Promise 构造函数参数约定的构造函数。它还期望其 this 值提供一个 resolve 方法。

27.2.4.5.1 PerformPromiseRace ( iteratorRecord, constructor, resultCapability, promiseResolve )

The abstract operation PerformPromiseRace takes arguments iteratorRecord (一个 Iterator Record), constructor (一个 constructor), resultCapability (一个 PromiseCapability Record), and promiseResolve (一个函数对象) and returns 要么是包含一个 ECMAScript 语言值的 normal completion,要么是一个 throw completion. It performs the following steps when called:

  1. 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,则
      1. 返回 resultCapability.[[Promise]]
    3. nextPromise 为 ? Call(promiseResolve, constructor, « next »)。
    4. 执行 ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »)。

27.2.4.6 Promise.reject ( r )

该函数返回一个以传入参数为拒绝原因而被 reject 的新 promise。

  1. Cthis 值。
  2. promiseCapability 为 ? NewPromiseCapability(C)。
  3. 执行 ? Call(promiseCapability.[[Reject]], undefined, « r »)。
  4. 返回 promiseCapability.[[Promise]]
Note

该函数期望其 this 值为一个支持 Promise 构造函数参数约定的构造函数

27.2.4.7 Promise.resolve ( x )

该函数要么返回一个以传入参数 resolve 的新 promise,要么若该参数本身是由此构造函数产生的 promise,则直接返回该参数。

  1. Cthis 值。
  2. 如果 C 不是一个 Object,抛出 TypeError 异常。
  3. 返回 ? PromiseResolve(C, x)。
Note

该函数期望其 this 值为一个支持 Promise 构造函数参数约定的构造函数

27.2.4.7.1 PromiseResolve ( C, x )

The abstract operation PromiseResolve takes arguments C (一个 Object) and x (一个 ECMAScript 语言值) and returns 要么是包含一个 ECMAScript 语言值的 normal completion,要么是一个 throw completion. 返回一个以 x resolve 的新 promise。 It performs the following steps when called:

  1. 如果 IsPromise(x) 是 true,则
    1. xConstructor 为 ? Get(x, "constructor")。
    2. 如果 SameValue(xConstructor, C) 是 true,返回 x
  2. promiseCapability 为 ? NewPromiseCapability(C)。
  3. 执行 ? Call(promiseCapability.[[Resolve]], undefined, « x »)。
  4. 返回 promiseCapability.[[Promise]]

27.2.4.8 Promise.try ( callback, ...args )

该函数在被调用时执行下列步骤:

  1. Cthis 值。
  2. 如果 C 不是一个 Object,抛出 TypeError 异常。
  3. promiseCapability 为 ? NewPromiseCapability(C)。
  4. statusCompletion(Call(callback, undefined, args))。
  5. 如果 status 是一个 abrupt completion,则
    1. 执行 ? Call(promiseCapability.[[Reject]], undefined, « status.[[Value]] »)。
  6. 否则,
    1. 执行 ? Call(promiseCapability.[[Resolve]], undefined, « status.[[Value]] »)。
  7. 返回 promiseCapability.[[Promise]]
Note

该函数期望其 this 值为一个支持 Promise 构造函数参数约定的构造函数

27.2.4.9 Promise.withResolvers ( )

该函数返回一个具有三个属性的对象:一个新 promise 以及与之关联的 resolvereject 函数。

  1. Cthis 值。
  2. promiseCapability 为 ? NewPromiseCapability(C)。
  3. objOrdinaryObjectCreate(%Object.prototype%)。
  4. 执行 ! CreateDataPropertyOrThrow(obj, "promise", promiseCapability.[[Promise]])。
  5. 执行 ! CreateDataPropertyOrThrow(obj, "resolve", promiseCapability.[[Resolve]])。
  6. 执行 ! CreateDataPropertyOrThrow(obj, "reject", promiseCapability.[[Reject]])。
  7. 返回 obj

27.2.4.10 get Promise [ %Symbol.species% ]

Promise[%Symbol.species%] 是一个访问器属性,其 set 访问器函数为 undefined。其 get 访问器函数在被调用时执行下列步骤:

  1. 返回 this 值。

该函数的 "name" 属性值是 "get [Symbol.species]"

Note

Promise 原型方法通常使用其 this 值的构造函数来创建一个派生对象。然而,一个子类构造函数可以通过重新定义其 %Symbol.species% 属性来覆盖该默认行为。

27.2.5 Promise 原型对象的属性

Promise 原型对象

  • %Promise.prototype%
  • 有一个 [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 是一个普通对象
  • 不具有 [[PromiseState]] 内部槽,也不具有 Promise 实例的其他任何内部槽。

27.2.5.1 Promise.prototype.catch ( onRejected )

该方法被调用时执行以下步骤:

  1. promisethis 值。
  2. 返回 ? Invoke(promise, "then", « undefined, onRejected »)。

27.2.5.2 Promise.prototype.constructor

Promise.prototype.constructor 的初始值是 %Promise%

27.2.5.3 Promise.prototype.finally ( onFinally )

该方法被调用时执行以下步骤:

  1. promisethis 值。
  2. 如果 promise 不是一个 Object,抛出 TypeError 异常。
  3. C 为 ? SpeciesConstructor(promise, %Promise%)。
  4. 断言:IsConstructor(C) 为 true
  5. 如果 IsCallable(onFinally) 为 false,则
    1. thenFinallyonFinally
    2. catchFinallyonFinally
  6. 否则,
    1. thenFinallyClosure 为一个具有参数 (value) 的新抽象闭包,捕获 onFinallyC,在被调用时执行以下步骤:
      1. result 为 ? Call(onFinally, undefined)。
      2. p 为 ? PromiseResolve(C, result)。
      3. returnValue 为一个无参数的新抽象闭包,捕获 value 并在被调用时执行以下步骤:
        1. 返回 NormalCompletion(value)。
      4. valueThunkCreateBuiltinFunction(returnValue, 0, "", « »)。
      5. 返回 ? Invoke(p, "then", « valueThunk »)。
    2. thenFinallyCreateBuiltinFunction(thenFinallyClosure, 1, "", « »)。
    3. catchFinallyClosure 为一个具有参数 (reason) 的新抽象闭包,捕获 onFinallyC,在被调用时执行以下步骤:
      1. result 为 ? Call(onFinally, undefined)。
      2. p 为 ? PromiseResolve(C, result)。
      3. throwReason 为一个无参数的新抽象闭包,捕获 reason 并在被调用时执行以下步骤:
        1. 返回 ThrowCompletion(reason)。
      4. throwerCreateBuiltinFunction(throwReason, 0, "", « »)。
      5. 返回 ? Invoke(p, "then", « thrower »)。
    4. catchFinallyCreateBuiltinFunction(catchFinallyClosure, 1, "", « »)。
  7. 返回 ? Invoke(promise, "then", « thenFinally, catchFinally »)。

27.2.5.4 Promise.prototype.then ( onFulfilled, onRejected )

该方法被调用时执行以下步骤:

  1. promisethis 值。
  2. 如果 IsPromise(promise) 为 false,抛出 TypeError 异常。
  3. C 为 ? SpeciesConstructor(promise, %Promise%)。
  4. resultCapability 为 ? NewPromiseCapability(C)。
  5. 返回 PerformPromiseThen(promise, onFulfilled, onRejected, resultCapability)。

27.2.5.4.1 PerformPromiseThen ( promise, onFulfilled, onRejected [ , resultCapability ] )

The abstract operation PerformPromiseThen takes arguments promise (a Promise), onFulfilled (an ECMAScript language value), and onRejected (an ECMAScript language value) and optional argument resultCapability (a PromiseCapability Record) and returns an ECMAScript language value. 使用 onFulfilledonRejected 作为 settle 动作在 promise 上执行 “then” 操作。若传入 resultCapability,则通过更新 resultCapability 的 promise 来存储结果;若未传入,则表示 PerformPromiseThen 是由规范内部操作调用,其结果不重要。 It performs the following steps when called:

  1. 断言:IsPromise(promise) 为 true
  2. 如果 resultCapability 未传入,则
    1. resultCapability 设为 undefined
  3. 如果 IsCallable(onFulfilled) 为 false,则
    1. onFulfilledJobCallbackempty
  4. 否则,
    1. onFulfilledJobCallbackHostMakeJobCallback(onFulfilled)。
  5. 如果 IsCallable(onRejected) 为 false,则
    1. onRejectedJobCallbackempty
  6. 否则,
    1. onRejectedJobCallbackHostMakeJobCallback(onRejected)。
  7. fulfillReactionPromiseReaction Record { [[Capability]]: resultCapability, [[Type]]: fulfill, [[Handler]]: onFulfilledJobCallback }。
  8. rejectReactionPromiseReaction Record { [[Capability]]: resultCapability, [[Type]]: reject, [[Handler]]: onRejectedJobCallback }。
  9. 如果 promise.[[PromiseState]]pending,则
    1. fulfillReaction 追加到 promise.[[PromiseFulfillReactions]]
    2. rejectReaction 追加到 promise.[[PromiseRejectReactions]]
  10. 否则如果 promise.[[PromiseState]]fulfilled,则
    1. valuepromise.[[PromiseResult]]
    2. fulfillJobNewPromiseReactionJob(fulfillReaction, value)。
    3. 执行 HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]])。
  11. 否则,
    1. 断言:promise.[[PromiseState]]rejected
    2. reasonpromise.[[PromiseResult]]
    3. 如果 promise.[[PromiseIsHandled]]false,执行 HostPromiseRejectionTracker(promise, "handle")。
    4. rejectJobNewPromiseReactionJob(rejectReaction, reason)。
    5. 执行 HostEnqueuePromiseJob(rejectJob.[[Job]], rejectJob.[[Realm]])。
  12. promise.[[PromiseIsHandled]] 设为 true
  13. 如果 resultCapabilityundefined,则
    1. 返回 undefined
  14. 否则,
    1. 返回 resultCapability.[[Promise]]

27.2.5.5 Promise.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串值 "Promise"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } 属性。

27.2.6 Promise 实例的属性

Promise 实例是普通对象,从 Promise 原型对象(那个内在对象 %Promise.prototype%)继承属性。Promise 实例最初按照 Table 90 描述的内部槽创建。

Table 90: Promise 实例的内部槽
内部槽 类型 描述
[[PromiseState]] pending, fulfilled, 或 rejected 决定该 promise 对其 then 方法的传入调用如何作出反应。
[[PromiseResult]] 一个 ECMAScript 语言值empty promise 被 fulfill 或 reject 时的值(若有)。当且仅当 [[PromiseState]]pending 时为 empty
[[PromiseFulfillReactions]] 一个 PromiseReaction RecordList 当(如果)promise 从 pending 转变为 fulfilled 状态时要处理的记录。
[[PromiseRejectReactions]] 一个 PromiseReaction RecordList 当(如果)promise 从 pending 转变为 rejected 状态时要处理的记录。
[[PromiseIsHandled]] 一个 Boolean 指示该 promise 是否曾拥有过 fulfill 或 reject 处理器;用于未处理拒绝的跟踪。

27.3 GeneratorFunction 对象

GeneratorFunction 是通常通过求值 GeneratorDeclarationGeneratorExpressionGeneratorMethod 产生的函数。也可通过调用内在对象 %GeneratorFunction% 创建。

Figure 6 (Informative): Generator 对象关系
大量框与箭头的示意图。

27.3.1 GeneratorFunction 构造函数

GeneratorFunction 构造函数

  • %GeneratorFunction%
  • Function 的子类。
  • 当以函数(而非构造函数)方式调用时创建并初始化一个新的 GeneratorFunction。故函数调用 GeneratorFunction (…) 等价于以相同参数的对象创建表达式 new GeneratorFunction (…)
  • 可用作类定义中 extends 子句的值。意图继承指定 GeneratorFunction 行为的子类构造函数必须包含对 GeneratorFunction 构造函数super 调用,以创建并初始化带有内建 GeneratorFunction 行为所需内部槽的子类实例。所有用于定义 generator 函数对象的 ECMAScript 语法形式都会创建 GeneratorFunction 的直接实例。没有语法手段创建 GeneratorFunction 子类的实例。

27.3.1.1 GeneratorFunction ( ...parameterArgs, bodyArg )

最后一个参数(如果存在)指定生成器函数的函数体(可执行代码);之前的任意参数指定形式参数。

该函数被调用时执行以下步骤:

  1. C 为活动函数对象
  2. 如果 bodyArg 不存在,将 bodyArg 设为空字符串。
  3. 返回 ? CreateDynamicFunction(C, NewTarget, generator, parameterArgs, bodyArg)。
Note

参见 20.2.1.1 的注。

27.3.2 GeneratorFunction 构造函数的属性

GeneratorFunction 构造函数

  • 是一个继承自 Function 构造函数的标准内建函数对象
  • 具有值为 %Function%[[Prototype]] 内部槽。
  • 具有值为 1𝔽"length" 属性。
  • 具有值为 "GeneratorFunction""name" 属性。
  • 具有以下属性:

27.3.2.1 GeneratorFunction.prototype

GeneratorFunction.prototype 的初始值是 GeneratorFunction 原型对象

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

27.3.3 GeneratorFunction 原型对象的属性

GeneratorFunction 原型对象

27.3.3.1 GeneratorFunction.prototype.constructor

GeneratorFunction.prototype.constructor 的初始值是 %GeneratorFunction%

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.3.3.2 GeneratorFunction.prototype.prototype

GeneratorFunction.prototype.prototype 的初始值是 %GeneratorPrototype%

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.3.3.3 GeneratorFunction.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "GeneratorFunction"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.3.4 GeneratorFunction 实例

每个 GeneratorFunction 实例都是一个 ECMAScript 函数对象,并拥有 Table 28 中列出的内部槽。所有此类实例的 [[IsClassConstructor]] 内部槽的值为 false

每个 GeneratorFunction 实例具有以下自有属性:

27.3.4.1 length

20.2.4.1 中给出的 Function 实例 "length" 属性规范同样适用于 GeneratorFunction 实例。

27.3.4.2 name

20.2.4.2 中给出的 Function 实例 "name" 属性规范同样适用于 GeneratorFunction 实例。

27.3.4.3 prototype

每当创建一个 GeneratorFunction 实例时,也会创建另一个普通对象,作为该生成器函数 "prototype" 属性的初始值。该 prototype 属性的值用于在以 [[Call]] 调用该生成器函数对象时初始化新建 Generator 的 [[Prototype]] 内部槽。

该属性具有 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }。

Note

不同于 Function 实例,GeneratorFunction 的 "prototype" 属性值对象没有 "constructor" 属性,其值为该 GeneratorFunction 实例。

27.4 AsyncGeneratorFunction 对象

AsyncGeneratorFunction 是通常通过求值 AsyncGeneratorDeclarationAsyncGeneratorExpressionAsyncGeneratorMethod 语法产生式创建的函数。也可通过调用内在对象 %AsyncGeneratorFunction% 创建。

27.4.1 AsyncGeneratorFunction 构造函数

AsyncGeneratorFunction 构造函数

  • %AsyncGeneratorFunction%
  • Function 的子类。
  • 当以函数(而非构造函数)方式调用时创建并初始化一个新的 AsyncGeneratorFunction。故函数调用 AsyncGeneratorFunction (...) 等价于以相同参数的对象创建表达式 new AsyncGeneratorFunction (...)
  • 可用作类定义中 extends 子句的值。意图继承指定 AsyncGeneratorFunction 行为的子类构造函数必须包含对 AsyncGeneratorFunction 构造函数super 调用,以创建并初始化带有内建 AsyncGeneratorFunction 行为所需内部槽的子类实例。所有用于定义 async generator 函数对象的 ECMAScript 语法形式都会创建 AsyncGeneratorFunction 的直接实例。没有语法手段创建 AsyncGeneratorFunction 子类的实例。

27.4.1.1 AsyncGeneratorFunction ( ...parameterArgs, bodyArg )

最后一个参数(如果存在)指定异步生成器函数的函数体(可执行代码);之前的任意参数指定形式参数。

该函数被调用时执行以下步骤:

  1. C 为活动函数对象
  2. 如果 bodyArg 不存在,将 bodyArg 设为空字符串。
  3. 返回 ? CreateDynamicFunction(C, NewTarget, async-generator, parameterArgs, bodyArg)。
Note

参见 20.2.1.1 的注。

27.4.2 AsyncGeneratorFunction 构造函数的属性

AsyncGeneratorFunction 构造函数

  • 是一个继承自 Function 构造函数的标准内建函数对象
  • 具有值为 %Function%[[Prototype]] 内部槽。
  • 具有值为 1𝔽"length" 属性。
  • 具有值为 "AsyncGeneratorFunction""name" 属性。
  • 具有以下属性:

27.4.2.1 AsyncGeneratorFunction.prototype

AsyncGeneratorFunction.prototype 的初始值是 AsyncGeneratorFunction 原型对象

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

27.4.3 AsyncGeneratorFunction 原型对象的属性

AsyncGeneratorFunction 原型对象

27.4.3.1 AsyncGeneratorFunction.prototype.constructor

AsyncGeneratorFunction.prototype.constructor 的初始值是 %AsyncGeneratorFunction%

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.4.3.2 AsyncGeneratorFunction.prototype.prototype

AsyncGeneratorFunction.prototype.prototype 的初始值是 %AsyncGeneratorPrototype%

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.4.3.3 AsyncGeneratorFunction.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "AsyncGeneratorFunction"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.4.4 AsyncGeneratorFunction 实例

每个 AsyncGeneratorFunction 实例都是一个 ECMAScript 函数对象,并拥有 Table 28 中列出的内部槽。所有此类实例的 [[IsClassConstructor]] 内部槽的值为 false

每个 AsyncGeneratorFunction 实例具有以下自有属性:

27.4.4.1 length

"length" 属性的值是一个整数 Number,表示该 AsyncGeneratorFunction 期望的典型参数个数。然而,语言允许以其他参数个数调用该函数。以不同于其 "length" 属性指定参数个数调用时 AsyncGeneratorFunction 的行为依赖于函数本身。

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.4.4.2 name

20.2.4.2 中给出的 Function 实例 "name" 属性规范同样适用于 AsyncGeneratorFunction 实例。

27.4.4.3 prototype

每当创建一个 AsyncGeneratorFunction 实例时,也会创建另一个普通对象,作为该异步生成器函数 "prototype" 属性的初始值。该 prototype 属性的值用于在以 [[Call]] 调用该生成器函数对象时初始化新建 AsyncGenerator 的 [[Prototype]] 内部槽。

该属性具有 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }。

Note

不同于函数实例,AsyncGeneratorFunction 的 "prototype" 属性值对象没有 "constructor" 属性,其值为该 AsyncGeneratorFunction 实例。

27.5 Generator 对象

Generator 通过调用一个生成器函数创建,并符合迭代器接口与可迭代接口。

Generator 实例直接从创建该实例的生成器函数 "prototype" 属性初始值继承属性。Generator 实例间接从 %GeneratorPrototype% 继承属性。

27.5.1 %GeneratorPrototype% 对象

%GeneratorPrototype% 对象:

  • %GeneratorFunction.prototype.prototype%
  • 是一个普通对象
  • 不是一个 Generator 实例,且没有 [[GeneratorState]] 内部槽。
  • 具有值为 %Iterator.prototype%[[Prototype]] 内部槽。
  • 具有被所有 Generator 实例间接继承的属性。

27.5.1.1 %GeneratorPrototype%.constructor

%GeneratorPrototype%.constructor 的初始值是 %GeneratorFunction.prototype%

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.5.1.2 %GeneratorPrototype%.next ( value )

  1. 返回 ? GeneratorResume(this value, value, empty)。

27.5.1.3 %GeneratorPrototype%.return ( value )

该方法被调用时执行以下步骤:

  1. gthis 值。
  2. CReturnCompletion(value)。
  3. 返回 ? GeneratorResumeAbrupt(g, C, empty)。

27.5.1.4 %GeneratorPrototype%.throw ( exception )

该方法被调用时执行以下步骤:

  1. gthis 值。
  2. CThrowCompletion(exception)。
  3. 返回 ? GeneratorResumeAbrupt(g, C, empty)。

27.5.1.5 %GeneratorPrototype% [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "Generator"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.5.2 Generator 实例的属性

Generator 实例最初按 Table 91 中描述的内部槽创建。

Table 91: Generator 实例的内部槽
内部槽 类型 描述
[[GeneratorState]] suspended-start, suspended-yield, executing, 或 completed 该生成器的当前执行状态。
[[GeneratorContext]] 一个执行上下文 执行该生成器代码时使用的执行上下文。
[[GeneratorBrand]] 一个 String 或 empty 用于区分不同种类生成器的标记。由 ECMAScript 源文本声明的生成器的 [[GeneratorBrand]] 始终为 empty

27.5.3 Generator 抽象操作

27.5.3.1 GeneratorStart ( generator, generatorBody )

The abstract operation GeneratorStart takes arguments generator (a Generator) and generatorBody (a FunctionBody Parse Node or an Abstract Closure with no parameters) and returns unused. It performs the following steps when called:

  1. 断言:generator.[[GeneratorState]]suspended-start
  2. genContext 为正在运行的执行上下文。
  3. genContext 的 Generator 组件设为 generator
  4. closure 为一个无参数的新抽象闭包,捕获 generatorBody 并在被调用时执行以下步骤:
    1. acGenContext 为正在运行的执行上下文。
    2. acGeneratoracGenContext 的 Generator 组件。
    3. 如果 generatorBody 是一个 Parse Node,则
      1. resultCompletion(Evaluation of generatorBody)。
    4. 否则,
      1. 断言:generatorBody 是一个无参数抽象闭包。
      2. resultCompletion(generatorBody())。
    5. 断言:若我们在此返回,生成器要么抛出了异常,要么执行了隐式或显式的 return。
    6. acGenContext 从执行上下文栈移除,并恢复栈顶执行上下文为正在运行的执行上下文。
    7. acGenerator.[[GeneratorState]] 设为 completed
    8. 注:一旦生成器进入 completed 状态,它将不再离开该状态,其关联执行上下文不再恢复。此时可丢弃与 acGenerator 相关的任意执行状态。
    9. 如果 result 是一个 normal completion,则
      1. resultValueundefined
    10. 否则如果 result 是一个 return completion,则
      1. resultValueresult.[[Value]]
    11. 否则,
      1. 断言:result 是一个 throw completion。
      2. 返回 ? result
    12. 返回 NormalCompletion(CreateIteratorResultObject(resultValue, true))。
  5. 设定 genContext 的代码求值状态,使得当该执行上下文恢复求值时,将无参数调用 closure
  6. generator.[[GeneratorContext]] 设为 genContext
  7. 返回 unused

27.5.3.2 GeneratorValidate ( generator, generatorBrand )

The abstract operation GeneratorValidate takes arguments generator (an ECMAScript language value) and generatorBrand (a String or empty) and returns either a normal completion containing one of suspended-start, suspended-yield, or completed, or a throw completion. It performs the following steps when called:

  1. 执行 ? RequireInternalSlot(generator, [[GeneratorState]])。
  2. 执行 ? RequireInternalSlot(generator, [[GeneratorBrand]])。
  3. 如果 generator.[[GeneratorBrand]] 不等于 generatorBrand,抛出 TypeError 异常。
  4. 断言:generator 也有 [[GeneratorContext]] 内部槽。
  5. stategenerator.[[GeneratorState]]
  6. 如果 stateexecuting,抛出 TypeError 异常。
  7. 返回 state

27.5.3.3 GeneratorResume ( generator, value, generatorBrand )

The abstract operation GeneratorResume takes arguments generator (an ECMAScript language value), value (an ECMAScript language value or empty), and generatorBrand (a String or empty) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. state 为 ? GeneratorValidate(generator, generatorBrand)。
  2. 如果 statecompleted,返回 CreateIteratorResultObject(undefined, true)。
  3. 断言:statesuspended-startsuspended-yield
  4. genContextgenerator.[[GeneratorContext]]
  5. methodContext 为正在运行的执行上下文。
  6. 挂起 methodContext
  7. generator.[[GeneratorState]] 设为 executing
  8. genContext 压入执行上下文栈;genContext 现在是正在运行的执行上下文。
  9. 恢复 genContext 的挂起求值,使用 NormalCompletion(value) 作为使其挂起的操作的结果。令 result 为恢复计算返回的值。
  10. 断言:当我们在此返回时,genContext 已从执行上下文栈移除且 methodContext 是当前正在运行的执行上下文。
  11. 返回 ? result

27.5.3.4 GeneratorResumeAbrupt ( generator, abruptCompletion, generatorBrand )

The abstract operation GeneratorResumeAbrupt takes arguments generator (an ECMAScript language value), abruptCompletion (a return completion or a throw completion), and generatorBrand (a String or empty) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. state 为 ? GeneratorValidate(generator, generatorBrand)。
  2. 如果 statesuspended-start,则
    1. generator.[[GeneratorState]] 设为 completed
    2. 注:一旦生成器进入 completed 状态,它将不再离开该状态,其关联执行上下文不再恢复。此时可丢弃与 generator 相关的任意执行状态。
    3. state 设为 completed
  3. 如果 statecompleted,则
    1. 如果 abruptCompletion 是一个 return completion,则
      1. 返回 CreateIteratorResultObject(abruptCompletion.[[Value]], true)。
    2. 返回 ? abruptCompletion
  4. 断言:statesuspended-yield
  5. genContextgenerator.[[GeneratorContext]]
  6. methodContext 为正在运行的执行上下文。
  7. 挂起 methodContext
  8. generator.[[GeneratorState]] 设为 executing
  9. genContext 压入执行上下文栈;genContext 现在是正在运行的执行上下文。
  10. 恢复 genContext 的挂起求值,使用 abruptCompletion 作为使其挂起的操作的结果。令 result 为恢复计算返回的 Completion Record
  11. 断言:当我们在此返回时,genContext 已从执行上下文栈移除且 methodContext 是当前正在运行的执行上下文。
  12. 返回 ? result

27.5.3.5 GetGeneratorKind ( )

The abstract operation GetGeneratorKind takes no arguments and returns non-generator, sync, or async. It performs the following steps when called:

  1. genContext 为正在运行的执行上下文。
  2. 如果 genContext 没有 Generator 组件,返回 non-generator
  3. generatorgenContext 的 Generator 组件。
  4. 如果 generator 具有 [[AsyncGeneratorState]] 内部槽,返回 async
  5. 否则,返回 sync

27.5.3.6 GeneratorYield ( iteratorResult )

The abstract operation GeneratorYield takes argument iteratorResult (an Object that conforms to the IteratorResult interface) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. genContext 为正在运行的执行上下文。
  2. 断言:genContext 是一个生成器的执行上下文。
  3. generatorgenContext 的 Generator 组件的值。
  4. 断言:GetGeneratorKind() 是 sync
  5. generator.[[GeneratorState]] 设为 suspended-yield
  6. genContext 从执行上下文栈移除,恢复栈顶执行上下文为正在运行的执行上下文。
  7. callerContext 为正在运行的执行上下文。
  8. 恢复 callerContext,传入 NormalCompletion(iteratorResult)。如果 genContext 之后再次被恢复,令 resumptionValue 为恢复时使用的 Completion Record
  9. 断言:若控制流到达此处,则 genContext 再次成为正在运行的执行上下文。
  10. 返回 resumptionValue

27.5.3.7 Yield ( value )

The abstract operation Yield takes argument value (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. generatorKindGetGeneratorKind()。
  2. 如果 generatorKindasync,返回 ? AsyncGeneratorYield(? Await(value))。
  3. 否则,返回 ? GeneratorYield(CreateIteratorResultObject(value, false))。

27.5.3.8 CreateIteratorFromClosure ( closure, generatorBrand, generatorPrototype [ , extraSlots ] )

The abstract operation CreateIteratorFromClosure takes arguments closure (an Abstract Closure with no parameters), generatorBrand (a String or empty), and generatorPrototype (an Object) and optional argument extraSlots (a List of names of internal slots) and returns a Generator. It performs the following steps when called:

  1. 注:closure 可以包含对 Yield 操作的使用,以产出一个 IteratorResult 对象。
  2. 如果 extraSlots 不存在,将 extraSlots 设为一个新的空 List
  3. internalSlotsListextraSlots 与 « [[GeneratorState]], [[GeneratorContext]], [[GeneratorBrand]] » 的列表连接。
  4. generatorOrdinaryObjectCreate(generatorPrototype, internalSlotsList)。
  5. generator.[[GeneratorBrand]] 设为 generatorBrand
  6. generator.[[GeneratorState]] 设为 suspended-start
  7. callerContext 为正在运行的执行上下文。
  8. calleeContext 为一个新的执行上下文。
  9. calleeContext 的 Function 设为 null
  10. calleeContextRealm 设为当前 Realm Record
  11. calleeContext 的 ScriptOrModule 设为 callerContext 的 ScriptOrModule。
  12. 如果 callerContext 尚未被挂起,则挂起 callerContext
  13. calleeContext 压入执行上下文栈;calleeContext 现在是正在运行的执行上下文。
  14. 执行 GeneratorStart(generator, closure)。
  15. calleeContext 从执行上下文栈移除并恢复 callerContext 为正在运行的执行上下文。
  16. 返回 generator

27.6 AsyncGenerator 对象

AsyncGenerator 通过调用一个 async 生成器函数创建,并同时符合异步迭代器接口与异步可迭代接口。

AsyncGenerator 实例直接从创建该实例的异步生成器函数 "prototype" 属性的初始值继承属性。AsyncGenerator 实例间接从 %AsyncGeneratorPrototype% 继承属性。

27.6.1 %AsyncGeneratorPrototype% 对象

%AsyncGeneratorPrototype% 对象:

  • %AsyncGeneratorFunction.prototype.prototype%
  • 是一个普通对象
  • 不是 AsyncGenerator 实例,并且没有 [[AsyncGeneratorState]] 内部槽。
  • 具有值为 %AsyncIteratorPrototype%[[Prototype]] 内部槽。
  • 具有被所有 AsyncGenerator 实例间接继承的属性。

27.6.1.1 %AsyncGeneratorPrototype%.constructor

%AsyncGeneratorPrototype%.constructor 的初始值是 %AsyncGeneratorFunction.prototype%

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.6.1.2 %AsyncGeneratorPrototype%.next ( value )

  1. generatorthis 值。
  2. promiseCapability 为 ! NewPromiseCapability(%Promise%)。
  3. resultCompletion(AsyncGeneratorValidate(generator, empty))。
  4. IfAbruptRejectPromise(result, promiseCapability)。
  5. stategenerator.[[AsyncGeneratorState]]
  6. 如果 statecompleted,则
    1. iteratorResultCreateIteratorResultObject(undefined, true)。
    2. 执行 ! Call(promiseCapability.[[Resolve]], undefined, « iteratorResult »)。
    3. 返回 promiseCapability.[[Promise]]
  7. completionNormalCompletion(value)。
  8. 执行 AsyncGeneratorEnqueue(generator, completion, promiseCapability)。
  9. 如果 statesuspended-startsuspended-yield,则
    1. 执行 AsyncGeneratorResume(generator, completion)。
  10. 否则,
    1. 断言:stateexecutingdraining-queue
  11. 返回 promiseCapability.[[Promise]]

27.6.1.3 %AsyncGeneratorPrototype%.return ( value )

  1. generatorthis 值。
  2. promiseCapability 为 ! NewPromiseCapability(%Promise%)。
  3. resultCompletion(AsyncGeneratorValidate(generator, empty))。
  4. IfAbruptRejectPromise(result, promiseCapability)。
  5. completionReturnCompletion(value)。
  6. 执行 AsyncGeneratorEnqueue(generator, completion, promiseCapability)。
  7. stategenerator.[[AsyncGeneratorState]]
  8. 如果 statesuspended-startcompleted,则
    1. generator.[[AsyncGeneratorState]] 设为 draining-queue
    2. 执行 AsyncGeneratorAwaitReturn(generator)。
  9. 否则如果 statesuspended-yield,则
    1. 执行 AsyncGeneratorResume(generator, completion)。
  10. 否则,
    1. 断言:stateexecutingdraining-queue
  11. 返回 promiseCapability.[[Promise]]

27.6.1.4 %AsyncGeneratorPrototype%.throw ( exception )

  1. generatorthis 值。
  2. promiseCapability 为 ! NewPromiseCapability(%Promise%)。
  3. resultCompletion(AsyncGeneratorValidate(generator, empty))。
  4. IfAbruptRejectPromise(result, promiseCapability)。
  5. stategenerator.[[AsyncGeneratorState]]
  6. 如果 statesuspended-start,则
    1. generator.[[AsyncGeneratorState]] 设为 completed
    2. state 设为 completed
  7. 如果 statecompleted,则
    1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « exception »)。
    2. 返回 promiseCapability.[[Promise]]
  8. completionThrowCompletion(exception)。
  9. 执行 AsyncGeneratorEnqueue(generator, completion, promiseCapability)。
  10. 如果 statesuspended-yield,则
    1. 执行 AsyncGeneratorResume(generator, completion)。
  11. 否则,
    1. 断言:stateexecutingdraining-queue
  12. 返回 promiseCapability.[[Promise]]

27.6.1.5 %AsyncGeneratorPrototype% [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "AsyncGenerator"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.6.2 AsyncGenerator 实例的属性

AsyncGenerator 实例最初按如下描述的内部槽创建:

Table 92: AsyncGenerator 实例的内部槽
内部槽 类型 描述
[[AsyncGeneratorState]] suspended-start, suspended-yield, executing, draining-queue, 或 completed 异步生成器的当前执行状态。
[[AsyncGeneratorContext]] 一个执行上下文 执行该异步生成器代码时使用的执行上下文。
[[AsyncGeneratorQueue]] 一个 AsyncGeneratorRequest RecordList 表示恢复该异步生成器请求的记录。除状态转换期间外,当且仅当 [[AsyncGeneratorState]]executingdraining-queue 时其非空。
[[GeneratorBrand]] 一个 String 或 empty 用于区分不同种类异步生成器的标记。由 ECMAScript 源文本声明的异步生成器的 [[GeneratorBrand]] 始终为 empty

27.6.3 AsyncGenerator 抽象操作

27.6.3.1 AsyncGeneratorRequest 记录

AsyncGeneratorRequest 是一个 Record 值,用于存储关于异步生成器应如何恢复的信息,并包含履行或拒绝相应 promise 的能力。

其具有以下字段:

Table 93: AsyncGeneratorRequest Record 字段
字段名 取值 含义
[[Completion]] 一个 Completion Record 用于恢复该异步生成器的 Completion Record
[[Capability]] 一个 PromiseCapability Record 与此请求关联的 promise 能力。

27.6.3.2 AsyncGeneratorStart ( generator, generatorBody )

The abstract operation AsyncGeneratorStart takes arguments generator (an AsyncGenerator) and generatorBody (a FunctionBody Parse Node or an Abstract Closure with no parameters) and returns unused. It performs the following steps when called:

  1. 断言:generator.[[AsyncGeneratorState]]suspended-start
  2. genContext 为正在运行的执行上下文。
  3. genContext 的 Generator 组件设为 generator
  4. closure 为一个无参数的新抽象闭包,捕获 generatorBody 并在被调用时执行以下步骤:
    1. acGenContext 为正在运行的执行上下文。
    2. acGeneratoracGenContext 的 Generator 组件。
    3. 如果 generatorBody 是一个 Parse Node,则
      1. resultCompletion(Evaluation of generatorBody)。
    4. 否则,
      1. 断言:generatorBody 是一个无参数抽象闭包。
      2. resultCompletion(generatorBody())。
    5. 断言:若我们在此返回,异步生成器要么抛出异常,要么执行了隐式或显式的 return。
    6. acGenContext 从执行上下文栈移除,并恢复栈顶执行上下文为正在运行的执行上下文。
    7. acGenerator.[[AsyncGeneratorState]] 设为 draining-queue
    8. 如果 result 是一个 normal completion,将 result 设为 NormalCompletion(undefined)。
    9. 如果 result 是一个 return completion,将 result 设为 NormalCompletion(result.[[Value]])。
    10. 执行 AsyncGeneratorCompleteStep(acGenerator, result, true)。
    11. 执行 AsyncGeneratorDrainQueue(acGenerator)。
    12. 返回 NormalCompletion(undefined)。
  5. 设定 genContext 的代码求值状态,使得当该执行上下文恢复求值时,将无参数调用 closure
  6. generator.[[AsyncGeneratorContext]] 设为 genContext
  7. generator.[[AsyncGeneratorQueue]] 设为一个新的空 List
  8. 返回 unused

27.6.3.3 AsyncGeneratorValidate ( generator, generatorBrand )

The abstract operation AsyncGeneratorValidate takes arguments generator (an ECMAScript language value) and generatorBrand (a String or empty) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. 执行 ? RequireInternalSlot(generator, [[AsyncGeneratorContext]])。
  2. 执行 ? RequireInternalSlot(generator, [[AsyncGeneratorState]])。
  3. 执行 ? RequireInternalSlot(generator, [[AsyncGeneratorQueue]])。
  4. 如果 generator.[[GeneratorBrand]] 不等于 generatorBrand,抛出 TypeError 异常。
  5. 返回 unused

27.6.3.4 AsyncGeneratorEnqueue ( generator, completion, promiseCapability )

The abstract operation AsyncGeneratorEnqueue takes arguments generator (an AsyncGenerator), completion (a Completion Record), and promiseCapability (a PromiseCapability Record) and returns unused. It performs the following steps when called:

  1. requestAsyncGeneratorRequest { [[Completion]]: completion, [[Capability]]: promiseCapability }。
  2. request 追加到 generator.[[AsyncGeneratorQueue]]
  3. 返回 unused

27.6.3.5 AsyncGeneratorCompleteStep ( generator, completion, done [ , realm ] )

The abstract operation AsyncGeneratorCompleteStep takes arguments generator (an AsyncGenerator), completion (a Completion Record), and done (a Boolean) and optional argument realm (a Realm Record) and returns unused. It performs the following steps when called:

  1. 断言:generator.[[AsyncGeneratorQueue]] 非空。
  2. nextgenerator.[[AsyncGeneratorQueue]] 的第一个元素。
  3. 移除 generator.[[AsyncGeneratorQueue]] 的第一个元素。
  4. promiseCapabilitynext.[[Capability]]
  5. valuecompletion.[[Value]]
  6. 如果 completion 是一个 throw completion,则
    1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « value »)。
  7. 否则,
    1. 断言:completion 是一个 normal completion。
    2. 如果存在 realm,则
      1. oldRealm 为正在运行的执行上下文的 Realm
      2. 将正在运行的执行上下文的 Realm 设为 realm
      3. iteratorResultCreateIteratorResultObject(value, done)。
      4. 将正在运行的执行上下文的 Realm 设回 oldRealm
    3. 否则,
      1. iteratorResultCreateIteratorResultObject(value, done)。
    4. 执行 ! Call(promiseCapability.[[Resolve]], undefined, « iteratorResult »)。
  8. 返回 unused

27.6.3.6 AsyncGeneratorResume ( generator, completion )

The abstract operation AsyncGeneratorResume takes arguments generator (an AsyncGenerator) and completion (a Completion Record) and returns unused. It performs the following steps when called:

  1. 断言:generator.[[AsyncGeneratorState]]suspended-startsuspended-yield
  2. genContextgenerator.[[AsyncGeneratorContext]]
  3. callerContext 为正在运行的执行上下文。
  4. 挂起 callerContext
  5. generator.[[AsyncGeneratorState]] 设为 executing
  6. genContext 压入执行上下文栈;genContext 现在是正在运行的执行上下文。
  7. 恢复 genContext 的挂起求值,使用 completion 作为使其挂起的操作的结果。令 result 为恢复计算返回的 Completion Record
  8. 断言:result 永不是一个 abrupt completion。
  9. 断言:当我们在此返回时,genContext 已从执行上下文栈移除且 callerContext 是当前正在运行的执行上下文。
  10. 返回 unused

27.6.3.7 AsyncGeneratorUnwrapYieldResumption ( resumptionValue )

The abstract operation AsyncGeneratorUnwrapYieldResumption takes argument resumptionValue (a Completion Record) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. 如果 resumptionValue 不是一个 return completion,返回 ? resumptionValue
  2. awaitedCompletion(Await(resumptionValue.[[Value]]))。
  3. 如果 awaited 是一个 throw completion,返回 ? awaited
  4. 断言:awaited 是一个 normal completion。
  5. 返回 ReturnCompletion(awaited.[[Value]])。

27.6.3.8 AsyncGeneratorYield ( value )

The abstract operation AsyncGeneratorYield takes argument value (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. genContext 为正在运行的执行上下文。
  2. 断言:genContext 是一个生成器的执行上下文。
  3. generatorgenContext 的 Generator 组件的值。
  4. 断言:GetGeneratorKind() 是 async
  5. completionNormalCompletion(value)。
  6. 断言:执行上下文栈至少有两个元素。
  7. previousContext 为执行上下文栈倒数第二个元素。
  8. previousRealmpreviousContextRealm
  9. 执行 AsyncGeneratorCompleteStep(generator, completion, false, previousRealm)。
  10. queuegenerator.[[AsyncGeneratorQueue]]
  11. 如果 queue 非空,则
    1. 注:执行在不挂起生成器的情况下继续。
    2. toYieldqueue 的第一个元素。
    3. resumptionValueCompletion(toYield.[[Completion]])。
    4. 返回 ? AsyncGeneratorUnwrapYieldResumption(resumptionValue)。
  12. 否则,
    1. generator.[[AsyncGeneratorState]] 设为 suspended-yield
    2. genContext 从执行上下文栈移除并恢复栈顶执行上下文为正在运行的执行上下文。
    3. callerContext 为正在运行的执行上下文。
    4. 恢复 callerContext,传入 undefined。如果 genContext 之后再次被恢复,令 resumptionValue 为恢复时使用的 Completion Record
    5. 断言:若控制流到达此处,则 genContext 再次成为正在运行的执行上下文。
    6. 返回 ? AsyncGeneratorUnwrapYieldResumption(resumptionValue)。

27.6.3.9 AsyncGeneratorAwaitReturn ( generator )

The abstract operation AsyncGeneratorAwaitReturn takes argument generator (an AsyncGenerator) and returns unused. It performs the following steps when called:

  1. 断言:generator.[[AsyncGeneratorState]]draining-queue
  2. queuegenerator.[[AsyncGeneratorQueue]]
  3. 断言:queue 非空。
  4. nextqueue 的第一个元素。
  5. completionCompletion(next.[[Completion]])。
  6. 断言:completion 是一个 return completion。
  7. promiseCompletionCompletion(PromiseResolve(%Promise%, completion.[[Value]]))。
  8. 如果 promiseCompletion 是一个 abrupt completion,则
    1. 执行 AsyncGeneratorCompleteStep(generator, promiseCompletion, true)。
    2. 执行 AsyncGeneratorDrainQueue(generator)。
    3. 返回 unused
  9. 断言:promiseCompletion 是一个 normal completion。
  10. promisepromiseCompletion.[[Value]]
  11. fulfilledClosure 为一个具有参数 (value) 的新抽象闭包,捕获 generator 并在被调用时执行以下步骤:
    1. 断言:generator.[[AsyncGeneratorState]]draining-queue
    2. resultNormalCompletion(value)。
    3. 执行 AsyncGeneratorCompleteStep(generator, result, true)。
    4. 执行 AsyncGeneratorDrainQueue(generator)。
    5. 返回 NormalCompletion(undefined)。
  12. onFulfilledCreateBuiltinFunction(fulfilledClosure, 1, "", « »)。
  13. rejectedClosure 为一个具有参数 (reason) 的新抽象闭包,捕获 generator 并在被调用时执行以下步骤:
    1. 断言:generator.[[AsyncGeneratorState]]draining-queue
    2. resultThrowCompletion(reason)。
    3. 执行 AsyncGeneratorCompleteStep(generator, result, true)。
    4. 执行 AsyncGeneratorDrainQueue(generator)。
    5. 返回 NormalCompletion(undefined)。
  14. onRejectedCreateBuiltinFunction(rejectedClosure, 1, "", « »)。
  15. 执行 PerformPromiseThen(promise, onFulfilled, onRejected)。
  16. 返回 unused

27.6.3.10 AsyncGeneratorDrainQueue ( generator )

The abstract operation AsyncGeneratorDrainQueue takes argument generator (an AsyncGenerator) and returns unused. 它会耗尽生成器的 AsyncGeneratorQueue,直到遇到持有 return completion 的 AsyncGeneratorRequest。 It performs the following steps when called:

  1. 断言:generator.[[AsyncGeneratorState]]draining-queue
  2. queuegenerator.[[AsyncGeneratorQueue]]
  3. queue 非空时重复,
    1. nextqueue 的第一个元素。
    2. completionCompletion(next.[[Completion]])。
    3. 如果 completion 是一个 return completion,则
      1. 执行 AsyncGeneratorAwaitReturn(generator)。
      2. 返回 unused
    4. 否则,
      1. 如果 completion 是一个 normal completion,则
        1. completion 设为 NormalCompletion(undefined)。
      2. 执行 AsyncGeneratorCompleteStep(generator, completion, true)。
  4. generator.[[AsyncGeneratorState]] 设为 completed
  5. 返回 unused

27.6.3.11 CreateAsyncIteratorFromClosure ( closure, generatorBrand, generatorPrototype )

The abstract operation CreateAsyncIteratorFromClosure takes arguments closure (an Abstract Closure with no parameters), generatorBrand (a String or empty), and generatorPrototype (an Object) and returns an AsyncGenerator. It performs the following steps when called:

  1. 注:closure 可以包含 Await 操作的使用以及 Yield 操作以产出一个 IteratorResult 对象。
  2. internalSlotsList 为 « [[AsyncGeneratorState]], [[AsyncGeneratorContext]], [[AsyncGeneratorQueue]], [[GeneratorBrand]] »。
  3. generatorOrdinaryObjectCreate(generatorPrototype, internalSlotsList)。
  4. generator.[[GeneratorBrand]] 设为 generatorBrand
  5. generator.[[AsyncGeneratorState]] 设为 suspended-start
  6. callerContext 为正在运行的执行上下文。
  7. calleeContext 为一个新的执行上下文。
  8. calleeContext 的 Function 设为 null
  9. calleeContextRealm 设为当前 Realm Record
  10. calleeContext 的 ScriptOrModule 设为 callerContext 的 ScriptOrModule。
  11. 如果 callerContext 尚未被挂起,则挂起 callerContext
  12. calleeContext 压入执行上下文栈;calleeContext 现在是正在运行的执行上下文。
  13. 执行 AsyncGeneratorStart(generator, closure)。
  14. calleeContext 从执行上下文栈移除并恢复 callerContext 为正在运行的执行上下文。
  15. 返回 generator

27.7 AsyncFunction 对象

AsyncFunction 通常通过求值 AsyncFunctionDeclarationAsyncFunctionExpressionAsyncMethodAsyncArrowFunction 创建。也可通过调用内在对象 %AsyncFunction% 创建。

27.7.1 AsyncFunction 构造函数

AsyncFunction 构造函数

  • %AsyncFunction%
  • Function 的子类。
  • 当以函数(而非构造函数)方式调用时创建并初始化一个新的 AsyncFunction。故函数调用 AsyncFunction(…) 等价于以相同参数的对象创建表达式 new AsyncFunction(…)
  • 可用作类定义中 extends 子句的值。意图继承指定 AsyncFunction 行为的子类构造函数必须包含对 AsyncFunction 构造函数super 调用,以创建并初始化具有内建异步函数行为所需内部槽的子类实例。所有用于定义异步函数对象的 ECMAScript 语法形式都会创建 AsyncFunction 的直接实例。没有语法手段创建 AsyncFunction 子类的实例。

27.7.1.1 AsyncFunction ( ...parameterArgs, bodyArg )

最后一个参数(如果存在)指定异步函数的函数体(可执行代码)。之前的任意参数指定形式参数。

该函数被调用时执行以下步骤:

  1. C 为活动函数对象
  2. 如果 bodyArg 不存在,将 bodyArg 设为空字符串。
  3. 返回 ? CreateDynamicFunction(C, NewTarget, async, parameterArgs, bodyArg)。
Note
参见 20.2.1.1 的注。

27.7.2 AsyncFunction 构造函数的属性

AsyncFunction 构造函数

  • 是一个继承自 Function 构造函数的标准内建函数对象
  • 具有值为 %Function%[[Prototype]] 内部槽。
  • 具有值为 1𝔽"length" 属性。
  • 具有值为 "AsyncFunction""name" 属性。
  • 具有以下属性:

27.7.2.1 AsyncFunction.prototype

AsyncFunction.prototype 的初始值是 AsyncFunction 原型对象

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

27.7.3 AsyncFunction 原型对象的属性

AsyncFunction 原型对象

27.7.3.1 AsyncFunction.prototype.constructor

AsyncFunction.prototype.constructor 的初始值是 %AsyncFunction%

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.7.3.2 AsyncFunction.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "AsyncFunction"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

27.7.4 AsyncFunction 实例

每个 AsyncFunction 实例都是一个 ECMAScript 函数对象,并拥有 Table 28 中列出的内部槽。所有此类实例的 [[IsClassConstructor]] 内部槽的值为 false。AsyncFunction 实例不是构造函数,且没有 [[Construct]] 内部方法。由于不可构造,AsyncFunction 实例没有 prototype 属性。

每个 AsyncFunction 实例具有以下自有属性:

27.7.4.1 length

20.2.4.1 中给出的 Function 实例 "length" 属性规范同样适用于 AsyncFunction 实例。

27.7.4.2 name

20.2.4.2 中给出的 Function 实例 "name" 属性规范同样适用于 AsyncFunction 实例。

27.7.5 Async 函数的抽象操作

27.7.5.1 AsyncFunctionStart ( promiseCapability, asyncFunctionBody )

The abstract operation AsyncFunctionStart takes arguments promiseCapability (a PromiseCapability Record) and asyncFunctionBody (a FunctionBody Parse Node, an ExpressionBody Parse Node, or an Abstract Closure with no parameters) and returns unused. It performs the following steps when called:

  1. runningContext 为正在运行的执行上下文。
  2. asyncContextrunningContext 的一个副本。
  3. 注:复制执行状态是 AsyncBlockStart 恢复其执行所需。恢复一个当前正在执行的上下文是未定义的。
  4. 执行 AsyncBlockStart(promiseCapability, asyncFunctionBody, asyncContext)。
  5. 返回 unused

27.7.5.2 AsyncBlockStart ( promiseCapability, asyncBody, asyncContext )

The abstract operation AsyncBlockStart takes arguments promiseCapability (a PromiseCapability Record), asyncBody (a Parse Node or an Abstract Closure with no parameters), and asyncContext (an execution context) and returns unused. It performs the following steps when called:

  1. runningContext 为正在运行的执行上下文。
  2. closure 为一个无参数的新抽象闭包,捕获 promiseCapabilityasyncBody 并在被调用时执行以下步骤:
    1. acAsyncContext 为正在运行的执行上下文。
    2. 如果 asyncBody 是一个 Parse Node,则
      1. resultCompletion(Evaluation of asyncBody)。
    3. 否则,
      1. 断言:asyncBody 是一个无参数抽象闭包。
      2. resultCompletion(asyncBody())。
    4. 断言:若我们在此返回,异步函数要么抛出异常,要么执行了隐式或显式 return;所有等待均已完成。
    5. acAsyncContext 从执行上下文栈移除,并恢复栈顶执行上下文为正在运行的执行上下文。
    6. 如果 result 是一个 normal completion,则
      1. 执行 ! Call(promiseCapability.[[Resolve]], undefined, « undefined »)。
    7. 否则如果 result 是一个 return completion,则
      1. 执行 ! Call(promiseCapability.[[Resolve]], undefined, « result.[[Value]] »)。
    8. 否则,
      1. 断言:result 是一个 throw completion。
      2. 执行 ! Call(promiseCapability.[[Reject]], undefined, « result.[[Value]] »)。
    9. 返回 NormalCompletion(unused)。
  3. 设定 asyncContext 的代码求值状态,使得当该执行上下文恢复求值时,将无参数调用 closure
  4. asyncContext 压入执行上下文栈;asyncContext 现在是正在运行的执行上下文。
  5. 恢复 asyncContext 的挂起求值。令 result 为恢复计算返回的值。
  6. 断言:当我们在此返回时,asyncContext 已从执行上下文栈移除且 runningContext 是当前正在运行的执行上下文。
  7. 断言:result 是一个取值为 unused 的 normal completion。该值的可能来源是 Await,或当异步函数未等待任何内容时,上文步骤 2.i
  8. 返回 unused

27.7.5.3 Await ( value )

The abstract operation Await takes argument value (an ECMAScript language value) and returns either a normal completion containing either an ECMAScript language value or empty, or a throw completion. It performs the following steps when called:

  1. asyncContext 为正在运行的执行上下文。
  2. promise 为 ? PromiseResolve(%Promise%, value)。
  3. fulfilledClosure 为一个具有参数 (v) 的新抽象闭包,捕获 asyncContext 并在被调用时执行以下步骤:
    1. prevContext 为正在运行的执行上下文。
    2. 挂起 prevContext
    3. asyncContext 压入执行上下文栈;asyncContext 现在是正在运行的执行上下文。
    4. 恢复 asyncContext 的挂起求值,使用 NormalCompletion(v) 作为使其挂起的操作的结果。
    5. 断言:当我们到达此步骤时,asyncContext 已从执行上下文栈移除且 prevContext 是当前正在运行的执行上下文。
    6. 返回 NormalCompletion(undefined)。
  4. onFulfilledCreateBuiltinFunction(fulfilledClosure, 1, "", « »)。
  5. rejectedClosure 为一个具有参数 (reason) 的新抽象闭包,捕获 asyncContext 并在被调用时执行以下步骤:
    1. prevContext 为正在运行的执行上下文。
    2. 挂起 prevContext
    3. asyncContext 压入执行上下文栈;asyncContext 现在是正在运行的执行上下文。
    4. 恢复 asyncContext 的挂起求值,使用 ThrowCompletion(reason) 作为使其挂起的操作的结果。
    5. 断言:当我们到达此步骤时,asyncContext 已从执行上下文栈移除且 prevContext 是当前正在运行的执行上下文。
    6. 返回 NormalCompletion(undefined)。
  6. onRejectedCreateBuiltinFunction(rejectedClosure, 1, "", « »)。
  7. 执行 PerformPromiseThen(promise, onFulfilled, onRejected)。
  8. asyncContext 从执行上下文栈移除并恢复栈顶执行上下文为正在运行的执行上下文。
  9. callerContext 为正在运行的执行上下文。
  10. 恢复 callerContext,传入 empty。如果 asyncContext 之后再次被恢复,令 completion 为恢复时使用的 Completion Record
  11. 断言:若控制流到达此处,则 asyncContext 再次成为正在运行的执行上下文。
  12. 返回 completion

28 反射

28.1 Reflect 对象

Reflect 对象:

  • %Reflect%
  • 是全局对象 "Reflect" 属性的初始值。
  • 是一个普通对象
  • 具有值为 %Object.prototype%[[Prototype]] 内部槽。
  • 不是函数对象
  • 没有 [[Construct]] 内部方法;不能用 new 作为构造函数调用。
  • 没有 [[Call]] 内部方法;不能当作函数调用。

28.1.1 Reflect.apply ( target, thisArgument, argumentsList )

该函数被调用时执行以下步骤:

  1. 如果 IsCallable(target) 为 false,抛出 TypeError 异常。
  2. args 为 ? CreateListFromArrayLike(argumentsList)。
  3. 执行 PrepareForTailCall()。
  4. 返回 ? Call(target, thisArgument, args)。

28.1.2 Reflect.construct ( target, argumentsList [ , newTarget ] )

该函数被调用时执行以下步骤:

  1. 如果 IsConstructor(target) 为 false,抛出 TypeError 异常。
  2. 如果 newTarget 不存在,将 newTarget 设为 target
  3. 否则如果 IsConstructor(newTarget) 为 false,抛出 TypeError 异常。
  4. args 为 ? CreateListFromArrayLike(argumentsList)。
  5. 返回 ? Construct(target, args, newTarget)。

28.1.3 Reflect.defineProperty ( target, propertyKey, attributes )

该函数被调用时执行以下步骤:

  1. 如果 target 不是一个 Object,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(propertyKey)。
  3. desc 为 ? ToPropertyDescriptor(attributes)。
  4. 返回 ? target.[[DefineOwnProperty]](key, desc)。

28.1.4 Reflect.deleteProperty ( target, propertyKey )

该函数被调用时执行以下步骤:

  1. 如果 target 不是一个 Object,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(propertyKey)。
  3. 返回 ? target.[[Delete]](key)。

28.1.5 Reflect.get ( target, propertyKey [ , receiver ] )

该函数被调用时执行以下步骤:

  1. 如果 target 不是一个 Object,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(propertyKey)。
  3. 如果 receiver 不存在,则
    1. receiver 设为 target
  4. 返回 ? target.[[Get]](key, receiver)。

28.1.6 Reflect.getOwnPropertyDescriptor ( target, propertyKey )

该函数被调用时执行以下步骤:

  1. 如果 target 不是一个 Object,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(propertyKey)。
  3. desc 为 ? target.[[GetOwnProperty]](key)。
  4. 返回 FromPropertyDescriptor(desc)。

28.1.7 Reflect.getPrototypeOf ( target )

该函数被调用时执行以下步骤:

  1. 如果 target 不是一个 Object,抛出 TypeError 异常。
  2. 返回 ? target.[[GetPrototypeOf]]()

28.1.8 Reflect.has ( target, propertyKey )

该函数被调用时执行以下步骤:

  1. 如果 target 不是一个 Object,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(propertyKey)。
  3. 返回 ? target.[[HasProperty]](key)。

28.1.9 Reflect.isExtensible ( target )

该函数被调用时执行以下步骤:

  1. 如果 target 不是一个 Object,抛出 TypeError 异常。
  2. 返回 ? target.[[IsExtensible]]()

28.1.10 Reflect.ownKeys ( target )

该函数被调用时执行以下步骤:

  1. 如果 target 不是一个 Object,抛出 TypeError 异常。
  2. keys 为 ? target.[[OwnPropertyKeys]]()
  3. 返回 CreateArrayFromList(keys)。

28.1.11 Reflect.preventExtensions ( target )

该函数被调用时执行以下步骤:

  1. 如果 target 不是一个 Object,抛出 TypeError 异常。
  2. 返回 ? target.[[PreventExtensions]]()

28.1.12 Reflect.set ( target, propertyKey, V [ , receiver ] )

该函数被调用时执行以下步骤:

  1. 如果 target 不是一个 Object,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(propertyKey)。
  3. 如果 receiver 不存在,则
    1. receiver 设为 target
  4. 返回 ? target.[[Set]](key, V, receiver)。

28.1.13 Reflect.setPrototypeOf ( target, proto )

该函数被调用时执行以下步骤:

  1. 如果 target 不是一个 Object,抛出 TypeError 异常。
  2. 如果 proto 不是一个 Object 且 proto 不为 null,抛出 TypeError 异常。
  3. 返回 ? target.[[SetPrototypeOf]](proto)。

28.1.14 Reflect [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是字符串 "Reflect"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

28.2 Proxy 对象

28.2.1 Proxy 构造函数

Proxy 构造函数

  • %Proxy%
  • 是全局对象 "Proxy" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 Proxy 对象。
  • 不应作为普通函数调用;若以此方式调用将抛出异常。

28.2.1.1 Proxy ( target, handler )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 为 undefined,抛出 TypeError 异常。
  2. 返回 ? ProxyCreate(target, handler)。

28.2.2 Proxy 构造函数的属性

Proxy 构造函数

  • 有一个 [[Prototype]] 内部槽,其值为 %Function.prototype%
  • 没有 "prototype" 属性,因为 Proxy 对象没有需要初始化的 [[Prototype]] 内部槽。
  • 具有以下属性:

28.2.2.1 Proxy.revocable ( target, handler )

该函数创建一个可撤销的 Proxy 对象。

被调用时执行以下步骤:

  1. proxy 为 ? ProxyCreate(target, handler)。
  2. revokerClosure 为一个无参数的新抽象闭包(不捕获任何东西),调用时执行:
    1. F 为活动函数对象
    2. pF.[[RevocableProxy]]
    3. 如果 pnull,返回 NormalCompletion(undefined)。
    4. F.[[RevocableProxy]] 设为 null
    5. 断言:p 是一个 Proxy 奇异对象。
    6. p.[[ProxyTarget]] 设为 null
    7. p.[[ProxyHandler]] 设为 null
    8. 返回 NormalCompletion(undefined)。
  3. revokerCreateBuiltinFunction(revokerClosure, 0, "", « [[RevocableProxy]] »)。
  4. revoker.[[RevocableProxy]] 设为 proxy
    1. resultOrdinaryObjectCreate(%Object.prototype%)。
  5. 执行 ! CreateDataPropertyOrThrow(result, "proxy", proxy)。
  6. 执行 ! CreateDataPropertyOrThrow(result, "revoke", revoker)。
  7. 返回 result

28.3 模块命名空间对象

模块命名空间对象是一种模块命名空间奇异对象,提供在运行时以属性方式访问模块导出绑定的机制。没有用于模块命名空间对象的构造函数。相反,对每个由包含 NameSpaceImportImportDeclaration 导入的模块创建这样的对象。

10.4.6 指定的属性外,每个模块命名空间对象还有以下自有属性:

28.3.1 %Symbol.toStringTag%

%Symbol.toStringTag% 属性的初始值是字符串 "Module"

该属性具有 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

29 内存模型

内存一致性模型(或称 内存模型)规定了共享数据块事件的可能排序,这些事件通过访问由 SharedArrayBuffer 支持的 TypedArray 实例以及调用 Atomics 对象的方法产生。当程序无数据竞争(定义见下)时,事件的排序表现为顺序一致,即各代理动作的交错。当程序存在数据竞争时,共享内存操作可能表现为非顺序一致。例如,程序可能出现因果违反行为和其他令人惊讶的现象。这些惊讶源于编译器变换和 CPU 设计(例如乱序执行与推测执行)。内存模型定义了程序表现顺序一致行为的精确条件,以及数据竞争中可能读取的值。换言之,不存在未定义行为。

内存模型以关系约束形式定义,这些约束作用于在求值过程中由对 SharedArrayBuffer 的抽象操作或 Atomics 对象的方法引入的事件。

Note

本节提供了对 SharedArrayBuffer 抽象操作引入事件的公理化模型。需强调该模型不同于规范其余部分,并非可算法表达。抽象操作非确定性引入事件,是 ECMAScript 求值的操作语义与内存模型公理语义之间的接口。事件语义通过考虑一次求值中所有事件组成的图来定义。它们既非静态语义,也非运行时语义。目前没有演示的算法实现,而是一组约束,用来判定某事件图是否被允许。

29.1 内存模型基础

共享内存访问(读与写)分为两类:原子访问和数据访问(下文定义)。原子访问是顺序一致的,即存在一个所有代理都同意的严格全序。非原子访问在所有代理之间没有严格全序,即无序。

Note 1

不支持比顺序一致更弱、比无序更强的次序(如 release-acquire)。

共享数据块事件ReadSharedMemoryWriteSharedMemoryReadModifyWriteSharedMemory Record

Table 94: ReadSharedMemory 事件字段
字段名 取值 含义
[[Order]] seq-cstunordered 内存模型对该事件保证的最弱次序。
[[NoTear]] 一个 Boolean 该事件是否允许从多个范围与其相等的写事件读取。
[[Block]] 一个共享数据块 事件操作的块。
[[ByteIndex]] 一个非负整数 [[Block]] 中读取的字节地址。
[[ElementSize]] 一个非负整数 读取的大小。
Table 95: WriteSharedMemory 事件字段
字段名 取值 含义
[[Order]] seq-cstunorderedinit 内存模型对该事件保证的最弱次序。
[[NoTear]] 一个 Boolean 该事件是否允许被多个范围与其相等的读事件读取。
[[Block]] 一个共享数据块 事件操作的块。
[[ByteIndex]] 一个非负整数 [[Block]] 中写入的字节地址。
[[ElementSize]] 一个非负整数 写入的大小。
[[Payload]] 一个字节值List 供其他事件读取的字节值列表。
Table 96: ReadModifyWriteSharedMemory 事件字段
字段名 取值 含义
[[Order]] seq-cst 读-改-写事件始终顺序一致。
[[NoTear]] true 读-改-写事件不可撕裂。
[[Block]] 一个共享数据块 事件操作的块。
[[ByteIndex]] 一个非负整数 [[Block]] 中读改写的字节地址。
[[ElementSize]] 一个非负整数 读改写的大小。
[[Payload]] 一个字节值List 传递给 [[ModifyOp]]字节值列表。
[[ModifyOp]] 一个读-改-写修改函数 从读取的字节值 List[[Payload]] 返回修改后字节值 List 的抽象闭包。

这些事件由抽象操作或 Atomics 对象的方法引入。

某些操作还可能引入 Synchronize 事件。一个 Synchronize 事件 没有字段,仅用于直接约束其他事件的允许顺序。

除共享数据块事件与 Synchronize 事件外,还存在宿主特定事件。

令 ReadSharedMemory、WriteSharedMemory 或 ReadModifyWriteSharedMemory 事件的范围为从其 [[ByteIndex]][[ByteIndex]] + [[ElementSize]] - 1 的连续整数集合。两个事件的范围相等当且仅当它们具有相同 [[Block]] 且范围逐元素相等。若两个事件有相同 [[Block]]、范围不等且交集非空则范围重叠。若两个事件没有相同 [[Block]] 或其范围既不相等也不重叠则范围不相交。

Note 2

应考虑的宿主特定同步事件示例:将一个 SharedArrayBuffer 从一代理发送至另一代理(例如浏览器中的 postMessage),代理的启动与停止,以及通过共享内存之外的通道在代理集群内通信。对于某次执行 execution,这些事件由宿主通过 host-synchronizes-with 严格偏序提供。此外,宿主可以将宿主特定同步事件加入 execution.[[EventList]] 以参与 is-agent-order-before 关系。

候选执行中的事件由下列定义的关系排序。

29.2 代理事件记录

Agent Events Record 是具有以下字段的 Record

Table 97: Agent Events Record 字段
字段名 取值 含义
[[AgentSignifier]] 一个代理标识符 其求值导致此排序的代理。
[[EventList]] 一个事件的 List 求值过程中事件被追加到该列表。
[[AgentSynchronizesWith]] 一对 Synchronize 事件List 由操作语义引入的同步关系。

29.3 选定值记录

Chosen Value Record 是具有以下字段的 Record

Table 98: Chosen Value Record 字段
字段名 取值 含义
[[Event]] 一个共享数据块事件 为该选定值引入的 ReadSharedMemoryReadModifyWriteSharedMemory 事件。
[[ChosenValue]] 一个字节值List 求值过程中非确定性选出的字节。

29.4 候选执行

代理集群求值的一个 candidate execution 是具有以下字段的 Record

Table 99: Candidate Execution Record 字段
字段名 取值 含义
[[EventsRecords]] Agent Events RecordList 映射一个代理到求值过程中追加的事件列表。
[[ChosenValues]] Chosen Value RecordList ReadSharedMemoryReadModifyWriteSharedMemory 事件映射为求值过程中选定的字节值列表。

empty candidate execution 是各字段为空 List 的候选执行 Record

29.5 内存模型的抽象操作

29.5.1 EventSet ( execution )

The abstract operation EventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. events 为一个空 Set。
  2. 对于 execution.[[EventsRecords]] 中的每个 Agent Events Record aer,执行
    1. aer.[[EventList]] 中的每个事件 E,执行
      1. E 加入 events
  3. 返回 events

29.5.2 SharedDataBlockEventSet ( execution )

The abstract operation SharedDataBlockEventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. events 为一个空 Set。
  2. EventSet(execution) 中的每个事件 E,执行
    1. 如果 EReadSharedMemoryWriteSharedMemoryReadModifyWriteSharedMemory 事件,将 E 加入 events
  3. 返回 events

29.5.3 HostEventSet ( execution )

The abstract operation HostEventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. events 为一个空 Set。
  2. EventSet(execution) 中的每个事件 E,执行
    1. 如果 E 不在 SharedDataBlockEventSet(execution) 中,将 E 加入 events
  3. 返回 events

29.5.4 ComposeWriteEventBytes ( execution, byteIndex, Ws )

The abstract operation ComposeWriteEventBytes takes arguments execution (a candidate execution), byteIndex (a non-negative integer), and Ws (a List of either WriteSharedMemory or ReadModifyWriteSharedMemory events) and returns a List of byte values. It performs the following steps when called:

  1. byteLocationbyteIndex
  2. bytesRead 为一个新的空 List
  3. Ws 中每个元素 W,执行
    1. 断言:W 的范围包含 byteLocation
    2. payloadIndexbyteLocation - W.[[ByteIndex]]
    3. 如果 WWriteSharedMemory 事件,则
      1. byteW.[[Payload]][payloadIndex]。
    4. 否则,
      1. 断言:WReadModifyWriteSharedMemory 事件。
      2. bytesValueOfReadEvent(execution, W)。
      3. bytesModifiedW.[[ModifyOp]](bytes, W.[[Payload]])。
      4. bytebytesModified[payloadIndex]。
    5. byte 追加到 bytesRead
    6. byteLocation 设为 byteLocation + 1。
  4. 返回 bytesRead
Note 1

读-改-写修改 [[ModifyOp]] 由 Atomics 对象上引入 ReadModifyWriteSharedMemory 事件的函数属性给出。

Note 2

抽象操作将写事件的 List 组合为字节值List。用于 ReadSharedMemoryReadModifyWriteSharedMemory 事件的事件语义。

29.5.5 ValueOfReadEvent ( execution, R )

The abstract operation ValueOfReadEvent takes arguments execution (a candidate execution) and R (a ReadSharedMemory or ReadModifyWriteSharedMemory event) and returns a List of byte values. It performs the following steps when called:

  1. Wsreads-bytes-from(R) in execution
  2. 断言:Ws 是长度等于 R.[[ElementSize]]WriteSharedMemoryReadModifyWriteSharedMemory 事件 List
  3. 返回 ComposeWriteEventBytes(execution, R.[[ByteIndex]], Ws)。

29.6 候选执行的关系

以下关系与数学函数以特定候选执行为参数,对其事件排序。

29.6.1 is-agent-order-before

对候选执行 execution,其 is-agent-order-before 关系是满足以下条件的事件上的最小关系。

  • 对事件 ED,若存在 execution.[[EventsRecords]] 中的某个 Agent Events Record aer,使得 aer.[[EventList]] 同时包含 EDE 在该 List 顺序上位于 D 之前,则 Eexecution 中 is-agent-order-before D
Note

每个代理在求值期间按代理内严格全序引入事件。这些严格全序的并集即本关系。

29.6.2 reads-bytes-from

对候选执行 execution,其 reads-bytes-from 函数是一个数学函数,将 SharedDataBlockEventSet(execution) 中的事件映射到该集合中事件的 List,满足下列条件。

一个候选执行总能容纳一个 reads-bytes-from 函数。

29.6.3 reads-from

对候选执行 execution,其 reads-from 关系是满足以下条件的事件上的最小关系。

29.6.4 host-synchronizes-with

对候选执行 execution,其 host-synchronizes-with 关系是宿主提供的、在宿主特定事件上的严格偏序,至少满足:

Note 1

对候选执行 execution 中两个宿主特定事件 ED,若 E host-synchronizes-with D,则 E happens-before D

Note 2

该关系允许宿主提供额外同步机制,如在 HTML workers 间使用 postMessage

29.6.5 synchronizes-with

对候选执行 execution,其 synchronizes-with 关系是满足以下条件的事件上的最小关系:

  • 对事件 RW,若 R reads-from W in executionR.[[Order]]seq-cstW.[[Order]]seq-cstRW 范围相等,则 W synchronizes-with R
  • execution.[[EventsRecords]] 的每个元素 eventsRecord,以下成立:
    • eventsRecord.[[AgentSynchronizesWith]] 包含 (S, Sw),则 S synchronizes-with Sw
  • 对事件 ED,若 execution.[[HostSynchronizesWith]] 包含 (E, D),则 E synchronizes-with D
Note 1

内存模型文献惯例,写事件 synchronizes-with 读事件,而不是反之。

Note 2

init 事件不参与该关系,而由 happens-before 直接约束。

Note 3

并非所有通过 reads-from 关联的 seq-cst 事件都由 synchronizes-with 关联,只有范围相等者才关联。

Note 4

共享数据块事件 W synchronizes-with RR 仍可 reads-fromW 之外的写。

29.6.6 happens-before

对候选执行 execution,其 happens-before 关系是满足以下条件的事件上的最小关系。

Note

因 happens-before 是 agent-order 的超集,候选执行与 ECMAScript 的单线程求值语义一致。

29.7 合法执行的性质

29.7.1 有效选定读取

候选执行 execution 具有有效选定读取当且仅当以下算法返回 true

  1. SharedDataBlockEventSet(execution) 中每个 ReadSharedMemoryReadModifyWriteSharedMemory 事件 R,执行
    1. chosenValueRecordexecution.[[ChosenValues]][[Event]] 字段为 R 的元素。
    2. chosenValuechosenValueRecord.[[ChosenValue]]
    3. readValueValueOfReadEvent(execution, R)。
    4. chosenLenchosenValue 的元素个数。
    5. readLenreadValue 的元素个数。
    6. 如果 chosenLenreadLen,则
      1. 返回 false
    7. 如果 存在整数 i 属于 [0, chosenLen) 使 chosenValue[i] ≠ readValue[i],则
      1. 返回 false
  2. 返回 true

29.7.2 相干读取

候选执行 execution 具有相干读取当且仅当以下算法返回 true

  1. SharedDataBlockEventSet(execution) 中每个 ReadSharedMemoryReadModifyWriteSharedMemory 事件 R,执行
    1. Wsreads-bytes-from(R) in execution
    2. byteLocationR.[[ByteIndex]]
    3. Ws 中每个元素 W,执行
      1. 如果 R happens-before W,则
        1. 返回 false
      2. 如果 存在 WriteSharedMemoryReadModifyWriteSharedMemory 事件 V,其范围包含 byteLocation,且 W happens-before VV happens-before R,则
        1. 返回 false
      3. byteLocation 设为 byteLocation + 1。
  2. 返回 true

29.7.3 无撕裂读取

候选执行 execution 具有无撕裂读取当且仅当以下算法返回 true

  1. SharedDataBlockEventSet(execution) 中每个 ReadSharedMemoryReadModifyWriteSharedMemory 事件 R,执行
    1. 如果 R.[[NoTear]]true,则
      1. 断言:R.[[ByteIndex]] 除以 R.[[ElementSize]] 的余数为 0。
      2. 对每个事件 W(满足 R reads-from WW.[[NoTear]]true),执行
        1. 如果 RW 范围相等且存在事件 V 使得 VW 范围相等、V.[[NoTear]]trueWV 非同一共享数据块事件R reads-from V,则
          1. 返回 false
  2. 返回 true
Note

事件的 [[NoTear]] 字段为 true 表示该事件通过访问整数 TypedArray 引入;为 false 则表示通过访问浮点 TypedArray 或 DataView 引入。

直观地,该要求表示当内存范围以整数 TypedArray 对齐方式访问时,在与其他范围相等写事件的数据竞争中,必须由“单个”写事件“胜出”。更精确地:对齐的读事件不能读取由多个范围相等写事件的字节混合组成的值。然而对齐读事件仍可能读取来自范围重叠写事件的字节。

29.7.4 顺序一致原子

对候选执行 executionis-memory-order-beforeEventSet(execution) 所有事件的严格全序,且满足:

若候选执行存在一个 is-memory-order-before 关系,则其具有顺序一致原子。

Note 3

虽然 is-memory-order-before 包含 EventSet(execution) 的所有事件,但未被 happens-beforesynchronizes-with 约束的事件可在该顺序中任意位置出现。

29.7.5 合法执行

候选执行 execution 是合法执行(或简称执行)当且仅当以下各项均为真:

  • 宿主execution 提供 host-synchronizes-with 关系。
  • execution 存在一个为严格偏序happens-before 关系。
  • execution 具有有效选定读取。
  • execution 具有相干读取。
  • execution 具有无撕裂读取。
  • execution 具有顺序一致原子。

所有程序至少有一个合法执行。

29.8 竞争

对执行 execution 及其中 SharedDataBlockEventSet(execution) 的事件 ED,若以下算法返回 true,则 ED 处于一个 race 中。

  1. 如果 ED 不是同一共享数据块事件,则
    1. 如果并非 E happens-before DD happens-before E 同时成立,则
      1. 如果 ED 均为 WriteSharedMemoryReadModifyWriteSharedMemory 事件且范围不相交为假,则
        1. 返回 true
      2. 如果 E reads-from DD reads-from E,则
        1. 返回 true
  2. 返回 false

29.9 数据竞争

对执行 execution 及其中 SharedDataBlockEventSet(execution) 的事件 ED,若以下算法返回 true,则 ED 处于一个 data race 中。

  1. 如果 EDexecution 中处于 race,则
    1. 如果 E.[[Order]] 不是 seq-cstD.[[Order]] 不是 seq-cst,则
      1. 返回 true
    2. 如果 ED 范围重叠,则
      1. 返回 true
  2. 返回 false

29.10 数据竞争自由

执行 executiondata race free 当且仅当 SharedDataBlockEventSet(execution) 中不存在两事件处于数据竞争。

若程序所有执行均数据竞争自由,则该程序为数据竞争自由程序。

内存模型保证数据竞争自由程序所有事件的顺序一致性。

29.11 共享内存指南

Note 1

以下是面向使用共享内存的 ECMAScript 程序员的指南。

推荐保持程序数据竞争自由,即使同一内存位置不可能同时发生并发非原子操作。数据竞争自由程序具有交错语义:每个代理的每一步求值语义互相交错。此时无需理解内存模型细节,细节对编写 ECMAScript 的直觉帮助有限

更一般地,即便程序非数据竞争自由,也可能具可预测行为,只要原子操作不参与任何数据竞争,且竞争操作的访问大小一致。最简单方式是保证原子与非原子操作使用不同内存单元,且不同大小的原子访问不同时访问相同单元。实质上,程序应尽量将共享内存视为强类型。仍不可依赖竞争的非原子访问的顺序与时序,但若内存被强类型对待,竞争访问不会“撕裂”(其值的位不会混合)。

Note 2

以下是面向为使用共享内存程序编写编译器变换的 ECMAScript 实现者的指南。

希望在多代理环境中允许大多数在单代理环境有效的程序变换,以确保多代理程序中每个代理的性能与单代理时一样。此类变换往往难以判定。我们概述若干应视为规范性的规则(由内存模型蕴含或比其更强),但不一定穷尽。规则适用于在组成 is-agent-order-before 关系的事件引入之前的程序变换。

agent-order sliceis-agent-order-before 关系中属于单一代理的子集。

令读取事件的 possible read values 为该事件在所有合法执行中 ValueOfReadEvent 的所有值集合。

在无共享内存时有效的任意 agent-order slice 变换在存在共享内存时亦有效,以下例外:

  • 原子操作不可动摇:程序变换不得使 agent-order slice 中的 seq-cst 事件与其 unordered 操作重排,亦不得重排其 seq-cst 操作之间的顺序,也不得移除 seq-cst 操作。

    (实践中,该限制迫使编译器假设每个 seq-cst 操作均为同步点并被包含在最终 is-memory-order-before 关系中。)

  • 读取必须稳定:任一共享内存读取在一次执行中只能观察到单一值。

    (例如,若语义上单次读取被多次执行,则程序只能观察其中一个值;某些再物化变换可违反此规则。)

  • 写入必须稳定:所有可观察写入必须源于该次执行的程序语义。

    (例如,变换不能引入程序本不可能的写,如对更大位置的读改写来写较小数据,写入程序原本不可写的值,或将刚读取的值写回其位置且期间可能被他代理覆盖。)

  • 可能读取值不得为空:程序变换不能使某共享内存读取的可能读取值集合为空。

    (反直觉地,该规则实际限制对写的变换,因为写的作用仅在被读事件读取。例如写可移动、合并,有时在两个 seq-cst 操作间重排,但不可删掉所有更新某位置的写,必须保留一个。)

仍然有效的变换示例:合并多个对同一位置的非原子读;重排非原子读;引入推测非原子读;合并多个对同一位置的非原子写;对不同位置的非原子写重排;将非原子读外提出循环(即使影响终止性)。注意别名 TypedArrays 使证明位置不同变得困难。

Note 3

以下是面向为共享内存访问生成机器码的 ECMAScript 实现者的指南。

内存模型不弱于 ARM 或 Power 的架构,非原子存取可编译为裸存取。原子存取可编译为保证顺序一致的指令。若不存在此类指令,则使用内存屏障(如在裸存/取两侧放置)。读改写操作可编译为目标架构的读改写指令,如 x86 上的 LOCK 前缀指令,ARM 的 load-exclusive/store-exclusive,Power 的 load-link/store-conditional。

具体而言,内存模型旨在允许如下代码生成:

  • 程序中的每个原子操作都被视为必要。
  • 原子操作不与其他原子或非原子操作重排。
  • 函数被假定执行原子操作。
  • 原子操作不以更大数据的读改写实现,而在不支持相应大小原子时使用非锁自由原子(假定平台具备所有必要尺寸的普通内存访问)。

朴素代码生成模式:

  • 常规加载与存储 -> 单条加载/存储指令。
  • 锁自由原子加载与存储 -> 全栅栏,常规加载/存储,再全栅栏。
  • 锁自由原子读改写 -> 全栅栏,原子读改写指令序列,全栅栏。
  • 非锁自由原子 -> 自旋锁获取,全栅栏,一系列非原子读写,全栅栏,自旋锁释放。

该映射在原子操作与非原子写或不同大小原子不竞争下正确;若竞争,内存模型将相关原子操作降级为非原子。但此朴素映射很强:允许原子操作充当顺序一致栅栏,这超出模型实际保证。

局部优化在模型约束下也是允许的,例如:

  • 平台相关的消除冗余栅栏(例如 x86 上锁自由原子读写的栅栏多可省略,除写后的栅栏)。
  • 多数现代平台支持所需数据大小的锁自由原子;若需非锁自由原子,可将原子操作体周围栅栏折叠进锁操作;最简单是每个 SharedArrayBuffer 一个锁字。
  • 更复杂的局部优化,如合并背靠背栅栏;x86 上分隔原子写的栅栏可省,因写后所需栅栏仅用于分隔与后续读。

Annex A (informative) 语法概要

A.1 词法语法

SourceCharacter :: 任意 Unicode 码点 (any Unicode code point) InputElementDiv :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator RightBracePunctuator InputElementRegExp :: WhiteSpace LineTerminator Comment CommonToken RightBracePunctuator RegularExpressionLiteral InputElementRegExpOrTemplateTail :: WhiteSpace LineTerminator Comment CommonToken RegularExpressionLiteral TemplateSubstitutionTail InputElementTemplateTail :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator TemplateSubstitutionTail InputElementHashbangOrRegExp :: WhiteSpace LineTerminator Comment CommonToken HashbangComment RegularExpressionLiteral WhiteSpace :: <TAB> <VT> <FF> <ZWNBSP> <USP> LineTerminator :: <LF> <CR> <LS> <PS> LineTerminatorSequence :: <LF> <CR> [lookahead ≠ <LF>] <LS> <PS> <CR> <LF> Comment :: MultiLineComment SingleLineComment MultiLineComment :: /* MultiLineCommentCharsopt */ MultiLineCommentChars :: MultiLineNotAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt PostAsteriskCommentChars :: MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt MultiLineNotAsteriskChar :: SourceCharacter but not * MultiLineNotForwardSlashOrAsteriskChar :: SourceCharacter but not one of / or * SingleLineComment :: // SingleLineCommentCharsopt SingleLineCommentChars :: SingleLineCommentChar SingleLineCommentCharsopt SingleLineCommentChar :: SourceCharacter but not LineTerminator HashbangComment :: #! SingleLineCommentCharsopt CommonToken :: IdentifierName PrivateIdentifier Punctuator NumericLiteral StringLiteral Template PrivateIdentifier :: # IdentifierName IdentifierName :: IdentifierStart IdentifierName IdentifierPart IdentifierStart :: IdentifierStartChar \ UnicodeEscapeSequence IdentifierPart :: IdentifierPartChar \ UnicodeEscapeSequence IdentifierStartChar :: UnicodeIDStart $ _ IdentifierPartChar :: UnicodeIDContinue $ AsciiLetter :: one of a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z UnicodeIDStart :: any Unicode code point with the Unicode property “ID_Start” UnicodeIDContinue :: any Unicode code point with the Unicode property “ID_Continue” ReservedWord :: one of await break case catch class const continue debugger default delete do else enum export extends false finally for function if import in instanceof new null return super switch this throw true try typeof var void while with yield Punctuator :: OptionalChainingPunctuator OtherPunctuator OptionalChainingPunctuator :: ?. [lookahead ∉ DecimalDigit] OtherPunctuator :: one of { ( ) [ ] . ... ; , < > <= >= == != === !== + - * % ** ++ -- << >> >>> & | ^ ! ~ && || ?? ? : = += -= *= %= **= <<= >>= >>>= &= |= ^= &&= ||= ??= => DivPunctuator :: / /= RightBracePunctuator :: } NullLiteral :: null BooleanLiteral :: true false NumericLiteralSeparator :: _ NumericLiteral :: DecimalLiteral DecimalBigIntegerLiteral NonDecimalIntegerLiteral[+Sep] NonDecimalIntegerLiteral[+Sep] BigIntLiteralSuffix LegacyOctalIntegerLiteral DecimalBigIntegerLiteral :: 0 BigIntLiteralSuffix NonZeroDigit DecimalDigits[+Sep]opt BigIntLiteralSuffix NonZeroDigit NumericLiteralSeparator DecimalDigits[+Sep] BigIntLiteralSuffix NonDecimalIntegerLiteral[Sep] :: BinaryIntegerLiteral[?Sep] OctalIntegerLiteral[?Sep] HexIntegerLiteral[?Sep] BigIntLiteralSuffix :: n DecimalLiteral :: DecimalIntegerLiteral . DecimalDigits[+Sep]opt ExponentPart[+Sep]opt . DecimalDigits[+Sep] ExponentPart[+Sep]opt DecimalIntegerLiteral ExponentPart[+Sep]opt DecimalIntegerLiteral :: 0 NonZeroDigit NonZeroDigit NumericLiteralSeparatoropt DecimalDigits[+Sep] NonOctalDecimalIntegerLiteral DecimalDigits[Sep] :: DecimalDigit DecimalDigits[?Sep] DecimalDigit [+Sep] DecimalDigits[+Sep] NumericLiteralSeparator DecimalDigit DecimalDigit :: one of 0 1 2 3 4 5 6 7 8 9 NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9 ExponentPart[Sep] :: ExponentIndicator SignedInteger[?Sep] ExponentIndicator :: one of e E SignedInteger[Sep] :: DecimalDigits[?Sep] + DecimalDigits[?Sep] - DecimalDigits[?Sep] BinaryIntegerLiteral[Sep] :: 0b BinaryDigits[?Sep] 0B BinaryDigits[?Sep] BinaryDigits[Sep] :: BinaryDigit BinaryDigits[?Sep] BinaryDigit [+Sep] BinaryDigits[+Sep] NumericLiteralSeparator BinaryDigit BinaryDigit :: one of 0 1 OctalIntegerLiteral[Sep] :: 0o OctalDigits[?Sep] 0O OctalDigits[?Sep] OctalDigits[Sep] :: OctalDigit OctalDigits[?Sep] OctalDigit [+Sep] OctalDigits[+Sep] NumericLiteralSeparator OctalDigit LegacyOctalIntegerLiteral :: 0 OctalDigit LegacyOctalIntegerLiteral OctalDigit NonOctalDecimalIntegerLiteral :: 0 NonOctalDigit LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit NonOctalDecimalIntegerLiteral DecimalDigit LegacyOctalLikeDecimalIntegerLiteral :: 0 OctalDigit LegacyOctalLikeDecimalIntegerLiteral OctalDigit OctalDigit :: one of 0 1 2 3 4 5 6 7 NonOctalDigit :: one of 8 9 HexIntegerLiteral[Sep] :: 0x HexDigits[?Sep] 0X HexDigits[?Sep] HexDigits[Sep] :: HexDigit HexDigits[?Sep] HexDigit [+Sep] HexDigits[+Sep] NumericLiteralSeparator HexDigit HexDigit :: one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F StringLiteral :: " DoubleStringCharactersopt " ' SingleStringCharactersopt ' DoubleStringCharacters :: DoubleStringCharacter DoubleStringCharactersopt SingleStringCharacters :: SingleStringCharacter SingleStringCharactersopt DoubleStringCharacter :: SourceCharacter but not one of " or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation SingleStringCharacter :: SourceCharacter but not one of ' or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation LineContinuation :: \ LineTerminatorSequence EscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] LegacyOctalEscapeSequence NonOctalDecimalEscapeSequence HexEscapeSequence UnicodeEscapeSequence CharacterEscapeSequence :: SingleEscapeCharacter NonEscapeCharacter SingleEscapeCharacter :: one of ' " \ b f n r t v NonEscapeCharacter :: SourceCharacter but not one of EscapeCharacter or LineTerminator EscapeCharacter :: SingleEscapeCharacter DecimalDigit x u LegacyOctalEscapeSequence :: 0 [lookahead ∈ { 8, 9 }] NonZeroOctalDigit [lookahead ∉ OctalDigit] ZeroToThree OctalDigit [lookahead ∉ OctalDigit] FourToSeven OctalDigit ZeroToThree OctalDigit OctalDigit NonZeroOctalDigit :: OctalDigit but not 0 ZeroToThree :: one of 0 1 2 3 FourToSeven :: one of 4 5 6 7 NonOctalDecimalEscapeSequence :: one of 8 9 HexEscapeSequence :: x HexDigit HexDigit UnicodeEscapeSequence :: u Hex4Digits u{ CodePoint } Hex4Digits :: HexDigit HexDigit HexDigit HexDigit RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags RegularExpressionBody :: RegularExpressionFirstChar RegularExpressionChars RegularExpressionChars :: [empty] RegularExpressionChars RegularExpressionChar RegularExpressionFirstChar :: RegularExpressionNonTerminator but not one of * or \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionChar :: RegularExpressionNonTerminator but not one of \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionBackslashSequence :: \ RegularExpressionNonTerminator RegularExpressionNonTerminator :: SourceCharacter but not LineTerminator RegularExpressionClass :: [ RegularExpressionClassChars ] RegularExpressionClassChars :: [empty] RegularExpressionClassChars RegularExpressionClassChar RegularExpressionClassChar :: RegularExpressionNonTerminator but not one of ] or \ RegularExpressionBackslashSequence RegularExpressionFlags :: [empty] RegularExpressionFlags IdentifierPartChar Template :: NoSubstitutionTemplate TemplateHead NoSubstitutionTemplate :: ` TemplateCharactersopt ` TemplateHead :: ` TemplateCharactersopt ${ TemplateSubstitutionTail :: TemplateMiddle TemplateTail TemplateMiddle :: } TemplateCharactersopt ${ TemplateTail :: } TemplateCharactersopt ` TemplateCharacters :: TemplateCharacter TemplateCharactersopt TemplateCharacter :: $ [lookahead ≠ {] \ TemplateEscapeSequence \ NotEscapeSequence LineContinuation LineTerminatorSequence SourceCharacter but not one of ` or \ or $ or LineTerminator TemplateEscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] HexEscapeSequence UnicodeEscapeSequence NotEscapeSequence :: 0 DecimalDigit DecimalDigit but not 0 x [lookahead ∉ HexDigit] x HexDigit [lookahead ∉ HexDigit] u [lookahead ∉ HexDigit] [lookahead ≠ {] u HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit HexDigit [lookahead ∉ HexDigit] u { [lookahead ∉ HexDigit] u { NotCodePoint [lookahead ∉ HexDigit] u { CodePoint [lookahead ∉ HexDigit] [lookahead ≠ }] NotCodePoint :: HexDigits[~Sep] but only if the MV of HexDigits > 0x10FFFF CodePoint :: HexDigits[~Sep] but only if the MV of HexDigits ≤ 0x10FFFF

A.2 表达式

IdentifierReference[Yield, Await] : Identifier [~Yield] yield [~Await] await BindingIdentifier[Yield, Await] : Identifier yield await LabelIdentifier[Yield, Await] : Identifier [~Yield] yield [~Await] await Identifier : IdentifierName but not ReservedWord PrimaryExpression[Yield, Await] : this IdentifierReference[?Yield, ?Await] Literal ArrayLiteral[?Yield, ?Await] ObjectLiteral[?Yield, ?Await] FunctionExpression ClassExpression[?Yield, ?Await] GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral[?Yield, ?Await, ~Tagged] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[Yield, Await] : ( Expression[+In, ?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ) ( ) ( ... BindingIdentifier[?Yield, ?Await] ) ( ... BindingPattern[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingIdentifier[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingPattern[?Yield, ?Await] )

当处理产生式实例
PrimaryExpression[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
时,CoverParenthesizedExpressionAndArrowParameterList 的解释使用以下语法进行细化:

ParenthesizedExpression[Yield, Await] : ( Expression[+In, ?Yield, ?Await] )

 

Literal : NullLiteral BooleanLiteral NumericLiteral StringLiteral ArrayLiteral[Yield, Await] : [ Elisionopt ] [ ElementList[?Yield, ?Await] ] [ ElementList[?Yield, ?Await] , Elisionopt ] ElementList[Yield, Await] : Elisionopt AssignmentExpression[+In, ?Yield, ?Await] Elisionopt SpreadElement[?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt AssignmentExpression[+In, ?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt SpreadElement[?Yield, ?Await] Elision : , Elision , SpreadElement[Yield, Await] : ... AssignmentExpression[+In, ?Yield, ?Await] ObjectLiteral[Yield, Await] : { } { PropertyDefinitionList[?Yield, ?Await] } { PropertyDefinitionList[?Yield, ?Await] , } PropertyDefinitionList[Yield, Await] : PropertyDefinition[?Yield, ?Await] PropertyDefinitionList[?Yield, ?Await] , PropertyDefinition[?Yield, ?Await] PropertyDefinition[Yield, Await] : IdentifierReference[?Yield, ?Await] CoverInitializedName[?Yield, ?Await] PropertyName[?Yield, ?Await] : AssignmentExpression[+In, ?Yield, ?Await] MethodDefinition[?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] PropertyName[Yield, Await] : LiteralPropertyName ComputedPropertyName[?Yield, ?Await] LiteralPropertyName : IdentifierName StringLiteral NumericLiteral ComputedPropertyName[Yield, Await] : [ AssignmentExpression[+In, ?Yield, ?Await] ] CoverInitializedName[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await] Initializer[In, Yield, Await] : = AssignmentExpression[?In, ?Yield, ?Await] TemplateLiteral[Yield, Await, Tagged] : NoSubstitutionTemplate SubstitutionTemplate[?Yield, ?Await, ?Tagged] SubstitutionTemplate[Yield, Await, Tagged] : TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged] TemplateSpans[Yield, Await, Tagged] : TemplateTail TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateTail TemplateMiddleList[Yield, Await, Tagged] : TemplateMiddle Expression[+In, ?Yield, ?Await] TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await] MemberExpression[Yield, Await] : PrimaryExpression[?Yield, ?Await] MemberExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] MemberExpression[?Yield, ?Await] . IdentifierName MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] SuperProperty[?Yield, ?Await] MetaProperty new MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] MemberExpression[?Yield, ?Await] . PrivateIdentifier SuperProperty[Yield, Await] : super [ Expression[+In, ?Yield, ?Await] ] super . IdentifierName MetaProperty : NewTarget ImportMeta NewTarget : new . target ImportMeta : import . meta NewExpression[Yield, Await] : MemberExpression[?Yield, ?Await] new NewExpression[?Yield, ?Await] CallExpression[Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] SuperCall[?Yield, ?Await] ImportCall[?Yield, ?Await] CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await] CallExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] CallExpression[?Yield, ?Await] . IdentifierName CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] CallExpression[?Yield, ?Await] . PrivateIdentifier

当处理产生式实例
CallExpression[Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await]
时,CoverCallExpressionAndAsyncArrowHead 的解释使用以下语法进行细化:

CallMemberExpression[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

 

SuperCall[Yield, Await] : super Arguments[?Yield, ?Await] ImportCall[Yield, Await] : import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) Arguments[Yield, Await] : ( ) ( ArgumentList[?Yield, ?Await] ) ( ArgumentList[?Yield, ?Await] , ) ArgumentList[Yield, Await] : AssignmentExpression[+In, ?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , ... AssignmentExpression[+In, ?Yield, ?Await] OptionalExpression[Yield, Await] : MemberExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalChain[Yield, Await] : ?. Arguments[?Yield, ?Await] ?. [ Expression[+In, ?Yield, ?Await] ] ?. IdentifierName ?. TemplateLiteral[?Yield, ?Await, +Tagged] ?. PrivateIdentifier OptionalChain[?Yield, ?Await] Arguments[?Yield, ?Await] OptionalChain[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] OptionalChain[?Yield, ?Await] . IdentifierName OptionalChain[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] OptionalChain[?Yield, ?Await] . PrivateIdentifier LeftHandSideExpression[Yield, Await] : NewExpression[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalExpression[?Yield, ?Await] UpdateExpression[Yield, Await] : LeftHandSideExpression[?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] ++ LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] -- ++ UnaryExpression[?Yield, ?Await] -- UnaryExpression[?Yield, ?Await] UnaryExpression[Yield, Await] : UpdateExpression[?Yield, ?Await] delete UnaryExpression[?Yield, ?Await] void UnaryExpression[?Yield, ?Await] typeof UnaryExpression[?Yield, ?Await] + UnaryExpression[?Yield, ?Await] - UnaryExpression[?Yield, ?Await] ~ UnaryExpression[?Yield, ?Await] ! UnaryExpression[?Yield, ?Await] [+Await] AwaitExpression[?Yield] ExponentiationExpression[Yield, Await] : UnaryExpression[?Yield, ?Await] UpdateExpression[?Yield, ?Await] ** ExponentiationExpression[?Yield, ?Await] MultiplicativeExpression[Yield, Await] : ExponentiationExpression[?Yield, ?Await] MultiplicativeExpression[?Yield, ?Await] MultiplicativeOperator ExponentiationExpression[?Yield, ?Await] MultiplicativeOperator : one of * / % AdditiveExpression[Yield, Await] : MultiplicativeExpression[?Yield, ?Await] AdditiveExpression[?Yield, ?Await] + MultiplicativeExpression[?Yield, ?Await] AdditiveExpression[?Yield, ?Await] - MultiplicativeExpression[?Yield, ?Await] ShiftExpression[Yield, Await] : AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] << AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] >> AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] >>> AdditiveExpression[?Yield, ?Await] RelationalExpression[In, Yield, Await] : ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] < ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] > ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] <= ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] >= ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] instanceof ShiftExpression[?Yield, ?Await] [+In] RelationalExpression[+In, ?Yield, ?Await] in ShiftExpression[?Yield, ?Await] [+In] PrivateIdentifier in ShiftExpression[?Yield, ?Await] EqualityExpression[In, Yield, Await] : RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] == RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] != RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] === RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] !== RelationalExpression[?In, ?Yield, ?Await] BitwiseANDExpression[In, Yield, Await] : EqualityExpression[?In, ?Yield, ?Await] BitwiseANDExpression[?In, ?Yield, ?Await] & EqualityExpression[?In, ?Yield, ?Await] BitwiseXORExpression[In, Yield, Await] : BitwiseANDExpression[?In, ?Yield, ?Await] BitwiseXORExpression[?In, ?Yield, ?Await] ^ BitwiseANDExpression[?In, ?Yield, ?Await] BitwiseORExpression[In, Yield, Await] : BitwiseXORExpression[?In, ?Yield, ?Await] BitwiseORExpression[?In, ?Yield, ?Await] | BitwiseXORExpression[?In, ?Yield, ?Await] LogicalANDExpression[In, Yield, Await] : BitwiseORExpression[?In, ?Yield, ?Await] LogicalANDExpression[?In, ?Yield, ?Await] && BitwiseORExpression[?In, ?Yield, ?Await] LogicalORExpression[In, Yield, Await] : LogicalANDExpression[?In, ?Yield, ?Await] LogicalORExpression[?In, ?Yield, ?Await] || LogicalANDExpression[?In, ?Yield, ?Await] CoalesceExpression[In, Yield, Await] : CoalesceExpressionHead[?In, ?Yield, ?Await] ?? BitwiseORExpression[?In, ?Yield, ?Await] CoalesceExpressionHead[In, Yield, Await] : CoalesceExpression[?In, ?Yield, ?Await] BitwiseORExpression[?In, ?Yield, ?Await] ShortCircuitExpression[In, Yield, Await] : LogicalORExpression[?In, ?Yield, ?Await] CoalesceExpression[?In, ?Yield, ?Await] ConditionalExpression[In, Yield, Await] : ShortCircuitExpression[?In, ?Yield, ?Await] ShortCircuitExpression[?In, ?Yield, ?Await] ? AssignmentExpression[+In, ?Yield, ?Await] : AssignmentExpression[?In, ?Yield, ?Await] AssignmentExpression[In, Yield, Await] : ConditionalExpression[?In, ?Yield, ?Await] [+Yield] YieldExpression[?In, ?Await] ArrowFunction[?In, ?Yield, ?Await] AsyncArrowFunction[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] = AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] AssignmentOperator AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] &&= AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] ||= AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] ??= AssignmentExpression[?In, ?Yield, ?Await] AssignmentOperator : one of *= /= %= += -= <<= >>= >>>= &= ^= |= **=

在特定情况下,当处理产生式实例
AssignmentExpression[In, Yield, Await] : LeftHandSideExpression[?Yield, ?Await] = AssignmentExpression[?In, ?Yield, ?Await]
时,LeftHandSideExpression 的解释使用以下语法进行细化:

AssignmentPattern[Yield, Await] : ObjectAssignmentPattern[?Yield, ?Await] ArrayAssignmentPattern[?Yield, ?Await] ObjectAssignmentPattern[Yield, Await] : { } { AssignmentRestProperty[?Yield, ?Await] } { AssignmentPropertyList[?Yield, ?Await] } { AssignmentPropertyList[?Yield, ?Await] , AssignmentRestProperty[?Yield, ?Await]opt } ArrayAssignmentPattern[Yield, Await] : [ Elisionopt AssignmentRestElement[?Yield, ?Await]opt ] [ AssignmentElementList[?Yield, ?Await] ] [ AssignmentElementList[?Yield, ?Await] , Elisionopt AssignmentRestElement[?Yield, ?Await]opt ] AssignmentRestProperty[Yield, Await] : ... DestructuringAssignmentTarget[?Yield, ?Await] AssignmentPropertyList[Yield, Await] : AssignmentProperty[?Yield, ?Await] AssignmentPropertyList[?Yield, ?Await] , AssignmentProperty[?Yield, ?Await] AssignmentElementList[Yield, Await] : AssignmentElisionElement[?Yield, ?Await] AssignmentElementList[?Yield, ?Await] , AssignmentElisionElement[?Yield, ?Await] AssignmentElisionElement[Yield, Await] : Elisionopt AssignmentElement[?Yield, ?Await] AssignmentProperty[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt PropertyName[?Yield, ?Await] : AssignmentElement[?Yield, ?Await] AssignmentElement[Yield, Await] : DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt AssignmentRestElement[Yield, Await] : ... DestructuringAssignmentTarget[?Yield, ?Await] DestructuringAssignmentTarget[Yield, Await] : LeftHandSideExpression[?Yield, ?Await]

 

Expression[In, Yield, Await] : AssignmentExpression[?In, ?Yield, ?Await] Expression[?In, ?Yield, ?Await] , AssignmentExpression[?In, ?Yield, ?Await]

A.3 语句

Statement[Yield, Await, Return] : BlockStatement[?Yield, ?Await, ?Return] VariableStatement[?Yield, ?Await] EmptyStatement ExpressionStatement[?Yield, ?Await] IfStatement[?Yield, ?Await, ?Return] BreakableStatement[?Yield, ?Await, ?Return] ContinueStatement[?Yield, ?Await] BreakStatement[?Yield, ?Await] [+Return] ReturnStatement[?Yield, ?Await] WithStatement[?Yield, ?Await, ?Return] LabelledStatement[?Yield, ?Await, ?Return] ThrowStatement[?Yield, ?Await] TryStatement[?Yield, ?Await, ?Return] DebuggerStatement Declaration[Yield, Await] : HoistableDeclaration[?Yield, ?Await, ~Default] ClassDeclaration[?Yield, ?Await, ~Default] LexicalDeclaration[+In, ?Yield, ?Await] HoistableDeclaration[Yield, Await, Default] : FunctionDeclaration[?Yield, ?Await, ?Default] GeneratorDeclaration[?Yield, ?Await, ?Default] AsyncFunctionDeclaration[?Yield, ?Await, ?Default] AsyncGeneratorDeclaration[?Yield, ?Await, ?Default] BreakableStatement[Yield, Await, Return] : IterationStatement[?Yield, ?Await, ?Return] SwitchStatement[?Yield, ?Await, ?Return] BlockStatement[Yield, Await, Return] : Block[?Yield, ?Await, ?Return] Block[Yield, Await, Return] : { StatementList[?Yield, ?Await, ?Return]opt } StatementList[Yield, Await, Return] : StatementListItem[?Yield, ?Await, ?Return] StatementList[?Yield, ?Await, ?Return] StatementListItem[?Yield, ?Await, ?Return] StatementListItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] Declaration[?Yield, ?Await] LexicalDeclaration[In, Yield, Await] : LetOrConst BindingList[?In, ?Yield, ?Await] ; LetOrConst : let const BindingList[In, Yield, Await] : LexicalBinding[?In, ?Yield, ?Await] BindingList[?In, ?Yield, ?Await] , LexicalBinding[?In, ?Yield, ?Await] LexicalBinding[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await] VariableStatement[Yield, Await] : var VariableDeclarationList[+In, ?Yield, ?Await] ; VariableDeclarationList[In, Yield, Await] : VariableDeclaration[?In, ?Yield, ?Await] VariableDeclarationList[?In, ?Yield, ?Await] , VariableDeclaration[?In, ?Yield, ?Await] VariableDeclaration[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await] BindingPattern[Yield, Await] : ObjectBindingPattern[?Yield, ?Await] ArrayBindingPattern[?Yield, ?Await] ObjectBindingPattern[Yield, Await] : { } { BindingRestProperty[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] , BindingRestProperty[?Yield, ?Await]opt } ArrayBindingPattern[Yield, Await] : [ Elisionopt BindingRestElement[?Yield, ?Await]opt ] [ BindingElementList[?Yield, ?Await] ] [ BindingElementList[?Yield, ?Await] , Elisionopt BindingRestElement[?Yield, ?Await]opt ] BindingRestProperty[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] BindingPropertyList[Yield, Await] : BindingProperty[?Yield, ?Await] BindingPropertyList[?Yield, ?Await] , BindingProperty[?Yield, ?Await] BindingElementList[Yield, Await] : BindingElisionElement[?Yield, ?Await] BindingElementList[?Yield, ?Await] , BindingElisionElement[?Yield, ?Await] BindingElisionElement[Yield, Await] : Elisionopt BindingElement[?Yield, ?Await] BindingProperty[Yield, Await] : SingleNameBinding[?Yield, ?Await] PropertyName[?Yield, ?Await] : BindingElement[?Yield, ?Await] BindingElement[Yield, Await] : SingleNameBinding[?Yield, ?Await] BindingPattern[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt SingleNameBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt BindingRestElement[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] ... BindingPattern[?Yield, ?Await] EmptyStatement : ; ExpressionStatement[Yield, Await] : [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }] Expression[+In, ?Yield, ?Await] ; IfStatement[Yield, Await, Return] : if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else Statement[?Yield, ?Await, ?Return] if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [lookahead ≠ else] IterationStatement[Yield, Await, Return] : DoWhileStatement[?Yield, ?Await, ?Return] WhileStatement[?Yield, ?Await, ?Return] ForStatement[?Yield, ?Await, ?Return] ForInOfStatement[?Yield, ?Await, ?Return] DoWhileStatement[Yield, Await, Return] : do Statement[?Yield, ?Await, ?Return] while ( Expression[+In, ?Yield, ?Await] ) ; WhileStatement[Yield, Await, Return] : while ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] ForStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] Expression[~In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( var VariableDeclarationList[~In, ?Yield, ?Await] ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( LexicalDeclaration[~In, ?Yield, ?Await] Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] ForInOfStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] LeftHandSideExpression[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( [lookahead ≠ let] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] ForDeclaration[Yield, Await] : LetOrConst ForBinding[?Yield, ?Await] ForBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] ContinueStatement[Yield, Await] : continue ; continue [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ; BreakStatement[Yield, Await] : break ; break [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ; ReturnStatement[Yield, Await] : return ; return [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; WithStatement[Yield, Await, Return] : with ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] SwitchStatement[Yield, Await, Return] : switch ( Expression[+In, ?Yield, ?Await] ) CaseBlock[?Yield, ?Await, ?Return] CaseBlock[Yield, Await, Return] : { CaseClauses[?Yield, ?Await, ?Return]opt } { CaseClauses[?Yield, ?Await, ?Return]opt DefaultClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return]opt } CaseClauses[Yield, Await, Return] : CaseClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return] CaseClause[?Yield, ?Await, ?Return] CaseClause[Yield, Await, Return] : case Expression[+In, ?Yield, ?Await] : StatementList[?Yield, ?Await, ?Return]opt DefaultClause[Yield, Await, Return] : default : StatementList[?Yield, ?Await, ?Return]opt LabelledStatement[Yield, Await, Return] : LabelIdentifier[?Yield, ?Await] : LabelledItem[?Yield, ?Await, ?Return] LabelledItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] FunctionDeclaration[?Yield, ?Await, ~Default] ThrowStatement[Yield, Await] : throw [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; TryStatement[Yield, Await, Return] : try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] Catch[Yield, Await, Return] : catch ( CatchParameter[?Yield, ?Await] ) Block[?Yield, ?Await, ?Return] catch Block[?Yield, ?Await, ?Return] Finally[Yield, Await, Return] : finally Block[?Yield, ?Await, ?Return] CatchParameter[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] DebuggerStatement : debugger ;

A.4 函数与类

UniqueFormalParameters[Yield, Await] : FormalParameters[?Yield, ?Await] FormalParameters[Yield, Await] : [empty] FunctionRestParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameterList[?Yield, ?Await] , FunctionRestParameter[?Yield, ?Await] FormalParameterList[Yield, Await] : FormalParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameter[?Yield, ?Await] FunctionRestParameter[Yield, Await] : BindingRestElement[?Yield, ?Await] FormalParameter[Yield, Await] : BindingElement[?Yield, ?Await] FunctionDeclaration[Yield, Await, Default] : function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } [+Default] function ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } FunctionExpression : function BindingIdentifier[~Yield, ~Await]opt ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } FunctionBody[Yield, Await] : FunctionStatementList[?Yield, ?Await] FunctionStatementList[Yield, Await] : StatementList[?Yield, ?Await, +Return]opt ArrowFunction[In, Yield, Await] : ArrowParameters[?Yield, ?Await] [no LineTerminator here] => ConciseBody[?In] ArrowParameters[Yield, Await] : BindingIdentifier[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] ConciseBody[In] : [lookahead ≠ {] ExpressionBody[?In, ~Await] { FunctionBody[~Yield, ~Await] } ExpressionBody[In, Await] : AssignmentExpression[?In, ~Yield, ?Await]

当处理产生式实例
ArrowParameters[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
时,CoverParenthesizedExpressionAndArrowParameterList 的解释使用以下语法进行细化:

ArrowFormalParameters[Yield, Await] : ( UniqueFormalParameters[?Yield, ?Await] )

 

AsyncArrowFunction[In, Yield, Await] : async [no LineTerminator here] AsyncArrowBindingIdentifier[?Yield] [no LineTerminator here] => AsyncConciseBody[?In] CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody[?In] AsyncConciseBody[In] : [lookahead ≠ {] ExpressionBody[?In, +Await] { AsyncFunctionBody } AsyncArrowBindingIdentifier[Yield] : BindingIdentifier[?Yield, +Await] CoverCallExpressionAndAsyncArrowHead[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

当处理产生式实例
AsyncArrowFunction[In, Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody[?In]
时,CoverCallExpressionAndAsyncArrowHead 的解释使用以下语法进行细化:

AsyncArrowHead : async [no LineTerminator here] ArrowFormalParameters[~Yield, +Await]

 

MethodDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } GeneratorMethod[?Yield, ?Await] AsyncMethod[?Yield, ?Await] AsyncGeneratorMethod[?Yield, ?Await] get ClassElementName[?Yield, ?Await] ( ) { FunctionBody[~Yield, ~Await] } set ClassElementName[?Yield, ?Await] ( PropertySetParameterList ) { FunctionBody[~Yield, ~Await] } PropertySetParameterList : FormalParameter[~Yield, ~Await] GeneratorDeclaration[Yield, Await, Default] : function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } [+Default] function * ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorExpression : function * BindingIdentifier[+Yield, ~Await]opt ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorMethod[Yield, Await] : * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorBody : FunctionBody[+Yield, ~Await] YieldExpression[In, Await] : yield yield [no LineTerminator here] AssignmentExpression[?In, +Yield, ?Await] yield [no LineTerminator here] * AssignmentExpression[?In, +Yield, ?Await] AsyncGeneratorDeclaration[Yield, Await, Default] : async [no LineTerminator here] function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } [+Default] async [no LineTerminator here] function * ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorExpression : async [no LineTerminator here] function * BindingIdentifier[+Yield, +Await]opt ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorMethod[Yield, Await] : async [no LineTerminator here] * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorBody : FunctionBody[+Yield, +Await] AsyncFunctionDeclaration[Yield, Await, Default] : async [no LineTerminator here] function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } [+Default] async [no LineTerminator here] function ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionExpression : async [no LineTerminator here] function BindingIdentifier[~Yield, +Await]opt ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncMethod[Yield, Await] : async [no LineTerminator here] ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionBody : FunctionBody[~Yield, +Await] AwaitExpression[Yield] : await UnaryExpression[?Yield, +Await] ClassDeclaration[Yield, Await, Default] : class BindingIdentifier[?Yield, ?Await] ClassTail[?Yield, ?Await] [+Default] class ClassTail[?Yield, ?Await] ClassExpression[Yield, Await] : class BindingIdentifier[?Yield, ?Await]opt ClassTail[?Yield, ?Await] ClassTail[Yield, Await] : ClassHeritage[?Yield, ?Await]opt { ClassBody[?Yield, ?Await]opt } ClassHeritage[Yield, Await] : extends LeftHandSideExpression[?Yield, ?Await] ClassBody[Yield, Await] : ClassElementList[?Yield, ?Await] ClassElementList[Yield, Await] : ClassElement[?Yield, ?Await] ClassElementList[?Yield, ?Await] ClassElement[?Yield, ?Await] ClassElement[Yield, Await] : MethodDefinition[?Yield, ?Await] static MethodDefinition[?Yield, ?Await] FieldDefinition[?Yield, ?Await] ; static FieldDefinition[?Yield, ?Await] ; ClassStaticBlock ; FieldDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt ClassElementName[Yield, Await] : PropertyName[?Yield, ?Await] PrivateIdentifier ClassStaticBlock : static { ClassStaticBlockBody } ClassStaticBlockBody : ClassStaticBlockStatementList ClassStaticBlockStatementList : StatementList[~Yield, +Await, ~Return]opt

A.5 脚本与模块

Script : ScriptBodyopt ScriptBody : StatementList[~Yield, ~Await, ~Return] Module : ModuleBodyopt ModuleBody : ModuleItemList ModuleItemList : ModuleItem ModuleItemList ModuleItem ModuleItem : ImportDeclaration ExportDeclaration StatementListItem[~Yield, +Await, ~Return] ModuleExportName : IdentifierName StringLiteral ImportDeclaration : import ImportClause FromClause WithClauseopt ; import ModuleSpecifier WithClauseopt ; ImportClause : ImportedDefaultBinding NameSpaceImport NamedImports ImportedDefaultBinding , NameSpaceImport ImportedDefaultBinding , NamedImports ImportedDefaultBinding : ImportedBinding NameSpaceImport : * as ImportedBinding NamedImports : { } { ImportsList } { ImportsList , } FromClause : from ModuleSpecifier ImportsList : ImportSpecifier ImportsList , ImportSpecifier ImportSpecifier : ImportedBinding ModuleExportName as ImportedBinding ModuleSpecifier : StringLiteral ImportedBinding : BindingIdentifier[~Yield, +Await] WithClause : with { } with { WithEntries ,opt } WithEntries : AttributeKey : StringLiteral AttributeKey : StringLiteral , WithEntries AttributeKey : IdentifierName StringLiteral ExportDeclaration : export ExportFromClause FromClause WithClauseopt ; export NamedExports ; export VariableStatement[~Yield, +Await] export Declaration[~Yield, +Await] export default HoistableDeclaration[~Yield, +Await, +Default] export default ClassDeclaration[~Yield, +Await, +Default] export default [lookahead ∉ { function, async [no LineTerminator here] function, class }] AssignmentExpression[+In, ~Yield, +Await] ; ExportFromClause : * * as ModuleExportName NamedExports NamedExports : { } { ExportsList } { ExportsList , } ExportsList : ExportSpecifier ExportsList , ExportSpecifier ExportSpecifier : ModuleExportName ModuleExportName as ModuleExportName

A.6 数值转换

StringNumericLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt StrWhiteSpace ::: StrWhiteSpaceChar StrWhiteSpaceopt StrWhiteSpaceChar ::: WhiteSpace LineTerminator StrNumericLiteral ::: StrDecimalLiteral NonDecimalIntegerLiteral[~Sep] StrDecimalLiteral ::: StrUnsignedDecimalLiteral + StrUnsignedDecimalLiteral - StrUnsignedDecimalLiteral StrUnsignedDecimalLiteral ::: Infinity DecimalDigits[~Sep] . DecimalDigits[~Sep]opt ExponentPart[~Sep]opt . DecimalDigits[~Sep] ExponentPart[~Sep]opt DecimalDigits[~Sep] ExponentPart[~Sep]opt

所有未被 StringNumericLiteral 语法显式定义的语法符号,其定义与 数字字面量的词法语法 中使用的定义相同。

StringIntegerLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrIntegerLiteral StrWhiteSpaceopt StrIntegerLiteral ::: SignedInteger[~Sep] NonDecimalIntegerLiteral[~Sep]

A.7 时区偏移字符串格式

UTCOffset ::: ASCIISign Hour ASCIISign Hour HourSubcomponents[+Extended] ASCIISign Hour HourSubcomponents[~Extended] ASCIISign ::: one of + - Hour ::: 0 DecimalDigit 1 DecimalDigit 20 21 22 23 HourSubcomponents[Extended] ::: TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TemporalDecimalFractionopt TimeSeparator[Extended] ::: [+Extended] : [~Extended] [empty] MinuteSecond ::: 0 DecimalDigit 1 DecimalDigit 2 DecimalDigit 3 DecimalDigit 4 DecimalDigit 5 DecimalDigit TemporalDecimalFraction ::: TemporalDecimalSeparator DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator ::: one of . ,

A.8 正则表达式

Pattern[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Disjunction[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] | Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Alternative[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: [empty] Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Term[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Term[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Assertion[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Atom[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Atom[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Quantifier Assertion[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: ^ $ \b \B (?= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) Quantifier :: QuantifierPrefix QuantifierPrefix ? QuantifierPrefix :: * + ? { DecimalDigits[~Sep] } { DecimalDigits[~Sep] ,} { DecimalDigits[~Sep] , DecimalDigits[~Sep] } Atom[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: PatternCharacter . \ AtomEscape[?UnicodeMode, ?NamedCaptureGroups] CharacterClass[?UnicodeMode, ?UnicodeSetsMode] ( GroupSpecifier[?UnicodeMode]opt Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers : Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers - RegularExpressionModifiers : Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) RegularExpressionModifiers :: [empty] RegularExpressionModifiers RegularExpressionModifier RegularExpressionModifier :: one of i m s SyntaxCharacter :: one of ^ $ \ . * + ? ( ) [ ] { } | PatternCharacter :: SourceCharacter but not SyntaxCharacter AtomEscape[UnicodeMode, NamedCaptureGroups] :: DecimalEscape CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode] [+NamedCaptureGroups] k GroupName[?UnicodeMode] CharacterEscape[UnicodeMode] :: ControlEscape c AsciiLetter 0 [lookahead ∉ DecimalDigit] HexEscapeSequence RegExpUnicodeEscapeSequence[?UnicodeMode] IdentityEscape[?UnicodeMode] ControlEscape :: one of f n r t v GroupSpecifier[UnicodeMode] :: ? GroupName[?UnicodeMode] GroupName[UnicodeMode] :: < RegExpIdentifierName[?UnicodeMode] > RegExpIdentifierName[UnicodeMode] :: RegExpIdentifierStart[?UnicodeMode] RegExpIdentifierName[?UnicodeMode] RegExpIdentifierPart[?UnicodeMode] RegExpIdentifierStart[UnicodeMode] :: IdentifierStartChar \ RegExpUnicodeEscapeSequence[+UnicodeMode] [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpIdentifierPart[UnicodeMode] :: IdentifierPartChar \ RegExpUnicodeEscapeSequence[+UnicodeMode] [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpUnicodeEscapeSequence[UnicodeMode] :: [+UnicodeMode] u HexLeadSurrogate \u HexTrailSurrogate [+UnicodeMode] u HexLeadSurrogate [+UnicodeMode] u HexTrailSurrogate [+UnicodeMode] u HexNonSurrogate [~UnicodeMode] u Hex4Digits [+UnicodeMode] u{ CodePoint } UnicodeLeadSurrogate :: any Unicode code point in the inclusive interval from U+D800 to U+DBFF UnicodeTrailSurrogate :: any Unicode code point in the inclusive interval from U+DC00 to U+DFFF

对于每个 \u HexTrailSurrogate(其关联的 u HexLeadSurrogate 选择存在歧义),应与最近的、否则将没有对应 \u HexTrailSurrogate 的可能 u HexLeadSurrogate 进行关联。

 

HexLeadSurrogate :: Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xD800 to 0xDBFF HexTrailSurrogate :: Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xDC00 to 0xDFFF HexNonSurrogate :: Hex4Digits but only if the MV of Hex4Digits is not in the inclusive interval from 0xD800 to 0xDFFF IdentityEscape[UnicodeMode] :: [+UnicodeMode] SyntaxCharacter [+UnicodeMode] / [~UnicodeMode] SourceCharacter but not UnicodeIDContinue DecimalEscape :: NonZeroDigit DecimalDigits[~Sep]opt [lookahead ∉ DecimalDigit] CharacterClassEscape[UnicodeMode] :: d D s S w W [+UnicodeMode] p{ UnicodePropertyValueExpression } [+UnicodeMode] P{ UnicodePropertyValueExpression } UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue LoneUnicodePropertyNameOrValue UnicodePropertyName :: UnicodePropertyNameCharacters UnicodePropertyNameCharacters :: UnicodePropertyNameCharacter UnicodePropertyNameCharactersopt UnicodePropertyValue :: UnicodePropertyValueCharacters LoneUnicodePropertyNameOrValue :: UnicodePropertyValueCharacters UnicodePropertyValueCharacters :: UnicodePropertyValueCharacter UnicodePropertyValueCharactersopt UnicodePropertyValueCharacter :: UnicodePropertyNameCharacter DecimalDigit UnicodePropertyNameCharacter :: AsciiLetter _ CharacterClass[UnicodeMode, UnicodeSetsMode] :: [ [lookahead ≠ ^] ClassContents[?UnicodeMode, ?UnicodeSetsMode] ] [^ ClassContents[?UnicodeMode, ?UnicodeSetsMode] ] ClassContents[UnicodeMode, UnicodeSetsMode] :: [empty] [~UnicodeSetsMode] NonemptyClassRanges[?UnicodeMode] [+UnicodeSetsMode] ClassSetExpression NonemptyClassRanges[UnicodeMode] :: ClassAtom[?UnicodeMode] ClassAtom[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode] ClassAtom[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode] NonemptyClassRangesNoDash[UnicodeMode] :: ClassAtom[?UnicodeMode] ClassAtomNoDash[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode] ClassAtomNoDash[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode] ClassAtom[UnicodeMode] :: - ClassAtomNoDash[?UnicodeMode] ClassAtomNoDash[UnicodeMode] :: SourceCharacter but not one of \ or ] or - \ ClassEscape[?UnicodeMode] ClassEscape[UnicodeMode] :: b [+UnicodeMode] - CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode] ClassSetExpression :: ClassUnion ClassIntersection ClassSubtraction ClassUnion :: ClassSetRange ClassUnionopt ClassSetOperand ClassUnionopt ClassIntersection :: ClassSetOperand && [lookahead ≠ &] ClassSetOperand ClassIntersection && [lookahead ≠ &] ClassSetOperand ClassSubtraction :: ClassSetOperand -- ClassSetOperand ClassSubtraction -- ClassSetOperand ClassSetRange :: ClassSetCharacter - ClassSetCharacter ClassSetOperand :: NestedClass ClassStringDisjunction ClassSetCharacter NestedClass :: [ [lookahead ≠ ^] ClassContents[+UnicodeMode, +UnicodeSetsMode] ] [^ ClassContents[+UnicodeMode, +UnicodeSetsMode] ] \ CharacterClassEscape[+UnicodeMode] ClassStringDisjunction :: \q{ ClassStringDisjunctionContents } ClassStringDisjunctionContents :: ClassString ClassString | ClassStringDisjunctionContents ClassString :: [empty] NonEmptyClassString NonEmptyClassString :: ClassSetCharacter NonEmptyClassStringopt ClassSetCharacter :: [lookahead ∉ ClassSetReservedDoublePunctuator] SourceCharacter but not ClassSetSyntaxCharacter \ CharacterEscape[+UnicodeMode] \ ClassSetReservedPunctuator \b ClassSetReservedDoublePunctuator :: one of && !! ## $$ %% ** ++ ,, .. :: ;; << == >> ?? @@ ^^ `` ~~ ClassSetSyntaxCharacter :: one of ( ) [ ] { } / - \ | ClassSetReservedPunctuator :: one of & - ! # % , : ; < = > @ ` ~

Annex B (normative) 供网页浏览器使用的额外 ECMAScript 特性

当 ECMAScript 宿主是网页浏览器时,本附录中定义的 ECMAScript 语言语法和语义是必需的。如果 ECMAScript 宿主不是网页浏览器,则本附录内容是规范性的但可选。

本附录中定义的一些特性在本附录中具体说明,另一些则在本文档主体中说明。

当某个特性在正文中定义时,每个其影响文档的点都会用带颜色框中的 “Normative Optional” 字样标记。此外,如果该特性牵涉算法或早期错误规则中的特定措辞,则这些措辞会以 “the host supports” 该相关特性为条件加以保护。网页浏览器被要求支持所有此类特性。

Note

本附录描述了各种历史遗留特性,以及网页浏览器 ECMAScript 宿主的其他特征。本附录中规定的所有语言特性和行为都具有一个或多个不理想的特征,如果没有遗留使用,它们本应从本规范中移除。然而,大量现有网页使用这些特性,意味着浏览器必须继续支持它们。本附录中的规范定义了这些遗留特性的互操作实现要求。

这些特性不被视为 ECMAScript 语言的核心部分。编写新的 ECMAScript 代码时,程序员不应使用或假设这些特性和行为的存在。除非实现是网页浏览器的一部分,或需要运行与浏览器遇到的相同遗留 ECMAScript 代码,否则不鼓励 ECMAScript 实现实现这些特性。

B.1 附加语法

B.1.1 类 HTML 注释

12.4 的语法和语义按如下方式扩展,但在使用目标符号 Module 解析源码文本时不允许此扩展:

Syntax

InputElementHashbangOrRegExp :: WhiteSpace LineTerminator Comment CommonToken HashbangComment RegularExpressionLiteral HTMLCloseComment Comment :: MultiLineComment SingleLineComment SingleLineHTMLOpenComment SingleLineHTMLCloseComment SingleLineDelimitedComment MultiLineComment :: /* FirstCommentLineopt LineTerminator MultiLineCommentCharsopt */ HTMLCloseCommentopt FirstCommentLine :: SingleLineDelimitedCommentChars SingleLineHTMLOpenComment :: <!-- SingleLineCommentCharsopt SingleLineHTMLCloseComment :: LineTerminatorSequence HTMLCloseComment SingleLineDelimitedComment :: /* SingleLineDelimitedCommentCharsopt */ HTMLCloseComment :: WhiteSpaceSequenceopt SingleLineDelimitedCommentSequenceopt --> SingleLineCommentCharsopt SingleLineDelimitedCommentChars :: SingleLineNotAsteriskChar SingleLineDelimitedCommentCharsopt * SingleLinePostAsteriskCommentCharsopt SingleLineNotAsteriskChar :: SourceCharacter but not one of * or LineTerminator SingleLinePostAsteriskCommentChars :: SingleLineNotForwardSlashOrAsteriskChar SingleLineDelimitedCommentCharsopt * SingleLinePostAsteriskCommentCharsopt SingleLineNotForwardSlashOrAsteriskChar :: SourceCharacter but not one of / or * or LineTerminator WhiteSpaceSequence :: WhiteSpace WhiteSpaceSequenceopt SingleLineDelimitedCommentSequence :: SingleLineDelimitedComment WhiteSpaceSequenceopt SingleLineDelimitedCommentSequenceopt

类似包含行终止符代码点的 MultiLineCommentSingleLineHTMLCloseComment 在句法语法解析目的上被视为一个 LineTerminator

B.1.2 正则表达式模式

22.2.1 的语法按如下方式修改与扩展。这些更改引入了通过文法产生式的排序与上下文信息消解的歧义。使用下列语法解析时,只有此前的产生式候选不匹配时才考虑后续候选。

这种替代模式文法与语义只改变 BMP 模式的语法与语义。下面的语法扩展包含带有 [UnicodeMode] 参数的产生式。然而,这些扩展均不改变在目标符号上存在 [UnicodeMode] 参数时被识别的 Unicode 模式的语法。

Syntax

Term[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: [+UnicodeMode] Assertion[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] [+UnicodeMode] Atom[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Quantifier [+UnicodeMode] Atom[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] [~UnicodeMode] QuantifiableAssertion[?NamedCaptureGroups] Quantifier [~UnicodeMode] Assertion[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] [~UnicodeMode] ExtendedAtom[?NamedCaptureGroups] Quantifier [~UnicodeMode] ExtendedAtom[?NamedCaptureGroups] Assertion[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: ^ $ \b \B [+UnicodeMode] (?= Disjunction[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) [+UnicodeMode] (?! Disjunction[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) [~UnicodeMode] QuantifiableAssertion[?NamedCaptureGroups] (?<= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) QuantifiableAssertion[NamedCaptureGroups] :: (?= Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) (?! Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) ExtendedAtom[NamedCaptureGroups] :: . \ AtomEscape[~UnicodeMode, ?NamedCaptureGroups] \ [lookahead = c] CharacterClass[~UnicodeMode, ~UnicodeSetsMode] ( GroupSpecifier[~UnicodeMode]opt Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers : Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers - RegularExpressionModifiers : Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) InvalidBracedQuantifier ExtendedPatternCharacter InvalidBracedQuantifier :: { DecimalDigits[~Sep] } { DecimalDigits[~Sep] ,} { DecimalDigits[~Sep] , DecimalDigits[~Sep] } ExtendedPatternCharacter :: SourceCharacter but not one of ^ $ \ . * + ? ( ) [ | AtomEscape[UnicodeMode, NamedCaptureGroups] :: [+UnicodeMode] DecimalEscape [~UnicodeMode] DecimalEscape but only if the CapturingGroupNumber of DecimalEscape is ≤ CountLeftCapturingParensWithin(the Pattern containing DecimalEscape) CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode, ?NamedCaptureGroups] [+NamedCaptureGroups] k GroupName[?UnicodeMode] CharacterEscape[UnicodeMode, NamedCaptureGroups] :: ControlEscape c AsciiLetter 0 [lookahead ∉ DecimalDigit] HexEscapeSequence RegExpUnicodeEscapeSequence[?UnicodeMode] [~UnicodeMode] LegacyOctalEscapeSequence IdentityEscape[?UnicodeMode, ?NamedCaptureGroups] IdentityEscape[UnicodeMode, NamedCaptureGroups] :: [+UnicodeMode] SyntaxCharacter [+UnicodeMode] / [~UnicodeMode] SourceCharacterIdentityEscape[?NamedCaptureGroups] SourceCharacterIdentityEscape[NamedCaptureGroups] :: [~NamedCaptureGroups] SourceCharacter but not c [+NamedCaptureGroups] SourceCharacter but not one of c or k ClassAtomNoDash[UnicodeMode, NamedCaptureGroups] :: SourceCharacter but not one of \ or ] or - \ ClassEscape[?UnicodeMode, ?NamedCaptureGroups] \ [lookahead = c] ClassEscape[UnicodeMode, NamedCaptureGroups] :: b [+UnicodeMode] - [~UnicodeMode] c ClassControlLetter CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode, ?NamedCaptureGroups] ClassControlLetter :: DecimalDigit _ Note

当同一左侧同时出现带 [+UnicodeMode] 与 [~UnicodeMode] 守卫时,用于控制消解优先级。

B.1.2.1 静态语义:早期错误

22.2.1.1 的语义按如下扩展:

ExtendedAtom :: InvalidBracedQuantifier
  • 若任意源码文本被此产生式匹配,则为语法错误。

此外,下列产生式的规则添加 高亮 文本后被修改:

NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents
  • 若第一个 ClassAtom 的 IsCharacterClass 为 true 或第二个 ClassAtom 的 IsCharacterClass 为 true 且该产生式具有 [UnicodeMode] 参数,则为语法错误。
  • 若第一个 ClassAtom 的 IsCharacterClass 为 false,第二个 ClassAtom 的 IsCharacterClass 为 false,且第一个 ClassAtom 的 CharacterValue 严格大于第二个的 CharacterValue,则为语法错误。
NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents
  • ClassAtomNoDash 的 IsCharacterClass 为 trueClassAtom 的 IsCharacterClass 为 true 且该产生式具有 [UnicodeMode] 参数,则为语法错误。
  • ClassAtomNoDash 的 IsCharacterClass 为 falseClassAtom 的 IsCharacterClass 为 false,且 ClassAtomNoDash 的 CharacterValue 严格大于 ClassAtom 的 CharacterValue,则为语法错误。

B.1.2.2 静态语义:CountLeftCapturingParensWithin 与 CountLeftCapturingParensBefore

在 CountLeftCapturingParensWithin 与 CountLeftCapturingParensBefore 的定义中,对 “ Atom :: ( GroupSpecifieropt Disjunction ) ” 的引用应解释为 “ Atom :: ( GroupSpecifieropt Disjunction ) ” 或 “ ExtendedAtom :: ( GroupSpecifieropt Disjunction ) ”。

B.1.2.3 静态语义:IsCharacterClass

22.2.1.6 的语义按如下扩展:

ClassAtomNoDash :: \ [lookahead = c]
  1. 返回 false

B.1.2.4 静态语义:CharacterValue

22.2.1.7 的语义按如下扩展:

ClassAtomNoDash :: \ [lookahead = c]
  1. 返回 U+005C (REVERSE SOLIDUS) 的数值。
ClassEscape :: c ClassControlLetter
  1. chClassControlLetter 匹配的代码点。
  2. ich 的数值。
  3. 返回 i 除以 32 的余数。
CharacterEscape :: LegacyOctalEscapeSequence
  1. 返回 LegacyOctalEscapeSequence 的 MV(见 12.9.4.3)。

B.1.2.5 运行时语义:CompileSubpattern

CompileSubpattern 的语义按如下扩展:

Term :: QuantifiableAssertion Quantifier 的规则与 Term :: Atom Quantifier 相同,但用 QuantifiableAssertion 替换 Atom

Term :: ExtendedAtom Quantifier 的规则与 Term :: Atom Quantifier 相同,但用 ExtendedAtom 替换 Atom

Term :: ExtendedAtom 的规则与 Term :: Atom 相同,但用 ExtendedAtom 替换 Atom

B.1.2.6 运行时语义:CompileAssertion

Assertion :: (?= Disjunction ) Assertion :: (?! Disjunction ) 产生式的 CompileAssertion 规则同样用于 QuantifiableAssertion 产生式,但用 QuantifiableAssertion 替换 Assertion

B.1.2.7 运行时语义:CompileAtom

Atom :: PatternCharacter 外,Atom 产生式的 CompileAtom 规则也用于 ExtendedAtom 产生式,但用 ExtendedAtom 替换 Atom。同时添加以下带参数 direction 的规则:

ExtendedAtom :: \ [lookahead = c]
  1. A 为包含单个字符 \ U+005C (REVERSE SOLIDUS) 的 CharSet
  2. 返回 CharacterSetMatcher(rer, A, false, direction)。
ExtendedAtom :: ExtendedPatternCharacter
  1. chExtendedPatternCharacter 所表示的字符。
  2. A 为包含字符 ch 的单元素 CharSet
  3. 返回 CharacterSetMatcher(rer, A, false, direction)。

B.1.2.8 运行时语义:CompileToCharSet

22.2.2.9 的语义按如下扩展:

以下两条规则替换 CompileToCharSet 对应规则。

NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents
  1. A 为第一个 ClassAtom 的 CompileToCharSet,参数 rer
  2. B 为第二个 ClassAtom 的 CompileToCharSet,参数 rer
  3. CClassContents 的 CompileToCharSet,参数 rer
  4. DCharacterRangeOrUnion(rer, A, B)。
  5. 返回 DC 的并集。
NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents
  1. AClassAtomNoDash 的 CompileToCharSet,参数 rer
  2. BClassAtom 的 CompileToCharSet,参数 rer
  3. CClassContents 的 CompileToCharSet,参数 rer
  4. DCharacterRangeOrUnion(rer, A, B)。
  5. 返回 DC 的并集。

另外,向 CompileToCharSet 添加以下规则。

ClassEscape :: c ClassControlLetter
  1. cv 为该 ClassEscape 的 CharacterValue。
  2. c 为字符值为 cv 的字符。
  3. 返回包含单个字符 cCharSet
ClassAtomNoDash :: \ [lookahead = c]
  1. 返回包含单个字符 \ U+005C (REVERSE SOLIDUS) 的 CharSet
Note
该产生式只能从字符类中出现的序列 \c(其后未跟可接受控制字符)到达。

B.1.2.8.1 CharacterRangeOrUnion ( rer, A, B )

The abstract operation CharacterRangeOrUnion takes arguments rer (a RegExp Record), A (a CharSet), and B (a CharSet) and returns a CharSet. It performs the following steps when called:

  1. HasEitherUnicodeFlag(rer) 为 false,则
    1. A 不正好包含一个字符或 B 不正好包含一个字符,则
      1. C 为包含单个字符 - U+002D (HYPHEN-MINUS) 的 CharSet
      2. 返回 CharSet ABC 的并集。
  2. 返回 CharacterRange(A, B)。

B.1.2.9 静态语义:ParsePattern ( patternText, u, v )

22.2.3.4 的语义按如下扩展:

抽象操作 ParsePattern 接受参数 patternText(一串 Unicode 代码点)、u(一个 Boolean)与 v(一个 Boolean)。调用时执行以下步骤:

  1. vtrueutrue,则
    1. parseResult 为包含一个或多个 SyntaxError 对象的 List
  2. 否则若 vtrue,则
    1. parseResult 为 ParseText(patternText, Pattern[+UnicodeMode, +UnicodeSetsMode, +NamedCaptureGroups])。
  3. 否则若 utrue,则
    1. parseResult 为 ParseText(patternText, Pattern[+UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups])。
  4. 否则,
    1. parseResult 为 ParseText(patternText, Pattern[~UnicodeMode, ~UnicodeSetsMode, ~NamedCaptureGroups])。
    2. parseResult 是 Parse Node 且 parseResult 包含 GroupName,则
      1. parseResult 设为 ParseText(patternText, Pattern[~UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups])。
  5. 返回 parseResult

B.2 额外内建属性

当 ECMAScript 宿主是网页浏览器时,标准内建对象具有以下额外属性。

B.2.1 全局对象的额外属性

Table 100 中的条目被添加到 Table 6

Table 100: 额外的著名内在对象
内在名称 全局名称 ECMAScript 语言关联
%escape% escape escape 函数 (B.2.1.1)
%unescape% unescape unescape 函数 (B.2.1.2)

B.2.1.1 escape ( string )

该函数是全局对象的一个属性。它计算一个字符串值的新版本,其中某些代码单元被十六进制转义序列替换。

当替换数值 ≤ 0x00FF 的代码单元时,使用形如 %xx 的两位转义序列。替换数值严格大于 0x00FF 的代码单元时,使用形如 %uxxxx 的四位转义序列。

它是 %escape% 内在对象。

调用时执行以下步骤:

  1. string 设为 ? ToString(string)。
  2. lenstring 的长度。
  3. R 为空字符串。
  4. unescapedSet 为 ASCII 单词字符与 "@*+-./" 的串联。
  5. k 为 0。
  6. k < len 重复,
    1. Cstring 中索引 k 处的代码单元。
    2. unescapedSet 包含 C,则
      1. SC
    3. 否则,
      1. nC 的数值。
      2. n < 256,则
        1. hex 为将 n 格式化为大写十六进制数的字符串表示。
        2. S"%"StringPad(hex, 2, "0", start) 的串联。
      3. 否则,
        1. hex 为将 n 格式化为大写十六进制数的字符串表示。
        2. S"%u"StringPad(hex, 4, "0", start) 的串联。
    4. R 设为 RS 的串联。
    5. k 设为 k + 1。
  7. 返回 R
Note

该编码部分基于 RFC 1738 描述的编码,但本标准指定的全部编码如上所述,与 RFC 1738 内容无关。该编码不反映 RFC 3986 对 RFC 1738 的更改。

B.2.1.2 unescape ( string )

该函数是全局对象的一个属性。它计算一个字符串值的新版本,其中每个可能由 escape 函数引入的转义序列被其表示的代码单元替换。

它是 %unescape% 内在对象。

调用时执行以下步骤:

  1. string 设为 ? ToString(string)。
  2. lenstring 的长度。
  3. R 为空字符串。
  4. k 为 0。
  5. k < len 重复,
    1. Cstring 中索引 k 处的代码单元。
    2. C 是代码单元 0x0025 (PERCENT SIGN),则
      1. hexDigits 为空字符串。
      2. optionalAdvance 为 0。
      3. k + 5 < lenstring 中索引 k + 1 处代码单元为 0x0075 (LATIN SMALL LETTER U),则
        1. hexDigits 设为 stringk + 2 到 k + 6 的子串。
        2. optionalAdvance 设为 5。
      4. 否则若 k + 3 ≤ len,则
        1. hexDigits 设为 stringk + 1 到 k + 3 的子串。
        2. optionalAdvance 设为 2。
      5. parseResult 为 ParseText(hexDigits, HexDigits[~Sep])。
      6. parseResult 是 Parse Node,则
        1. nparseResult 的 MV。
        2. C 设为数值为 n 的代码单元。
        3. k 设为 k + optionalAdvance
    3. R 设为 RC 的串联。
    4. k 设为 k + 1。
  6. 返回 R

B.2.2 String.prototype 对象的额外属性

B.2.2.1 String.prototype.substr ( start, length )

该方法返回将 this 值转换为字符串后的一个substring,从索引 start 开始,长度为 length 个代码单元(或如果 lengthundefined 则直到字符串末尾)。若 start 为负,则将其视为 sourceLength + start,其中 sourceLength 是字符串长度。结果是一个字符串值,而不是字符串对象。

调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireObjectCoercible(O)。
  3. S 为 ? ToString(O)。
  4. sizeS 的长度。
  5. intStart 为 ? ToIntegerOrInfinity(start)。
  6. intStart = -∞,将 intStart 设为 0。
  7. 否则若 intStart < 0,将 intStart 设为 max(size + intStart, 0)。
  8. 否则,将 intStart 设为 min(intStart, size)。
  9. lengthundefined,令 intLengthsize;否则令 intLength 为 ? ToIntegerOrInfinity(length)。
  10. intLength 夹取到 0 与 size 之间。
  11. intEndmin(intStart + intLength, size)。
  12. 返回 SintStartintEnd 的子串。
Note

该方法有意设计为泛型;它不要求其 this 值为字符串对象。因此可以被转移到其他对象上用作方法。

B.2.2.2 String.prototype.anchor ( name )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "a", "name", name)。

B.2.2.2.1 CreateHTML ( string, tag, attribute, value )

The abstract operation CreateHTML takes arguments string (an ECMAScript language value), tag (a String), attribute (a String), and value (an ECMAScript language value) and returns either a normal completion containing a String or a throw completion. It performs the following steps when called:

  1. 执行 ? RequireObjectCoercible(string)。
  2. S 为 ? ToString(string)。
  3. p1"<"tag 的串联。
  4. attribute 不是空字符串,则
    1. V 为 ? ToString(value)。
    2. escapedV 为与 V 相同的字符串值,除了 V 中每个代码单元 0x0022 (QUOTATION MARK) 被六个代码单元序列 "&quot;" 替换。
    3. p1 设为以下串联:
      • p1
      • 代码单元 0x0020 (SPACE)
      • attribute
      • 代码单元 0x003D (EQUALS SIGN)
      • 代码单元 0x0022 (QUOTATION MARK)
      • escapedV
      • 代码单元 0x0022 (QUOTATION MARK)
  5. p2p1">" 的串联。
  6. p3p2S 的串联。
  7. p4p3"</"tag">" 的串联。
  8. 返回 p4

B.2.2.3 String.prototype.big ( )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "big", "", "")。

B.2.2.4 String.prototype.blink ( )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "blink", "", "")。

B.2.2.5 String.prototype.bold ( )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "b", "", "")。

B.2.2.6 String.prototype.fixed ( )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "tt", "", "")。

B.2.2.7 String.prototype.fontcolor ( colour )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "font", "color", colour)。

B.2.2.8 String.prototype.fontsize ( size )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "font", "size", size)。

B.2.2.9 String.prototype.italics ( )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "i", "", "")。

B.2.2.10 String.prototype.link ( url )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "a", "href", url)。

B.2.2.11 String.prototype.small ( )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "small", "", "")。

B.2.2.12 String.prototype.strike ( )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "strike", "", "")。

B.2.2.13 String.prototype.sub ( )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "sub", "", "")。

B.2.2.14 String.prototype.sup ( )

该方法被调用时执行以下步骤:

  1. Sthis 值。
  2. 返回 ? CreateHTML(S, "sup", "", "")。

B.2.2.15 String.prototype.trimLeft ( )

Note

优先使用 "trimStart" 属性。"trimLeft" 属性主要为兼容旧代码而提供。建议在新的 ECMAScript 代码中使用 "trimStart" 属性。

"trimLeft" 属性的初始值是 %String.prototype.trimStart%,定义见 22.1.3.34

B.2.2.16 String.prototype.trimRight ( )

Note

优先使用 "trimEnd" 属性。"trimRight" 属性主要为兼容旧代码而提供。建议在新的 ECMAScript 代码中使用 "trimEnd" 属性。

"trimRight" 属性的初始值是 %String.prototype.trimEnd%,定义见 22.1.3.33

B.2.3 Date.prototype 对象的额外属性

B.2.3.1 Date.prototype.getYear ( )

Note

getFullYear 方法在几乎所有场景中更可取,因为它避免“2000 年问题”。

该方法被调用时执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. tNaN,返回 NaN
  5. 返回 YearFromTime(LocalTime(t)) - 1900𝔽

B.2.3.2 Date.prototype.setYear ( year )

Note

setFullYear 方法在几乎所有场景中更可取,因为它避免“2000 年问题”。

该方法被调用时执行以下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. tdateObject.[[DateValue]]
  4. y 为 ? ToNumber(year)。
  5. tNaN,将 t 设为 +0𝔽;否则将 t 设为 LocalTime(t)。
  6. yyyyMakeFullYear(y)。
  7. dMakeDay(yyyy, MonthFromTime(t), DateFromTime(t))。
  8. dateMakeDate(d, TimeWithinDay(t))。
  9. uTimeClip(UTC(date))。
  10. dateObject.[[DateValue]] 设为 u
  11. 返回 u

B.2.3.3 Date.prototype.toGMTString ( )

Note

更推荐使用 toUTCString 方法。本方法主要为兼容旧代码而提供。

"toGMTString" 属性的初始值是 %Date.prototype.toUTCString%,定义见 21.4.4.43

B.2.4 RegExp.prototype 对象的额外属性

B.2.4.1 RegExp.prototype.compile ( pattern, flags )

该方法被调用时执行以下步骤:

  1. Othis 值。
  2. 执行 ? RequireInternalSlot(O, [[RegExpMatcher]])。
  3. pattern 是一个对象且具有 [[RegExpMatcher]] 内部槽,则
    1. flags 不为 undefined,抛出 TypeError 异常。
    2. Ppattern.[[OriginalSource]]
    3. Fpattern.[[OriginalFlags]]
  4. 否则,
    1. Ppattern
    2. Fflags
  5. 返回 ? RegExpInitialize(O, P, F)。
Note

该方法使用新的模式与标志完全重新初始化 this RegExp。实现可以将使用此方法视为对结果 RegExp 对象将被多次使用的断言,从而可进行额外优化。

B.3 其他附加特性

B.3.1 带标签的函数声明

在 ECMAScript 2015 之前,LabelledStatement 的规范不允许将语句标签与 FunctionDeclaration 关联。然而,带标签的 FunctionDeclaration 是非严格代码的允许扩展,且多数浏览器宿主 ECMAScript 实现支持该扩展。ECMAScript 2015 及之后,LabelledStatement 的语法产生式允许将 FunctionDeclaration 用作 LabelledItem,但 14.13.1 包含的早期错误规则在发生时产生语法错误。然后该规则被修改,在宿主支持该特性的非严格代码中抑制该语法错误。

Note

WithStatementIfStatementIterationStatement早期错误规则阻止它们在非严格代码中包含带标签的 FunctionDeclaration

B.3.2 块级函数声明 Web 历史兼容语义

在 ECMAScript 2015 之前,规范未定义 FunctionDeclaration 作为 Block 语句 StatementList 元素的出现。然而,以这种形式的 FunctionDeclaration 的支持是允许扩展,多数浏览器宿主实现允许它们。不幸的是,此类声明的语义在这些实现之间有所不同。由于这些语义差异,使用 Block 级函数声明的现有网页 ECMAScript 源文本只有在其用法仅依赖所有浏览器实现对该声明语义的交集部分时才是可移植的。以下用例落在该交集语义内:

  1. 在单个块内声明并仅在该块内引用函数。

  2. 在单个 Block 中声明函数并可能使用,同时被不在该 Block 内的内部函数引用。

    • 一个或多个 FunctionDeclaration,其 BindingIdentifier 名称为 f,出现在封闭函数 g 的函数代码内,且该声明嵌套在一个 Block 中。
    • g 的函数代码内不存在其他非 varf 声明。
    • 在包含 f 声明的 BlockStatementList 内可以有 f 作为 IdentifierReference 的出现。
    • 在嵌套于 g 之内的另一个函数 h 中至少有一次 f 作为 IdentifierReference 的出现,且不存在其他 f 声明屏蔽 h 内对 f 的引用。
    • 所有对 h 的调用都发生在 f 声明已被求值之后。
  3. 在单个块中声明函数并可能使用,同时也在后续块中被引用。

第一种用例与 ECMAScript 2015 提供的 Block 级函数声明语义可互操作。任何使用该用例的既有 ECMAScript 源文本都将使用 101415 章节定义的块级函数声明语义运行。

第二与第三种用例的 ECMAScript 2015 互操作性需要对 101519.2.116.1.7 章节语义做出以下扩展。

如果 ECMAScript 实现有报告诊断警告消息的机制,当代码包含应用这些兼容语义并对非兼容语义引入可观察差异的 FunctionDeclaration 时应产生警告。例如,如果由于引入会造成早期错误而未引入 var 绑定,则不应产生警告。

该特性在以下点涉及特殊语义:

B.3.3 IfStatement 语句子句中的 FunctionDeclarations

以下内容扩展了 14.6 中的 IfStatement 产生式:

IfStatement[Yield, Await, Return] : if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else Statement[?Yield, ?Await, ?Return] if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else FunctionDeclaration[?Yield, ?Await, ~Default] if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else FunctionDeclaration[?Yield, ?Await, ~Default] if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] [lookahead ≠ else]

该产生式仅在解析非严格代码时适用。被该产生式匹配的源码文本按如下处理:每个匹配出现的 FunctionDeclaration[?Yield, ?Await, ~Default] 被视为占据该位置的 BlockStatement 的唯一 StatementListItem。此类合成 BlockStatement 的语义包括 B.3.2 中规定的网页历史兼容语义。

B.3.4 Catch 块中的 VariableStatements

该特性中,Catch 子句的 Block 可以包含将名称绑定到也由 CatchParameter 绑定的名称的 var 声明。通过修改 Catch : catch ( CatchParameter ) Block 14.15.1 中的一条早期错误规则实现。

Note

运行时,此类绑定在 VariableDeclarationEnvironment 中实例化。它们不会遮蔽由 CatchParameter 引入的同名绑定,因此此类 var 声明的 Initializer 将赋值给对应的 catch 参数,而非该 var 绑定。

该修改行为也适用于包含于 Catch 子句 Block 内直接 eval 调用引入的 varfunction 声明。通过修改 EvalDeclarationInstantiation 中步骤 3.d.i.2.a.i13.b.ii.4.a.i.i 实现。

B.3.5 ForIn 语句头中的初始值设定项

以下内容扩展了 14.7.5 中的 ForInOfStatement 产生式:

ForInOfStatement[Yield, Await, Return] : for ( var BindingIdentifier[?Yield, ?Await] Initializer[~In, ?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]

该产生式仅在解析非严格代码时适用。

8.3.1 中 ContainsDuplicateLabels 的静态语义扩展如下:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. 返回 Statement 的 ContainsDuplicateLabels,参数 labelSet

8.3.2 中 ContainsUndefinedBreakTarget 的静态语义扩展如下:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. 返回 Statement 的 ContainsUndefinedBreakTarget,参数 labelSet

8.3.3 中 ContainsUndefinedContinueTarget 的静态语义扩展如下:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. 返回 Statement 的 ContainsUndefinedContinueTarget,参数 iterationSet 与 « »。

14.7.5.2 中 IsDestructuring 的静态语义扩展如下:

BindingIdentifier : Identifier yield await
  1. 返回 false

8.2.6 中 VarDeclaredNames 的静态语义扩展如下:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. names1BindingIdentifier 的 BoundNames。
  2. names2Statement 的 VarDeclaredNames。
  3. 返回 names1names2 的列表串联。

8.2.7 中 VarScopedDeclarations 的静态语义扩展如下:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. declarations1 为 « BindingIdentifier »。
  2. declarations2Statement 的 VarScopedDeclarations。
  3. 返回 declarations1declarations2 的列表串联。

14.7.5.5 中 ForInOfLoopEvaluation 的运行时语义扩展如下:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. bindingIdBindingIdentifier 的 StringValue。
  2. lhs 为 ? ResolveBinding(bindingId)。
  3. 若 IsAnonymousFunctionDefinition(Initializer) 为 true,则
    1. value 为 ? NamedEvaluation(Initializer, 参数 bindingId)。
  4. 否则,
    1. rhs 为 ? Evaluation(Initializer)。
    2. value 为 ? GetValue(rhs)。
  5. 执行 ? PutValue(lhs, value)。
  6. keyResult 为 ? ForIn/OfHeadEvaluation(« », Expression, enumerate)。
  7. 返回 ? ForIn/OfBodyEvaluation(BindingIdentifier, Statement, keyResult, enumerate, var-binding, labelSet)。

B.3.6 [[IsHTMLDDA]] 内部槽

宿主定义对象上可存在一个 [[IsHTMLDDA]] internal slot。具有 [[IsHTMLDDA]] 内部槽的对象在 ToBooleanIsLooselyEqual 抽象操作中以及作为 typeof 运算符 操作数时表现得像 undefined

Note

本规范从不创建具有 [[IsHTMLDDA]] 内部槽的对象。然而,网页浏览器中的 document.all 对象 是一个带有该槽的宿主定义奇异对象,为网页兼容而存在。没有其它已知示例,实现除 document.all 外不应创建任何此类对象。

该特性在以下点涉及特殊语义:

B.3.7 HostMakeJobCallback 中的非默认行为

HostMakeJobCallback 抽象操作允许作为网页浏览器的宿主指定非默认行为。

B.3.8 HostEnsureCanAddPrivateElement 中的非默认行为

HostEnsureCanAddPrivateElement 抽象操作允许作为网页浏览器的宿主指定非默认行为。

B.3.9 函数调用赋值目标的运行时错误

当函数调用(13.3.6)在非严格代码中作为赋值目标使用时,不再产生早期错误,而是在赋值求值期间抛出 ReferenceError 异常。

Note

当赋值目标是 AssignmentExpressionLeftHandSideExpression 时,赋值运算符必须是 = 或一个 AssignmentOperator;特别地,此处允许不适用于逻辑赋值运算符(??=&&=||=)。

参见 AssignmentTargetType 的步骤 1,适用于 CallExpression : CoverCallExpressionAndAsyncArrowHead CallExpression : CallExpression Arguments

Annex C (informative) ECMAScript 的严格模式

严格模式的限制与例外

Annex D (informative) 宿主分层点

宿主的定义见 4.2

D.1 宿主钩子

HostCallJobCallback(...)

HostEnqueueFinalizationRegistryCleanupJob(...)

HostEnqueueGenericJob(...)

HostEnqueuePromiseJob(...)

HostEnqueueTimeoutJob(...)

HostEnsureCanCompileStrings(...)

HostFinalizeImportMeta(...)

HostGetImportMetaProperties(...)

HostGrowSharedArrayBuffer(...)

HostHasSourceTextAvailable(...)

HostLoadImportedModule(...)

HostGetSupportedImportAttributes(...)

HostMakeJobCallback(...)

HostPromiseRejectionTracker(...)

HostResizeArrayBuffer(...)

InitializeHostDefinedRealm(...)

D.2 宿主定义字段

Realm Record 上的 [[HostDefined]]:见 Table 22

Script Record 上的 [[HostDefined]]:见 Table 37

Module Record 上的 [[HostDefined]]:见 Table 41

JobCallback Record 上的 [[HostDefined]]:见 Table 26

Candidate Executions 上的 [[HostSynchronizesWith]]:见 Table 99

[[IsHTMLDDA]]:见 B.3.6

D.3 宿主定义对象

全局对象:见 19

D.4 运行作业

调用作业抽象闭包前的准备步骤与之后的清理步骤。见 9.5

D.5 奇异对象的内部方法

本规范中未指定的任意奇异对象在 Table 4 中的任何基本内部方法。

D.6 内建对象与方法

任何本规范未定义的内建对象与方法,除非在 17.1 中受到限制。

Annex E (informative) ECMAScript 2015 中的更正与澄清(可能的兼容性影响)

9.1.1.4.14-9.1.1.4.17:第 5 与 5.1 版使用属性存在性测试来判断与新全局声明对应的全局对象属性是否已存在。ECMAScript 2015 使用自有属性存在性测试。这与多数浏览器实现最常见的行为一致。

10.4.2.1:第 5 版将捕获当前数组长度的操作移至数组索引或新长度值进行整数转换之前。然而,如果转换过程有改变数组长度的副作用,捕获的长度可能失效。ECMAScript 2015 规定当前数组长度必须在此类副作用可能发生之后捕获。

21.4.1.31:之前的版本允许 TimeClip 抽象操作返回 +0𝔽-0𝔽 作为 0 时间值的表示。ECMAScript 2015 规定始终返回 +0𝔽。这意味着在 ECMAScript 2015 中 Date 的时间值不会可观察到 -0𝔽,返回时间值的方法也不会返回 -0𝔽

21.4.1.32:如果不存在 UTC 偏移表示,则使用本地时区。第 5.1 版错误地说缺失的时区应解释为 "z"

21.4.4.36:若年份无法用 21.4.1.32 指定的日期时间字符串格式表示,则抛出 RangeError。之前版本未指定该情况的行为。

21.4.4.41:之前版本未指定当时间值NaNDate.prototype.toString 返回的值。ECMAScript 2015 规定结果为字符串 "Invalid Date"

22.2.4.1, 22.2.6.13.1:RegExp 实例 "source" 属性值中的任何 LineTerminator 代码点必须使用转义序列表示。第 5.1 版仅要求转义 /

22.2.6.8, 22.2.6.11:在之前版本中,String.prototype.matchString.prototype.replace 对于 pattern 参数为设置了 global 标志的 RegExp 值的情况的规范不正确。旧规范指出每次尝试匹配模式时,如果 lastIndex 未改变,则应加 1。正确行为是只有当模式匹配到空字符串时才加 1。

23.1.3.30:之前版本未指定 Array.prototype.sort 如何解释由 comparator 返回的 NaN 值。ECMAScript 2015 规定此类值视为 comparator 返回 +0𝔽。还规定对 comparator 返回的结果应用 ToNumber。之前版本对结果非 Number 的情况是实现自定。实践中实现会调用 ToNumber

Annex F (informative) 引入与先前版本不兼容的新增与变更

6.2.5:在 ECMAScript 2015 中,函数调用不允许返回一个 Reference Record

7.1.4.1:在 ECMAScript 2015 中,对字符串值执行 ToNumber 现在识别并转换 BinaryIntegerLiteralOctalIntegerLiteral 数字字符串。之前版本转换为 NaN

9.3:在 ECMAScript 2018 中,模板对象按 Parse Node(源位置)规范化,而不是如之前版本那样在 Realm 中该模板字面量或标记模板的所有出现之间。

12.2:在 ECMAScript 2016 中,要求 Unicode 8.0.0 或更高,而 ECMAScript 2015 要求 Unicode 5.1。特别地,这导致 U+180E 蒙古元音分隔符从 Space_Separator (Zs) 类别(因此在 ECMAScript 2015 中视为空白)移动到 Format (Cf) 类别(自 Unicode 6.3.0 起)。这导致对空白敏感的方法表现不同。例如,之前版本 "\u180E".trim().length0,在 ECMAScript 2016 及后为 1。此外,ECMAScript 2017 要求始终使用最新 Unicode 标准。

12.7:在 ECMAScript 2015 中,IdentifierName 的有效代码点以 Unicode 属性 “ID_Start” 与 “ID_Continue” 表述。之前版本通过列举各种 Unicode 代码点类别指定有效的 IdentifierNameIdentifier 代码点。

12.10.1:在 ECMAScript 2015 中,自动分号插入会在缺少分号的 do-while 语句末尾添加分号。该变更使规范与现有多数实现的实际行为一致。

13.2.5.1:在 ECMAScript 2015 中,对象初始值设定中出现重复属性名不再是早期错误。

13.15.1:在 ECMAScript 2015 中,严格模式代码中对不可变绑定(如 FunctionExpression 的函数名)的赋值不再产生早期错误,而是产生运行时错误。

14.2:在 ECMAScript 2015 中,以 token let 开头,后跟输入元素 LineTerminator 再跟 IdentifierStatementList 是一个 LexicalDeclaration 的起始。之前版本中自动分号插入会在该 Identifier 输入元素前插入分号。

14.5:在 ECMAScript 2015 中,以 token let 开头后跟 token [StatementListItemLexicalDeclaration 的起始。之前版本该序列会是 ExpressionStatement 的起始。

14.6.2:在 ECMAScript 2015 中,IfStatement 的正常结果不再是值 empty。如果没有求值任何 Statement 部分或求值的 Statement 部分产生包含 empty正常完成,则结果为 undefined

14.7:在 ECMAScript 2015 中,如果 for 语句的 ( token 紧跟 token 序列 let [let 视为 LexicalDeclaration 的起始。之前版本该序列是 Expression 的起始。

14.7:在 ECMAScript 2015 中,如果 for-in 语句的 ( token 紧跟 token 序列 let [let 视为 ForDeclaration 的起始。之前版本该序列是 LeftHandSideExpression 的起始。

14.7:在 ECMAScript 2015 之前,初始化表达式可出现在紧接 in 关键字之前的 VariableDeclaration 中。ECMAScript 2015 中相同位置的 ForBinding 不允许此初始化器出现。ECMAScript 2017 中,此初始化器仅在非严格代码中允许。

14.7:在 ECMAScript 2015 中,对 IterationStatement 的求值结果不再是 [[Value]]empty正常完成。若其 Statement 部分未被求值或最终求值结果为 [[Value]]empty正常完成,则结果为 [[Value]]undefined正常完成

14.11.2:在 ECMAScript 2015 中,对 WithStatement 的求值结果不再是 [[Value]]empty正常完成。若其 Statement 部分求值产生 [[Value]]empty正常完成,结果为 [[Value]]undefined正常完成

14.12.4:在 ECMAScript 2015 中,对 SwitchStatement 的求值结果不再是 [[Value]]empty正常完成。若其 CaseBlock 部分求值产生 [[Value]]empty正常完成,结果为 [[Value]]undefined正常完成

14.15:在 ECMAScript 2015 中,Catch 子句包含与其参数相同 Identifiervar 声明是早期错误。之前版本该变量声明会在外层变量环境中实例化,但声明的 Initializer 值会赋给 Catch 参数。

14.15, 19.2.1.3:在 ECMAScript 2015 中,如果 Catch 子句求值一个非严格直接 eval 且其 eval 代码包含绑定与 Catch 参数同名的 varFunctionDeclaration 声明,则抛出运行时 SyntaxError

14.15.3:在 ECMAScript 2015 中,TryStatement 的结果不再是值 empty。如果其 Block 部分求值为包含 empty正常完成,则结果为 undefined。如果 Block 部分求值为抛出完成,且其 Catch 部分求值为包含 empty正常完成,在没有 Finally 子句或 Finally 子句求值为 empty 正常完成时结果为 undefined

15.4.5:在 ECMAScript 2015 中,作为 ObjectLiteral访问器属性 [[Get]][[Set]] 属性值创建的函数对象不是构造函数,也没有 "prototype" 自有属性。之前版本它们是构造函数并有 "prototype" 属性。

20.1.2.6:在 ECMAScript 2015 中,如果传给 Object.freeze 的参数不是对象,按无自有属性的不可扩展普通对象处理。之前版本非对象参数总是抛出 TypeError

20.1.2.8:在 ECMAScript 2015 中,如果传给 Object.getOwnPropertyDescriptor 的参数不是对象,尝试用 ToObject 强制转换,成功则使用结果替代原参数。之前版本非对象参数总是抛出 TypeError

20.1.2.10:同上。

20.1.2.12:同上。

20.1.2.16:在 ECMAScript 2015 中,非对象参数按无自有属性的不可扩展普通对象处理。之前版本抛出 TypeError

20.1.2.17:同上。

20.1.2.18:同上。

20.1.2.19:在 ECMAScript 2015 中,非对象参数尝试 ToObject 成功则使用结果。之前版本抛出 TypeError

20.1.2.20:非对象参数按不可扩展空对象处理。之前版本抛出 TypeError

20.1.2.22:同上。

20.2.3.2:在 ECMAScript 2015 中,绑定函数的 [[Prototype]] 内部槽设为其目标函数的 [[GetPrototypeOf]] 值。之前版本始终设为 %Function.prototype%

20.2.4.1:在 ECMAScript 2015 中,函数实例的 "length" 属性是可配置的。之前版本不可配置。

20.5.6.2:在 ECMAScript 2015 中,NativeError 构造函数[[Prototype]] 内部槽是 Error 构造函数。之前版本是 Function 原型对象

21.4.4:在 ECMAScript 2015 中,Date 原型对象不是 Date 实例。之前版本它是 TimeValue 为 NaN 的 Date 实例。

22.1.3.12:在 ECMAScript 2015 中,String.prototype.localeCompare 必须将 Unicode 标准下规范等价的字符串视为相同。之前版本允许忽略规范等价,使用按位比较。

22.1.3.2822.1.3.30:在 ECMAScript 2015 中,大小写转换处理基于代码点。之前版本仅对单个代码单元。受影响的代码点仅在 Deseret 区块。

22.1.3.32:在 ECMAScript 2015 中,String.prototype.trim 识别可能存在于 Unicode BMP 之外的空白代码点。然而截至 Unicode 7 尚无此类代码点。之前版本这些代码点不会被识别为空白。

22.2.4.1:在 ECMAScript 2015 中,如果 pattern 参数是 RegExp 实例且 flags 参数不为 undefined,则创建一个新 RegExp,其模式与 pattern 相同但标志为 flags。之前版本当 pattern 为 RegExp 且 flagsundefined 时抛出 TypeError

22.2.6:在 ECMAScript 2015 中,RegExp 原型对象不是 RegExp 实例。之前版本它是模式为空字符串的 RegExp 实例。

22.2.6:在 ECMAScript 2015 中,"source""global""ignoreCase""multiline" 是定义在 RegExp 原型对象上的访问器属性。之前版本它们是定义在 RegExp 实例上的数据属性

25.4.15:在 ECMAScript 2019 中,Atomics.wake 重命名为 Atomics.notify 以避免与 Atomics.wait 混淆。

27.1.6.4, 27.6.3.6:在 ECMAScript 2019 中,await 入队的作业数量减少,可能在 then() 调用与 await 表达式之间创建可观察到的解析顺序差异。

参考文献

  1. IEEE 754-2019IEEE Standard for Floating-Point Arithmetic。电气与电子工程师协会,纽约(2019) Note

    IEEE 754-2008 与 IEEE 754-2019 之间没有影响 ECMA-262 规范的规范性变更。

  2. The Unicode Standard,可访问 <https://unicode.org/versions/latest>
  3. Unicode Technical Note #5: Canonical Equivalence in Applications,可访问 <https://unicode.org/notes/tn5/>
  4. Unicode Technical Standard #10: Unicode Collation Algorithm,可访问 <https://unicode.org/reports/tr10/>
  5. Unicode Standard Annex #15, Unicode Normalization Forms,可访问 <https://unicode.org/reports/tr15/>
  6. Unicode Standard Annex #18: Unicode Regular Expressions,可访问 <https://unicode.org/reports/tr18/>
  7. Unicode Standard Annex #24: Unicode Script Property,可访问 <https://unicode.org/reports/tr24/>
  8. Unicode Standard Annex #31, Unicode Identifiers and Pattern Syntax,可访问 <https://unicode.org/reports/tr31/>
  9. Unicode Standard Annex #44: Unicode Character Database,可访问 <https://unicode.org/reports/tr44/>
  10. Unicode Technical Standard #51: Unicode Emoji,可访问 <https://unicode.org/reports/tr51/>
  11. IANA Time Zone Database,可访问 <https://www.iana.org/time-zones>
  12. ISO 8601:2004(E) Data elements and interchange formats — Information interchange — Representation of dates and times
  13. RFC 1738 “Uniform Resource Locators (URL)”,可访问 <https://tools.ietf.org/html/rfc1738>
  14. RFC 2396 “Uniform Resource Identifiers (URI): Generic Syntax”,可访问 <https://tools.ietf.org/html/rfc2396>
  15. RFC 3629 “UTF-8, a transformation format of ISO 10646”,可访问 <https://tools.ietf.org/html/rfc3629>
  16. RFC 7231 “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content”,可访问 <https://tools.ietf.org/html/rfc7231>

版本后记

本规范在 GitHub 上以一种称为 Ecmarkup 的纯文本源格式编写。Ecmarkup 是一种 HTML 与 Markdown 方言,提供框架与工具集,用于以纯文本编写 Ecma 规范,并将其处理为遵循本文档编辑惯例的全功能 HTML 呈现。Ecmarkup 构建并集成了多种其他格式与技术,包括用于定义语法的 Grammarkdown 与用于编写算法步骤的 Ecmarkdown。本规范的 PDF 呈现使用一个打印样式表生成,该样式表利用 CSS 分页媒体规范,并使用 PrinceXML 转换。

之前版本的本规范使用 Word 编写——构成本版本基础的 Ecmarkup 源文本是通过自动转换工具将 ECMAScript 2015 的 Word 文档转换为 Ecmarkup 生成的。

Copyright & Software License

Ecma International

Rue du Rhone 114

CH-1204 Geneva

Tel: +41 22 849 6000

Fax: +41 22 849 6001

Web: https://ecma-international.org/

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.