javascript
github地址:https://github.com/zhoushengmufc/es6
qq群:588950619

ECMA-262

7ᵗʰ Edition / June 2016

ECMAScript® 2016 语言规范

介绍#

Ecma标准定义了2016年ECMAScript语言。这是第七版的ECMAScript语言规范。自1997年出版的第一版,ECMAScript已经是世界上最广泛使用的通用编程语言。最好是被称为语言嵌入在web浏览器,但也为服务器和嵌入式应用程序被广泛采用。

ECMAScript是基于几种原始技术,最著名的是JavaScript(Netscape)和JScript(微软)。语言是由Brendan Eich在网景公司发明的,第一次出现在公司的导航器2.0浏览器。它出现在所有后续从网景浏览器,浏览器从微软Internet Explorer 3.0开始。

ECMAScript语言规范的发展始于1996年11月。第一版本Ecma标准采用的Ecma大会1997年6月。

Ecma标准提交ISO / IEC JTC 1采用快速程序下,国际标准ISO / IEC 16262和批准,1998年4月。Ecma大会1998年6月批准了第二版Ecma - 262使它完全符合ISO / IEC 16262。变化之间的第一和第二版编辑。

T他第三版标准的强大的正则表达式,引入更好的字符串处理,新控制语句,try / catch异常处理、严格的定义错误,格式为数字输出和次要的预期未来语言的发展变化。第三版的ECMAScript标准采用的Ecma大会1999年12月和2002年6月发布为ISO / IEC 16262:2002。

第三版的出版后,ECMAScript实现大规模采用结合万维网的编程语言,它已经成为本质上所有的网络浏览器所支持。重要的工作是开发一个ECMAScript第四版完成的。然而,工作没有完成,而不是发布为ECMAScript第四版,但有些是纳入第六版的发展。

ECMAScript的第五版(ecma - 262)编纂实际解释语言规范,已经成为常见的浏览器实现和增加了对新功能的支持,第三版的出版以来就出现了。这些特性包括访问属性,反射创建和检查对象,程序控制的财产属性,额外的数组操作功能,支持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的编译目标其他语言。它的一些主要改进包括模块,类声明,词汇块范围,迭代器和发电机,异步编程承诺,解构模式和适当的尾部调用。ECMAScript扩大图书馆的内置支持额外的数据抽象包括地图、集合和数组的二进制数值以及额外支持Unicode补充字符在字符串和正则表达式。通过子类化的内置模板也可扩展。第六版提供了常规的基础,增量式语言和库增强。第六版是2015年6月联合国大会通过。

ECMAScript规范第一ECMAScript版下发布Ecma TC39每年的新版本节奏和开放的开发过程。一个纯文本源文档建于2015年ECMAScript源文档作为完全在GitHub上进一步发展的基础。超过这个标准的发展,数以百计的把请求和问题提交代表成千上万的bug修复,编辑补丁和其他改进。此外,众多的软件工具开发援助在这方面包括Ecmarkup Ecmarkdown,Grammarkdown。此规范还包括支持一种新的求幂运算符和数组添加一个新方法。原型叫做includes.

几十个人代表许多组织作出了非常重要的贡献在Ecma TC39发展这版和之前的版本。此外,一个充满活力的社区出现了支持TC39 ECMAScript的努力。这个社区有了无数的草案,提交成千上万的bug报告,进行实验,实现了测试套件,受过教育的ECMAScript的全球开发者社区。不幸的是,它是不可能确定和组织并承认每一个人作出了贡献。

Allen Wirfs-Brock
ECMA-262, 6th Edition Project Editor

Brian Terlson
ECMA-262, 7th Edition Project Editor

1范围#

本标准规定了ECMAScript 2016通用编程语言

2一致性#

符合标准的ECMAScript实现,必须提供和支持本规范所有的类型,值,对象,属性,方法和语法及语义

符合标准的ECMAScript实现, 源文本必须与版本8.0.0以上且符合ISO/IEC 10646的unicode标准一致, .

ECMAScript的符合标准的实现,提供了一个应用程序编程接口,支持需要适应的程序所使用的语言和文化传统不同的人类语言和国家必须实现该接口定义的最新版的ecma - 402与本规范兼容。

ECMAScript的符合标准的实现可以提供额外的类型、值、对象、属性和功能之外在本规范中描述。特别是,ECMAScript的符合标准的实现可以提供属性不是本规范中描述,为这些属性和值,本规范中所描述的对象。

ECMAScript可能支持程序的一个符合标准的实现和正则表达式的语法没有在本规范中描述。特别是,ECMAScript可能支持程序的一个符合标准的实现语法,利用分条款中列出的“未来保留字”11.6.2.2 of this specification.

当一个符合标准的实现的ECMAScript不能实现任何扩展列为禁止分单元的扩展16.2.

3引用标准#

以下引用文档是不可缺少的这个文档的应用程序。为过时的引用,仅引用的版本适用。若引用的文件不标日期,最新版的引用的文件(包括任何修改)适用。

ISO/IEC 10646:2003: Information Technology – Universal Multiple-Octet Coded Character Set (UCS) plus Amendment 1:2005, Amendment 2:2006, Amendment 3:2008, and Amendment 4:2008, plus additional amendments and corrigenda, or successor

ECMA-402, ECMAScript 2015 Internationalization API Specification.
http://www.ecma-international.org/publications/standards/Ecma-402.htm

ECMA-404, The JSON Data Interchange Format.
http://www.ecma-international.org/publications/standards/Ecma-404.htm

4概述#

本节包含一个非规范化ECMAScript语言的概述。

ECMAScript是一种面向对象的编程语言来执行计算和操作计算对象在一个主机环境。ECMAScript定义在这里并不是计算自给自足;事实上,该规范中没有规定外部数据的输入或输出的计算结果。相反,预计一个ECMAScript程序的计算环境不仅将提供本规范中所描述的对象和其它设施还包括某些特定于环境的对象,其描述和行为超出了本规范的范围除了表明他们可能提供可以访问和某些特定的属性,可以从一个ECMAScript程序调用的函数。

ECMAScript最初设计用于脚本语言,但已成为广泛使用的一种通用编程语言。脚本语言是一种编程语言,用于操作,定制和自动化设施的现有系统。在这样的系统中,有用的功能已经可以通过一个用户界面,和脚本语言是一种机制,用于暴露程序控制功能。据说这样,现有系统提供一个对象的宿主环境和设施,完成了脚本语言的功能。一种脚本语言的目的是供专业和非专业程序员使用。

ECMAScript最初被设计为一个Web脚本语言 ,提供一种机制来活跃在浏览器和Web页面来执行服务器计算作为一个基于Web的客户机-服务器体系结构的一部分。ECMAScript是用来提供各种主机环境的核心脚本功能。因此在本文档中指定的核心语言除了任何特定主机环境。

使用ECMAScript已经超越了简单的脚本和现在使用的各种编程任务在许多不同的环境和鳞片。ECMAScript的使用范围的扩大,因此有它所提供的功能和设施。ECMAScript现在是一个功能齐全的将军提出的编程语言。

一些设施ECMAScript类似其他编程语言中使用,尤其是C、Java™,自我,和计划中描述:

ISO/IEC 9899:1996, Programming Languages – C.

Gosling, James, Bill Joy and Guy Steele. The Java Language Specification. Addison Wesley Publishing Co., 1996.

Ungar, David, and Smith, Randall B. Self: The Power of Simplicity. OOPSLA '87 Conference Proceedings, pp. 227-241, Orlando, FL, October 1987.

IEEE Standard for the Scheme Programming Language. IEEE Std 1178-1990.

4.1Web Scripting#

web浏览器提供了一个ECMAScript主机客户端计算环境包括,例如,窗口对象、菜单、弹出窗口、对话框、文本区域、锚,框架,浏览历史,cookie,和输入/输出。此外,主机环境提供了一种方法把脚本代码等事件改变焦点,页面和图像加载,卸载,错误和中止,选择,表单提交和鼠标操作。出现在HTML和脚本代码显示的页面是用户界面元素的组合和固定和计算文本和图像。脚本代码是反应用户交互,不需要一个主程序。

web服务器提供了一个不同的主机服务器端计算环境包括对象代表请求,客户,和文件;锁和共享数据的机制。通过使用浏览器端和服务器端脚本,可以分配计算客户端和服务器之间,为基于web的应用程序提供一个定制的用户界面。

每个支持ECMAScript的Web浏览器和服务器供应自己的主机环境,完成ECMAScript执行环境。

4.2ECMAScript Overview#

下面是一个非正式的概述ECMAScript-not语言描述的所有部分。本文不是标准的一部分。

ECMAScript基于对象: 基本语言和宿主工具都由一系列对象提供, ECMAScript程序是一组通信对象. 在ECMAScript中, 对象(object) 是一个或多个 属性(properties)组成,每个属性有决定怎么使用的属性(attributes),举个例子, 当Writable属性(attribute)设置为false时, 任何想设置为不同值的赋值都会失败. 属性(properties)是容纳其他对象, 原始值(primitive values), 或者 函数(functions)的容器. 一个原始值属于以下内置类型之一: Undefined, Null, Boolean, Number, String, 及 Symbol; 一个对象是内置类型的一员 Object; 函数是一个 callable object. 一个函数通过属性与对象相关联被称为方法(method).

ECMAScript 定义了一系列 内置对象(built-in objects) 实现了ECMAScript实体. 这些内置对象包括全局对象(global object); 内置对象是语言运行时语义的基础,包括 Object, Function, Boolean, Symbol, 以及各种 Error 对象; 表示和操作数值的对象,包括Math, Number, 和 Date; 文本处理对象 StringRegExp; 包括索引的对象集合的值 Array 及九种类型的数组,其元素都具有特定的数值数据表示形式; 有key的集合,包括 Map and Set 对象; 支持结构化数据的对象,包括 JSON, ArrayBuffer, and DataView; 支持控制抽象的对象包括生成器函数(generator function) 和 Promise 对象; 反射对象包括 ProxyReflect.

ECMAScript定义了一系列内置操作符(operators). ECMAScript操作符包括 各种一元运算,包括 乘法运算符, 加法运算符, 位移运算符, 关系运算符, 等于运算符, 二进制位操作符, 二进制逻辑运算符, 赋值操作符, 和 逗号运算符.

大型ECMAScript程序支持 模块(modules) 它允许程序被分成多个语句和声明序列。 每个模块显式地标识它使用的需要由其他模块提供的声明,以及它的哪些声明可供其他模块使用。

ECMAScript语法有意类似于Java语法。 放宽ECMAScript语法以使其成为易于使用的脚本语言。 例如,变量不需要声明具体类型,属性也不需要与类型关联,并且定义的函数不需要在调用它们之前声明

4.2.1对象(Objects)#

即使ECMAScript包括类定义的语法, ECMAScript对象不像C ++,Smalltalk或Java完全基于类。 对象可以以各种方式创建,包括通过字面符号或通过 构造函数(constructors) 创建对象,然后执行代码,初始化全部或部分地分配初始值性质。每个构造函数都有一个名为 原型("prototype") 用来实现 基于原型的继承共享属性. 对象是通过使用构造函数创建,使用 new 表达式; 例如, new Date(2009,11) 创建一个时间对象. 如果没有使用 new. 比如, Date() 生成当前日期和时间的字符串表示,而不是对象

构造函数创建的每个对象都有一个隐式引用(称为对象的 原型(prototype)) 指向构造函数的 原型("prototype") 属性. 此外,原型可以具有对其原型的非空隐式引用,等等; 这就是原型链(prototype chain).当引用对象中的属性时,该引用指的是原型链中包含该名称的属性的第一个对象中该名称的属性。 换句话说,首先检查直接对象的这种属性; 如果该对象包含命名属性,则是引用该属性; 如果该对象不包含命名属性,则接下来检查该对象的原型; 等等。

Figure 1: Object/Prototype Relationships
An image of lots of boxes and arrows.

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

所有自己的属性不包含其原型包含的特定属性的对象共享该属性及其值。 图1说明了这一点

CF 是一个构造函数(也是一个对象). 五个对象通过 new 表达式创建: cf1, cf2, cf3, cf4, and cf5. 每个对象都包含名为的属性 q1 and q2. 虚线表示隐式原型关系; 比如, cf3的 prototype 是 CFp. 构造函数, CF, 有2个自己的属性, 名为 P1P2, 其对于 CFp, cf1, cf2, cf3, cf4, 或 cf5不可见. 原型名为 CFP1 CFpcf1, cf2, cf3, cf4, and cf5共享 (除了 CF), 以及任何属性在 CFp的隐式原型链 中除了命名为q1, q2, or CFP1的属性. 注意,在 CFCFp之间没有隐式原型链接.

与大多数基于类的对象语言不同,属性可以通过向对象赋值来动态地添加到对象。 也就是说,构造函数不需要为所有或任何构造的对象的属性命名或赋值. 在上面的图中,可以为 cf1, cf2, cf3, cf4, and cf5添加一个新的共享属性,通过向 CFp分配一个新值.

虽然ECMAScript对象本质上不是基于类的,但是通常基于构造函数,原型对象和方法的常见模式来定义类似抽象的抽象是方便的。 ECMAScript内置对象本身遵循类似模式。 从ECMAScript 2015开始,ECMAScript语言包括句法类定义,允许程序员简明地定义符合内置对象所使用的类似类抽象模式的对象。

4.2.2ECMAScript的严格模式变体#

ECMAScript语言识别语言的一些用户可能希望限制其对语言中可用的一些特征的使用的可能性。 他们可能为了安全的目的这样做,以避免他们认为是容易出错的特征,获得增强的错误检查,或者出于其他选择的原因。 为了支持这种可能性,ECMAScript定义了语言的严格变体。 语言的严格变体排除了常规ECMAScript语言的一些特定语法和语义特征,并修改了一些特征的详细语义。 strict变体还指定了必须通过在非严格形式的语言中未指定为错误的情况下抛出错误异常来报告的其他错误条件。

ECMAScript的严格变体通常被称为语言的严格模式。 严格模式选择和ECMAScript的严格模式语法和语义的使用在单独的ECMAScript源文本单元的级别明确做出。 因为在语法源文本单元的级别选择严格模式,所以严格模式仅在这样的源文本单元内施加具有局部效果的限制。 严格模式不限制或修改ECMAScript语义的必须跨多个源文本单元一致地操作的任何方面。 完整的ECMAScript程序可以由严格模式和非严格模式ECMAScript源文本单元组成。 在这种情况下,严格模式仅适用于实际执行在严格模式源文本单元中定义的代码。

为了符合本规范,ECMAScript实现必须实现完全不受限的ECMAScript语言和本规范定义的ECMAScript语言的严格变体。 此外,实现必须支持将无限制和严格模式源文本单元组合成单个复合程序。

4.3术语和定义#

以下术语和定义适用于本文档.

4.3.1类型(type)#

本规范第6 节中定义的数据值集合

4.3.2原始值(primitive value)#

Undefined, Null, Boolean, Number, Symbol, String 在章节 6

Note

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

4.3.3对象(object)#

Object类型的成员

Note

对象是属性的集合,并且具有单个原型对象。 原型可以是null.

4.3.4构造函数(constructor)#

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

注意

构造函数的 prototype 属性的值是一个原型对象,用于实现继承和共享属性.

4.3.5原型(prototype)#

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

注意

当构造函数创建一个对象时, 该对象隐式引用构造函数的 原型(prototype) 属性,以解决属性引用的目的. 构造函数的原型(prototype)属性可以由程序表达式 constructor.prototype 引用,并且添加到对象原型的属性,通过继承所有对象共享原型。 或者,可以通过使用 Object.create 内置函数,使用明确指定的原型创建新对象。

4.3.6普通对象#

对象具有所有对象支持的基本内部方法

4.3.7非普通对象(exotic object)#

没有一个或多个基本内部默认方法的对象

Note

任何不是普通对象的对象都是非普通对象。

4.3.8标准对象#

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

4.3.9内置对象#

按照ECMAScript实现的对象

注意

标准内置对象在本规范中定义。 ECMAScript实现可以指定和提供附加种类的内置对象。 内置构造函数是一个内置对象,也是一个构造函数。

4.3.10未定义值#

原始值未分配值

4.3.11未定义类型#

类型,其唯一值是 undefined

4.3.12空值(null value)#

表示任何对象值的故意缺失的原始值

4.3.13空类型(Null type)#

类型,其唯一值是 null

4.3.14布尔值(Boolean value)#

布尔类型的成员

Note

只有两个布尔值, true false

4.3.15布尔类型(Boolean type)#

类型由原始值 true false 组成

4.3.16布尔对象(Boolean object)#

标准内置的 Boolean 构造函数的实例

注意

构造函数创建一个布尔对象,提供一个布尔值作为参数。 生成的对象有一个内部属性,其值为布尔值。 布尔对象可以强制为布尔值。

4.3.17字符串值(String value)#

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

Note

String值是String类型的成员。 序列中的每个整数值通常表示一个16位单位的UTF-16文本。 但是,ECMAScript不对值进行任何限制或要求,除非它们必须是16位无符号整数。

4.3.18字符串类型(String type)#

所有可能的字符串值

4.3.19字符串对象(String object)#

对象类型的成员,它是标准内置的 String 构造函数的实例

Note

使用 new String 构造函数创建一个String对象,并提供一个String值作为参数。 生成的对象有一个内部属性,其值为String值。 通过调用 String 构造函数作为函数,可以将String对象强制转换为String值 (21.1.1.1).

4.3.20数值(Number value)#

原始值对应于双精度64位二进制格式IEEE 754-2008值

Note

Number值是Number类型的成员,并且是数字的直接表示

4.3.21数字类型(Number type)#

包括所有可能的数值,包括特殊的“非数字”(NaN)值,正无穷大和负无穷大

4.3.22数字对象(Number object)#

对象类型的成员,它是标准内置的 Number 构造函数的实例

Note

通过使用 new Number 构造函数创建Number对象,并提供一个数字值作为参数。 生成的对象有一个内部属性,其值为数值。 通过调用 Number 构造函数作为函数,可以将Number对象强制转换为数字值 (20.1.1.1).

4.3.23无穷(Infinity)#

数值为正无限数值

4.3.24非数字(NaN)#

数字值,其是IEEE 754-2008“非数字”值

4.3.25符号值(Symbol value)#

原始值,表示唯一的非String的对象key值

4.3.26符号类型(Symbol type)#

所有可能的符号值

4.3.27符号对象(Symbol object)#

对象类型的成员,它是标准内置的 Symbol 构造函数的实例

4.3.28函数(function)#

可以作为子程序调用的对象类型的成员

注意

除了其属性,函数包含可执行代码和状态,确定调用时的行为方式。 函数的代码可以或不可以写在ECMAScript中.

4.3.29内置函数(built-in function)#

内置对象中的函数

注意

内置函数的示例包括 parseInt Math.exp 。 实现可以提供在本说明书中没有描述的与实现相关的内置函数。

4.3.30属性(property)#

一个对象的一部分,它将一个键(一个String值或一个Symbol值)和一个值相关联

Note

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

4.3.31方法(method)#

作为属性值的函数

注意

当一个函数被调用为一个对象的方法时,该对象作为其 this 值传递给函数.

4.3.32内置方法(built-in method)#

内置方法

Note

标准内置方法在本规范中定义,ECMAScript实现可以指定和提供其他附加的内置方法.

4.3.33属性(attribute)#

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

4.3.34自有属性(own property)#

对象直接包含的属性

4.3.35继承属性(inherited property)#

属性,它不是自己的属性,而是对象原型的属性(自己的或继承的)

4.4本规范的组织#

本规范的其余部分组织如下:

第5章定义了整个规范中使用的符号约定。

第6-9节定义了ECMAScript程序操作的执行环境。

第10-16节定义了实际的ECMAScript编程语言,包括其语法编码和所有语言特征的执行语义。

第17-26节定义了ECMAScript标准库。 它包括ECMAScript程序在执行时可用的所有标准对象的定义。

5符号约定#

5.1语法和词法(Syntactic and Lexical Grammars)#

5.1.1上下文无关语法#

上下文无关文法由多个产生式(productions)组成.每个production具有作为其左侧的非终止的抽象符号以及右侧零个或多个非终止符号和终止符 对于每个语法,终端符号从指定的字母表中绘制。

链产生式(chain production)是在其右侧具有一个非终端符号以及零个或多个终端符号的产品。

从由单个区分的非终止符(称为目标符号)组成的句子开始,给定的上下文无关语法规定了语言,即可能的 可以由右侧序列中的任何非终端,重复替换非终止符是左侧的终端符号的序列。

5.1.2词法和RegExp语法#

ECMAScript词法(lexical grammar) 在章节11. 该语法具有符合10.1中定义的源字符规则的Unicode码点. 它定义了一组生成,从目标符号 InputElementDiv InputElementTemplateTail InputElementRegExp InputElementRegExpOrTemplateTail ,它们描述了这些代码点的序列如何转换为一系列输入元素。

输入除空格和注释之外的元素构成ECMAScript语法语法的终端符号,称为ECMAScript 令牌(tokens)。这些令牌是ECMAScript语言的保留字,标识符,文字和标点符号。此外,行终止符虽然不被认为是令牌,但也成为输入元素流的一部分,并引导自动分号插入过程( 11.9 )。简单的空白和单行注释被丢弃,不会出现在句法语法的输入元素流中。 多行注释(MultiLineComment) (即表单 / * ... 的注释* / 无论是否跨越多行)同样简单地丢弃,如果它不包含行终止符;但如果 MultiLineComment 包含一个或多个行终止符,那么它将被单行终止符替换,成为其中的一部分的句法语法的输入元素流。

21.2.1 中给出了ECMAScript的RegExp语法外部参照>。 该语法还具有由 SourceCharacter 定义的代码点作为其终端符号。 它定义了一组生成,从目标符号 模式 开始,它们描述了代码点的序列如何转换为 正则表达式模式。

词法和RegExp语法的生成通过将两个冒号“ :: ”分隔为标点符号来区分。 词法和RegExp语法共享一些产生式。

5.1.3数字字符串语法(The Numeric String Grammar)#

另一种语法用于将字符串转换为数值。 这个语法类似于词法语法与数字文字有关的部分,并且具有其终端符号 源字符 。 这种语法在 7.1.3.1章节.

通过将三个冒号“ ::: ”作为标点符号来区分数字字符串语法的生成。

5.1.4语法的语法(The Syntactic Grammar)#

TECMAScript的语法语法在第11,12,13,14和15条中给出。该语法具有由词法语法定义为其终端符号的ECMAScript令牌( 5.1.2 )。 它定义了一组生产,从两个替代目标符号 脚本 模块 ,描述了令牌序列如何构成ECMAScript程序的语法正确的独立组件。

当代码点流被解析为ECMAScript 脚本 模块 ,首先通过重复应用词汇语法将其转换为输入元素流; 然后,这个输入元素流由语法语法的单个应用解析。 如果输入元素流中的令牌在没有遗漏的令牌的情况下,不能被解析为目标非终止的单个实例( 脚本 模块 ),则报错

只有一个冒号“”作为标点符号区分语法的语法的生成。

第12,13,14和15条中提出的语法语法不是完整的记录哪个令牌序列被接受为正确的ECMAScript 脚本 模块 。 还接受某些附加令牌序列,即如果在某些地方(例如在行终止符之前)仅将分号添加到序列中,那么语法将被描述。 此外,如果在某些“尴尬”的地方出现行终止符,则语法所描述的某些令牌序列不被认为是可接受的。

在某些情况下,为了避免歧义,句法语法使用广泛的制作,允许令牌序列不形成有效的ECMAScript 脚本 模块 。 例如,该技术用于对象文字和对象解构模式。 在这种情况下,提供了更加限制性的补充语法,其进一步限制可接受的令牌序列。 在某些上下文中,当明确指定时,使用补充语法的目标符号再次分析与这样的生产相对应的输入元素。 如果覆盖语法解析的输入元素流中的令牌不能被解析为相应的补充目标符号的单个实例,而没有令牌被遗忘,则输入流在语法上是错误的。

5.1.5语法符号(Grammar Notation)#

语法,RegExp和数字字符串语法的终端符号都显示在固定宽度字体中,无论是语法的生成还是在整个本规范中,只要文本直接引用这样的终端符号。 这些将以完全写成的脚本出现。 以这种方式指定的所有终端符号代码点应被理解为来自基本拉丁语范围的适当的Unicode代码点,而不是来自其他Unicode范围的任何类似代码点

非标签符号显示在斜体类型中。 非终止(也称为“生产”)的定义由定义的非终结符的名称引入,后跟一个或多个冒号。 (冒号数表示生产所属的语法)。非终结式的一个或多个替代右手边随后跟随。 例如,句法定义:

WhileStatement:while(Expression)Statement

表示非终止 While语句 表示 while ,后跟一个 左括号令牌,后跟一个 表达式 ,后跟右括号令牌,后跟一个 声明 表达式 声明 本身就是非终结者。 另一个例子,句法定义:

ArgumentList:AssignmentExpression ArgumentList,AssignmentExpression

s表示 ArgumentList 可能表示单个 AssignmentExpression ArgumentList , 后跟一个逗号,其后是 分配表达式 ArgumentList 的定义是递归的,也就是说,它是根据自身定义的。 结果是 ArgumentList 可能包含任何正数的参数,用逗号分隔,其中每个 参数表达式是 分配表达式 。 非终止的这种递归定义是常见的。

下标后缀“ opt ”,可能出现在终端或非终端之后,表示可选符号。 包含可选符号的替代实际上指定了两个右侧,一个省略了可选元素,另一个包含它。 这意味着:

VariableDeclaration:BindingIdentifierInitializeropt

是一个方便的缩写:

VariableDeclaration:BindingIdentifier BindingIdentifierInitializer

然后:

IterationStatement:for(LexicalDeclarationExpressionopt;Expressionopt)Statement

是一个方便的缩写:

IterationStatement:for(LexicalDeclaration;Expressionopt)Statement for(LexicalDeclarationExpression;Expressionopt)Statement

这又是一个缩写:

IterationStatement:for(LexicalDeclaration;)Statement for(LexicalDeclaration;Expression)Statement for(LexicalDeclarationExpression;)Statement for(LexicalDeclarationExpression;Expression)Statement

因此,在本示例中,迭代语句 的非终结符实际上有四个右侧的备选。

生产可以通过“ [parameters] ”形式的下标注释进行参数化,这可以显示为生产定义的非终结符号的后缀。 “parameters”可以是单个名称或逗号分隔的名称列表。 参数化生产是一组定义了参数名称的所有组合的缩写,后面是一个下划线,附加到参数化的非终结符号。 这意味着:

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

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

VariableDeclaration:BindingIdentifierInitializer[In]opt

是缩写为:

VariableDeclaration:BindingIdentifier BindingIdentifierInitializer_In

使用右侧非终结符号引用参数名称“”可以使参数值取决于参考当前生产的左侧符号的参数名称。 例如:

VariableDeclaration[In]:BindingIdentifierInitializer[?In]

是缩写为:

VariableDeclaration:BindingIdentifierInitializer VariableDeclaration_In:BindingIdentifierInitializer_In

如果右侧替代方案以“[+ parameter]“为前缀,则只有在引用生产的非终结符号时使用了该命名参数,该选项才可用。 如果右侧替代方案以“[~parameter]”作为前缀,则只有在引用生产的非终结符号时,该命名参数为not才可用。 这意味着:

StatementList[Return]:[+Return]ReturnStatement ExpressionStatement

是缩写为:

StatementList:ExpressionStatement StatementList_Return:ReturnStatement ExpressionStatement

StatementList[Return]:[~Return]ReturnStatement ExpressionStatement

是缩写为:

StatementList:ReturnStatement ExpressionStatement StatementList_Return:ExpressionStatement

当单词“one of”在语法定义中跟随冒号时,它们表示以下行或行上的每个终端符号都是替代定义。 例如,ECMAScript的词法语法包含生产:

NonZeroDigit::one of123456789

这只是一个方便的缩写:

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

如果短语“[empty]”出现在制作的右侧,则表示生产的右侧不包含终端或非终结符。

如果短语“[lookahead∉ set ]”出现在制作的右侧,则表示如果紧随其后的输入令牌序列是给定的成员,则表示生产可能不被使用setset可以写成一个逗号分隔的一个或两个元素终端序列的列表,它们以大括号括起来。 为了方便起见,该集合也可以被写为非终结符,在这种情况下,它表示非终端可以扩展的所有终端的集合。 如果set由单个终端组成,则可以使用短语“[lookahead≠ terminal ]”。

       例如,给定定义

DecimalDigit::one of0123456789 DecimalDigits::DecimalDigit DecimalDigitsDecimalDigit

定义

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

匹配字母 n ,后跟一个或多个十进制数字,其中第一个是偶数,或十进制数字不跟随另一个十进制数字。

如果句法语法生成的右侧出现“[no LineTerminator here]” ,表示产生式是限制性产生式:如果 LineTerminator 发生在指示位置的输入流中。 例如,生产:

ThrowStatement:throw[no LineTerminator here]Expression;

表示如果在 throw 之间的脚本中有 LineTerminator ,则 表达式 不会生效

除非限制生产禁止 LineTerminator 的存在,否则可能会出现任何数量的 LineTerminator 可能出现在输入元素流中的任何两个连续令牌之间,而不会影响脚本的句法可接受性。

当生成词汇语法或数字字符串语法的替代方案似乎是一个多码点标记时,它代表将构成这样一个令牌的代码点序列。

产生式的右侧可以指定使用短语“but not”,然后指示要排除的扩展名称是不允许某些扩展。 例如,生产:

Identifier::IdentifierNamebut not ReservedWord

意味着标识符 的非终止可以替换为任何代码点序列,可以替代 IdentifierName ,只要相同的代码点序列不能替代 ReservedWord

最后,在列举所有替代方案是不实际的情况下,以无衬线字体类型的描述性短语描述了一些非终结符号:

SourceCharacter::any Unicode code point

5.2算法约定#

规范通常使用编号列表来指定算法中的步骤。 这些算法用于精确指定ECMAScript语言结构所需的语义。 这些算法并不意味着使用任何具体的实现技术。 在实践中,可能有更有效的算法可用于实现给定的特征。

算法可以被明确地参数化,在这种情况下,参数的名称和用法必须作为算法定义的一部分提供。 为了便于在本说明书的多个部分使用它们,称为抽象操作的一些算法以参数化的功能形式命名和写入,以便它们可以由其他算法中的名称引用。 抽象操作通常使用诸如operationName( arg1 arg2 )的功能应用程序引用。 一些抽象操作被视为类类规范抽象的多态调度方法。 通常使用诸如 someValue .operationName( arg1 arg2 )的方法应用程序样式来引用这种类似方法的抽象操作。

调用抽象操作返回 完成 记录。 使用前缀为的功能应用程序样式和方法应用程序样式引用的抽象操作表示 ReturnIfAbrupt 应该应用于最终的 完成记录 。 例如, ? operationName()等效于 ReturnIfAbrupt (operationName())。 同样,? someValue .operationName()等效于 ReturnIfAbrupt ( someValue.operationName())。

前缀!用于表示抽象操作永远不会返回 突然完成 ,结果 完成记录 的值字段应该用于代替操作的返回值。 例如,“让 val var>成为!operationName()“等效于以下算法步骤:

  1. val 为operationName()。
  2. 断言: val 永远不会是 突然完成
  3. 如果 val 完成记录 ,让 val val .[[Value]]。     

算法可能与ECMAScript语法之一的生成相关联。 具有多个替代定义的生产通常对于每种替代方案具有不同的算法。 当算法与语法生产相关联时,它可以引用生产替代的终端和非终止符号,就像它们是算法的参数一样。 当以这种方式使用时,非终止符号是指解析源文本时匹配的实际替代定义。

当算法与生产替代方案相关联时,通常会显示替代方案,而没有任何“[]”语法注释。 这样的注释只能影响替代方法的句法识别,并且对替代方案的相关语义没有影响。

除非另有明确规定,否则所有链式产生式对于可能应用于产生式的左侧非终端的每个算法都有隐含的定义。 隐式定义简单地将相同的算法名称与相同的参数(如果有的话)重新应用于 链式产生式(chain production) 的唯一右手边的非终结符,然后返回结果。 例如,假设有一个产生式:

Block:{StatementList}

但是没有相应的执行算法被明确指定用于该产生式。 如果在一些算法中有一个形式的陈述:“返回执行结果 Block ”这是隐含的 存在以下形式的执行算法:

运行时语义:Evaluation

Block:{StatementList}
  1. Return the result of evaluating StatementList.返回evaluating StatementList 的结果。

为了表达的清楚,算法步骤可以被细分为顺序子步骤。 子项缩进,本身可以进一步划分成缩进的子步骤。 轮廓编号惯例用于识别具有标有小写字母字符的第一级子步骤的子步骤,以及用小写罗马数字标记的第二级子步骤。 如果需要三级以上,则这些规则使用数字标签与第四级重复。 例如:

  1. Top-level step
    1. Substep.
    2. Substep.
      1. Subsubstep.
        1. Subsubsubstep
          1. Subsubsubsubstep
            1. Subsubsubsubsubstep

步骤或子步骤可以被写为条件其子步骤的“if”谓词。 在这种情况下,只有在谓词为真的情况下才应用子步骤。 如果一个步骤或子步骤以“else”一词开始,那么它是一个谓词,它是同一级别上一个“if”谓词步骤的否定。

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

以“Assert:”开头的一个步骤说明了其算法的不变条件。 这样的断言被用于制定否则是隐式的显式算法不变量。 这种断言不会增加额外的语义要求,因此不需要由实现来检查。 它们仅用于澄清算法。

数学运算如加法,减法,否定,乘法,除法以及本章后面定义的数学函数,应该被理解为计算数学实数的精确数学结果,除非另有说明,否则不包括无穷大,不包括 与正零区分的负零。 该标准中的浮点运算模型的算法包括明确的步骤,在必要时,处理无穷大并签名为零并执行舍入。 如果将数学运算或函数应用于浮点数,则应理解为应用于由该浮点数表示的精确数学值; 这样的浮点数必须是有限的,如果它是 +0 -0 则相应的数学值只是0。

数学函数 abs x 产生绝对值 x ,它是 - x 如果 x 为负数(小于零),否则为 x 本身。

数学函数 min x1 x2 ,..., xN 产生数学上最小的 x1 xN 。 数学函数 max x1 x2 ,..., xN 产生数学上最大的 x1 xN 。 这些数学函数的域和范围包括 +∞-∞

符号" x modulo y "( y 必须是有限和非零)计算值 k y (或零)相同的符号,使得 abs ( k )< abs ( y )和 x - k = q × y 对于某个整数 q

数学函数 floor x 产生不大于 x 的最大整数(最接近正无穷大)。

注意

floor(x) = x-(x modulo 1).

5.3静态语义规则#

无上下文的语法没有足够的功能来表达所有规则,用于定义输入元素流是否形成有效的ECMAScript 脚本 模块 。 在某些情况下,需要使用ECMAScript算法约定或散文要求来表达额外的规则。 这样的规则总是与生成语法相关联,并被称为生产的静态语义

静态语义规则具有名称,通常使用算法定义。 命名静态语义规则与语法生产相关联,并且具有多个替代定义的生产通常对于每个替代方案,对于每个适用的命名静态语义规则来说都是不同的算法。

除非另有说明,否则本说明书中的每个语法生产替代方案都隐含地定义了一个名为Contains的静态语义规则,它包含一个名为 symbol 的参数,该参数的值是包含关联生产的语法的终端或非终结符。 Contains的默认定义是:

  1. 对于每个终端和非终结语法符号(For each terminal and nonterminal grammar symbol), sym, 在这个生产的定义中
    1. If sym is the same grammar symbol as symbol, return true.
    2. If sym is a nonterminal, then
      1. Let contained be the result of sym Contains symbol.
      2. If contained is true, return true.
  2. Return false.

上述定义明确地被覆盖了特定的产生式。

一种特殊的静态语义规则是一个 Early Error Rule 早期错误 规则定义 早期错误 条件(见条款与特定语法生成相关联的 16 )。执行大多数 早期错误 规则未在本规范的算法内显式调用。在 脚本 模块 ,验证所有 early error 脚本模块 。如果 早期错误 中的任何规则违反了脚本 模块 是无效,无法执行。

6ECMAScript数据类型和值#

本规范中的算法操纵每个值都具有关联类型的值。 可能的值类型是本节中定义的值类型。 类型进一步分类为ECMAScript语言类型(language types)和规范类型(specification types)。

在本说明书中,符号"Type(x)"用作“type of x” 的缩写, “type”是指本节中定义的ECMAScript语言和规范类型。 当使用术语“empty”就像命名一个值一样,它相当于说“没有任何类型的值”。

6.1ECMAScript语言类型(ECMAScript Language Types)#

一个 ECMAScript语言类型对应于ECMAScript程序员使用ECMAScript语言直接操作的值。 ECMAScript语言类型为Undefined,Null,Boolean,String,Symbol,Number和Object。 一个 ECMAScript语言值是以ECMAScript语言类型为特征的值。

6.1.1The Undefined Type#

The Undefined type 只有一个值,称为 undefined 。 未分配值的任何变量都具有值 undefined .

6.1.2The Null Type#

The Null type 只有一个值 null.

6.1.3The Boolean Type#

The Boolean type 表示具有两个值的逻辑实体 truefalse.

6.1.4The String Type#

String类型是零个或多个16位无符号整数值(元素“elements”)的所有有序序列的集合,最大长度为2 53 -1个元素。 字符串类型通常用于表示运行的ECMAScript程序中的文本数据,在这种情况下,String中的每个元素都被视为UTF-16代码单位值。 每个元素被认为占据该序列内的一个位置。 这些位置用非负整数索引。 第一个元素(如果有)是索引0,索引1的下一个元素(如果有的话),依次类推。 字符串的长度是其中的元素(即,16位值)的数量。 空字符串的长度为零,因此不包含元素。

其中ECMAScript操作解释字符串值,每个元素被解释为单个UTF-16代码单元。但是,ECMAScript对String值中的代码单元序列没有任何限制或要求,因此当解释为UTF-16代码单元序列时,它们可能不正确。不解释字符串内容的操作将它们视为未分化16位无符号整数的序列。函数 String.prototype.normalize (请参阅 21.1.3.12 )可用于显式标准化一个String值。 String.prototype.localeCompare (请参阅 21.1.3.10 )内部规范化字符串值,但没有其他操作会隐式地标准化它们所在的字符串。只有明确指定为语言或区域设置敏感的操作会产生语言敏感的结果。

注意

这种设计背后的理由是尽可能简单,高效地执行Strings。 如果ECMAScript源文本处于规范化形式C,则字符串字面值也将被归一化,只要它们不包含任何Unicode转义序列即可。

一些操作将字符串内容解释为UTF-16编码的Unicode代码点。 在这种情况下,解释是:

  • 范围为0到0xD7FF或0xE000到0xFFFF范围内的代码单元被解释为具有相同值的代码点。
  • 第一代码单元 c1 的范围为0xD800到0xDBFF,第二代码单元 c2 的两个代码单元的序列在0xDC00到0xDFFF的范围内,是 代理对,并被解释为具有值( c1 - 0xD800)×0x400 +( c2 - 0xDC00)+ 0x10000的代码点。 (查看 10.1.2)
  • 在0xD800到0xDFFF范围内但不是替代对的一部分的代码单元被解释为具有相同值的代码点。

6.1.5The Symbol Type#

The Symbol type 是可以用作Object属性的键的所有非String值的集合(6.1.7).

每个可能的符号值都是独一无二的.

每个符号值不可变地保存一个名为[[Description]]的关联值,它是 undefined 或一个String值。

6.1.5.1已知符号(Well-Known Symbols)#

已知符号是内置符号值,由本规范的算法明确引用。 它们通常用作其值用作规范算法的扩展点的属性的键。 除非另有规定,已知符号值由所有领域共享( 8.2 )。

        

在本说明书中,使用@@name形式的符号来引用公知的符号,其中“name”是 表1

Table 1: 已知Symbols
规格名称 [[Description]] 价值与目的
@@hasInstance "Symbol.hasInstance" 确定构造函数对象是否将对象识别为构造函数实例之一的方法。 由 instanceof 运算符的语义调用。
@@isConcatSpreadable "Symbol.isConcatSpreadable" 一个布尔值属性,如果为true,则表示一个对象可以通过 Array.prototype.concat 平坦化到其数组元素。
@@iterator "Symbol.iterator" 一种返回对象的默认迭代器的方法。 被称为for语句的语义。
@@match "Symbol.match" 与正则表达式匹配字符串的正则表达式方法。 由 String.prototype.match 方法调用。
@@replace "Symbol.replace" 一个正则表达式方法,用于替换字符串的匹配子字符串。 由 String.prototype.replace 方法调用。
@@search "Symbol.search" 一个正则表达式方法,它返回与正则表达式匹配的字符串中的索引。 由 String.prototype.search 方法调用。
@@species "Symbol.species" 一个函数值属性,它是用于创建派生对象的构造函数。
@@split "Symbol.split" 一个正则表达式方法,它在与正则表达式匹配的索引处分割字符串。 由 String.prototype.split 方法调用。
@@toPrimitive "Symbol.toPrimitive" 将对象转换为相应的原始值的方法。 由 ToPrimitive 抽象操作调用。
@@toStringTag "Symbol.toStringTag" 用于创建对象的默认字符串描述的String值属性。 通过内置方法访问 Object.prototype.toString
@@unscopables "Symbol.unscopables" 一个对象值属性,其自有和继承的属性名称是从具有关联对象的with中排除的属性名称。

6.1.6The Number Type#

Number类型正好是18437736874454810627(即 2 64 -2 53 +3 )值, 代表了IEEE标准二进制浮点算术中规定的双精度64位格式的IEEE 754-2008值,不同之处在于9007199254740990(即 2 53 -2 )独立的"非数字"值在ECMAScript中以单个特殊的 NaN 值表示。 (请注意, NaN 值由程序表达式 NaN 生成。)在某些实现中,外部代码可能能够检测各种Not- a-number值,但这种行为是依赖于实现的; 对于ECMAScript代码,所有 NaN 值彼此无法区分。

注意

可能在ArrayBuffer中观察到的位模式(请参阅 24.1 )之后,数值已被存储到其中并不一定与ECMAScript实现使用的该数值的内部表示相同。

还有另外两个特殊值,称为正无穷大负无穷大 。 为简洁起见,这些值也分别通过符号 +∞-∞来表示。 (请注意,这两个无限数值由程序表达式 +Infinity (或简称 Infinity )和 -Infinity 生成。)

另一个18437736874454810624(即264-253)值被称为有限数。 其中一半是正数,一半是负数; 对于每个有限的正数值,存在具有相同幅度的对应的负值。

请注意,存在正零负零。 为简洁起见,这些值也分别由符号 +0 -0 引用。 (请注意,这两个不同的零数值由程序表达式 +0 (或简称 0 )和 -0 生成。)

18437736874454810622(即 2 64 -2 53 -2 )有限非零值是二种:

18428729675200069632(即 2 64 -2 54 )被归一化

s × m × 2e

其中 s 是+1或-1, m 是小于2 53 但不小于2 52 sup>, e 是范围从-1074到971(含)的整数。

剩下的9007199254740990(即 2 53 -2 )值被非规范化,具有形式

s × m × 2e

其中 s 是+1或-1, m 是小于2 52 的正整数, e -1074。

请注意,其数量不大于2 53 的所有正整数和负整数可以在Number类型中表示(实际上,整数0具有两个表示, +0 和 -0 )。

有限数字如果为非零,并且是奇数有效位数 m 是奇数,否则为偶数

在本说明书中,短语“ x ”的数字值,其中 x 表示精确的非零真实数学量(甚至可能是非理性数字,如π)意味着数字值以下列方式选择。考虑Number类型的所有有限值的集合,其中删除了 -0 ,并添加了两个在Number类型中不能表示的附加值,即2 1024 (这是 + 1×2 53 ×2 971 )和 - 2 1024 (这是 - 1×2 53 ×2 971 )。选择最接近于 x 的该集合的成员。如果集合的两个值相等,则选择具有均匀有效位数的值;为此,两个额外的值2 1024 - 2 1024 被认为具有甚至显着性。最后,如果选择了2 1024 ,则将其替换为 +∞;如果选择了 - 2 1024 ,则将其替换为-∞;如果选择了 +0 ,当且仅当 x 小于零时,将其替换为 -0 任何其他选定的值不变地使用。结果是 x 的Number值。 (此过程完全符合IEEE 754-2008“从最接近,连接到偶数”模式的行为。)

一些ECMAScript运算符只处理特定范围内的整数,例如 - 2 31 通过 2 31 -1 ,或者范围为0到 2 16 -1 7.1 中数字转换操作的说明。

6.1.7The Object Type#

对象在逻辑上是属性的集合。 每个属性都是数据属性(data property)或访问器属性(accessor property):

  • data property ECMAScript语言值的键值对 和一组布尔属性组成。
  • accessor property 将键值与一个或两个访问器函数以及一组布尔属性相关联。 访问器函数用于存储或检索 ECMAScript语言值 与属性相关联。

使用键值识别属性。 属性键值是ECMAScript String值或Symbol值。 所有字符串和符号值(包括空字符串)都作为属性键有效。 property name是一个String值的属性键。

整数索引(integer index)是一个String值的属性键,它是一个规范的数字字符串(7.1.16),其数值为 +0 或正整数≤2 53 -1。数组索引(array index)是一个整数索引,其数值i在范围+0 ≤ i < 232-1

属性键用于访问属性及其值。 对于属性的访问有两种:getset,分别对应于值检索和赋值。 通过获取和设置访问可访问的属性包括作为对象的直接部分的自己的属性(own properties)和由另一个关联对象通过属性继承关系提供的继承属性(inherited properties)。 继承的属性可以是关联对象的自己的或继承的属性。 每个对象的属性必须每个都具有与该对象的其他属性的键值不同的键值。

所有对象都是逻辑上的属性集合,但是有多种形式的对象在其用于访问和操作其属性的语义上有所区别。 普通对象(Ordinary objects)是最常见的对象形式,具有默认对象语义。 异域对象(exotic object)是其属性语义与默认语义不同的任何形式的对象。

6.1.7.1属性的属性(Property Attributes)#

在本规范中使用属性来定义和解释Object属性的状态。 数据属性将键值与table2中列出的属性相关联Table 2.

Table 2: Attributes of a Data Property
Attribute Name Value Domain Description
[[Value]] Any ECMAScript language type 通过获取访问属性检索的值。 (The value retrieved by a get access of the property.)
[[Writable]] Boolean 如果 false ,ECMAScript代码尝试使用[[Set]]更改属性的[[Value]]属性将不会成功。
[[Enumerable]] Boolean 如果 true ,则属性将通过for-in枚举(请参阅13.7.5)。 否则,该属性不可枚举。
[[Configurable]] Boolean 如果 false ,尝试删除属性,将属性更改为访问者属性,或更改其属性([[Value]]除外)或将[[Writable]]更改为 false )将失败。

访问器属性(Accessor Property)将键值与 table3 中列出的属性相关联.

Table 3: Attributes of an Accessor Property
Attribute Name Value Domain Description
[[Get]] Object | Undefined 如果该值是一个Object,它必须是一个函数对象。 函数的[[Call]]内部方法( table6 )被调用一个空参数列表,用于在每次执行属性的访问访问时检索属性值。
[[Set]] Object | Undefined 如果该值是一个Object,它必须是一个函数对象。 函数的[[Call]]内部方法( table6 )被调用 每次执行属性的设置访问时,参数列表都包含分配的值作为唯一的参数。 属性的[[Set]]内部方法的效果可能但不是必要对属性的[[Get]]内部方法的后续调用返回的值有影响。
[[Enumerable]] Boolean 如果 true ,则属性将通过for-in枚举(请参阅13.7.5)。 否则,该属性不可枚举。
[[Configurable]] Boolean 如果 false ,尝试删除属性,将属性更改为数据属性或更改其属性将失败。

如果属性的属性(property's attributes)的初始值未由本规范明确指定,则 表4 被使用。

Table 4: Default Attribute Values
Attribute Name Default Value
[[Value]] undefined
[[Get]] undefined
[[Set]] undefined
[[Writable]] false
[[Enumerable]] false
[[Configurable]] false

6.1.7.2对象内部方法和内部插槽(Object Internal Methods and Internal Slots)#

ECMAScript中对象的实际语义是通过称为内部方法的算法指定的。 ECMAScript引擎中的每个对象与定义其运行时行为的一组内部方法相关联。 这些内部方法不是ECMAScript语言的一部分。 它们由本规范定义,仅用于说明目的。 但是,ECMAScript实现中的每个对象必须按照与它相关联的内部方法来指定。 这样做的确切方式是由实施决定的。

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

内部插槽(Internal slots)对应于与对象相关联并由各种ECMAScript规范算法使用的内部状态。 内部插槽不是对象属性,它们不是继承的。 根据具体的内部插槽规格,这种状态可能由任何 ECMAScript语言类型 或特定的ECMAScript规范类型值。 除非另有明确指定,内部插槽将作为创建对象的过程的一部分进行分配,并且可能不会动态添加到对象。 除非另有规定,内部插槽的初始值为 undefined 。 本规范中的各种算法创建了具有内部插槽的对象。 但是,ECMAScript语言不提供将内部插槽与对象相关联的直接方法。

内部方法和内部插槽在本规范中使用双括号[[]]中的名称进行标识.

Table 5 总结本规范使用的适用于由ECMAScript代码创建或操纵的所有对象的必需内部方法。 每个对象必须具有所有必要的内部方法的算法。 然而,所有对象不一定对这些方法使用相同的算法。

Table 5和其他类似表格的“签名”列描述了调用模式为每个内部方法。调用模式始终包含描述性参数名称的括号列表。如果参数名称与ECMAScript类型名称相同,则该名称将描述参数值所需的类型。如果内部方法明确地返回一个值,其参数列表后跟符号“→”和返回值的类型名称。签名中使用的类型名称是指在6增加了以下附加名称。 “any”表示该值可能是任何ECMAScript language type。内部方法隐式地返回一个Completion Record。除了其参数之外,内部方法始终可以访问作为方法调用目标的对象。

Table 5: 基本内部方法(Essential Internal Methods)
内部方法 (Internal Method) 签名 (Signature) 描述 (Description)
[[GetPrototypeOf]] () Object | Null 确定为该对象提供继承属性的对象。 一个 null 值表示没有继承属性。
[[SetPrototypeOf]] (Object | Null) Boolean 将此对象与提供继承属性的另一个对象相关联。 传递 null 表示没有继承的属性。 返回 true ,表示操作已成功完成,或 false 表示操作未成功。
[[IsExtensible]] ( ) Boolean 确定是否允许向此对象添加其他属性。
[[PreventExtensions]] ( ) Boolean 控制是否可以将新属性添加到此对象。 如果操作成功,返回 true ,否则返回 false
[[GetOwnProperty]] (propertyKey) Undefined | Property Descriptor 返回Property Descriptor 如果对象有属性 propertyKey, 否则返回 undefined
[[HasProperty]] (propertyKey) Boolean 返回一个布尔值,指示该对象是否具有自己的或继承的属性,其属性为 propertyKey
[[Get]] (propertyKey, Receiver) any 从该对象返回其键为 propertyKey 的属性的值。 如果必须执行任何ECMAScript代码来检索属性值,则在执行代码时,将使用 Receiver 作为this值。
[[Set]] (propertyKey, value, Receiver) Boolean 将键为 propertyKey 的属性的值设置为 value 。 如果必须执行任何ECMAScript代码来设置属性值,则在执行代码时,将使用 Receiver 作为this值。 如果属性值已设置或 false (如果无法设置)返回 true
[[Delete]] (propertyKey) Boolean 从该对象中删除其键为 propertyKey 的属性。 如果该属性未被删除并且仍然存在,则返回 false 。 如果属性被删除或不存在,返回 true
[[DefineOwnProperty]] (propertyKey, PropertyDescriptor) Boolean 创建或更改自己的属性,其关键是 propertyKey ,以具有由 PropertyDescriptor 描述的状态。 如果该属性成功创建/更新返回 true ,或者如果无法创建或更新该属性,则返回 false
[[OwnPropertyKeys]] ()List of propertyKey 返回一个Return a List其元素都是对象的自己的属性键。

Table 6 总结了可被称为函数的对象支持的其他基本内部方法。 函数对象(function object)是支持[[Call]]内部方法的对象。 constructor(构造函数)(也称为构造函数)是支持[[Construct]]内部方法的函数对象。

Table 6: 功能对象的附加基本内部方法
Internal Method Signature Description
[[Call]] (any, a List of any) any 执行与此对象关联的代码。 通过函数表达式调用。 内部方法的参数是一个this值,还有一个包含通过调用表达式传递给函数的参数的列表。 实现此内部方法的对象是可调用的(callable)
[[Construct]] (a List of any, Object) Object 创建一个对象。 通过newsuper运算符调用。 内部方法的第一个参数是包含运算符的参数的列表。 第二个参数是最初应用 new 运算符的对象。 实现此内部方法的对象称为构造函数(constructors)。 函数对象不一定是构造函数,而非构造函数对象没有[[Construct]]内部方法。

普通对象和标准外来对象的基本内部方法的语义在9 如果实现不支持外部对象的内部方法的任何指定使用,则尝试时该使用必须引发 TypeError 异常。

6.1.7.3基本内在方法的不变量#

ECMAScript引擎的对象的内部方法必须符合以下指定的不变量列表。 普通ECMAScript对象以及本规范中的所有标准异常对象都会保留这些不变量。 ECMAScript Proxy对象通过对[[ProxyHandler]]对象上调用的陷阱结果进行运行时检查来维护这些不变量。

提供异构对象的任何实现也必须为这些对象维护这些不变量。 违反这些不变量可能会导致ECMAScript代码具有不可预测的行为并创建安全问题。 但是,违反这些不变量绝对不会损害实现的内存安全。

实现不能允许以任何方式绕过这些不变量,例如通过提供实现基本内部方法的功能的替代接口,而不强制实现其不变量。

Definitions:

  • 内部方法的目标(target)是调用内部方法的对象。
  • 如果从[[IsExtensible]]内部方法返回false,或者[[PreventExtensions]]内部方法为true,那么目标是不可扩展的(non-extensible)
  • 不存在的(non-existent)属性是在不可扩展目标上作为自身属性不存在的属性。
  • 所有引用SameValue是根据SameValue算法。

[[GetPrototypeOf]] ( )

  • 返回值的类型必须为Object或Null。
  • 如果目标是不可扩展的(non-extensible),并且[[GetPrototypeOf]]返回一个值v,那么将来任何对[[GetPrototypeOf]]的调用应该返回SameValue作为v。
注1

对象的原型链应具有有限的长度(即从任何对象开始,将[[GetPrototypeOf]]内部方法递归应用于其结果应最终导致值为null)。 但是,如果原型链包含任何不使用[[GetPrototypeOf]]的普通对象定义的异常对象,则此要求不可执行为对象级不变量。 这样的圆形原型链可能会在访问对象属性时产生无限循环。

[[SetPrototypeOf]] (V)

  • 返回值的类型必须为布尔值。
  • 如果目标是不可扩展的,[[SetPrototypeOf]]必须返回false,除非V是SameValue作为目标的[[GetPrototypeOf]]值。

[[IsExtensible]] ( )

  • 返回值的类型必须为布尔值。
  • 如果[[IsExtensible]]返回false,则将来对目标中[[IsExtensible]]的调用必须返回false。

[[PreventExtensions]] ( )

  • 返回值的类型必须为布尔值。
  • 如果[[PreventExtensions]]返回true,则将来对目标中[[IsExtensible]]的调用必须返回false,目标被认为是不可扩展的(non-extensible)。

[[GetOwnProperty]] (P)

  • 返回值的类型必须是 Property Descriptor 或 Undefined.
  • 如果返回值的类型为 Property Descriptor, the 返回值必须是一个完整的属性描述符(property descriptor) (参考 6.2.4.6).
  • 如果属性P被描述为具有等于v的Desc.[[Value]],Desc.[[Writable]]和Desc.[[Configurable]]均为false的数据属性,则SameValue 必须在[[GetOwnProperty]](P)的所有将来调用时返回属性的Desc.[[Value]]属性
  • 如果[[Writable]]以外的P属性可能会随时间而改变,或属性可能会消失,则P的[[Configurable]]属性必须为true
  • 如果[[Writable]]属性可能从false更改为true,则[[Configurable]]属性必须为true。
  • 如果目标(target)是不可扩展(non-extensible)的且P不存在,那么目标上所有将来对[[GetOwnProperty]](P)的调用必须将P描述为不存在(即[[GetOwnProperty]](P)必须返回undefined。
注意2

作为第三个不变量的结果,如果属性被描述为数据属性,并且可能会随时间返回不同的值,则Desc.[[Writable]]和Desc.[[Configurable]]属性中的任何一个或两者必须是true 即使没有改变值(value)的机制也是通过其他内部方法暴露出来的。

[[DefineOwnProperty]] (P, Desc)

  • 返回值的类型必须为布尔值。
  • [[DefineOwnProperty]] 如果P以前被视为目标的不可配置(non-configurable)的自有属性,则必须返回false,除非:

    1. P是不可配置可写(non-configurable writable)的自己的数据属性。 不可配置可写数据属性可以更改为不可配置的不可写(non-configurable non-writable)数据属性。
    2. Desc中的所有属性都是作为P属性的SameValue
  • 如果目标是不可扩展的且P是不存在的属性,则[[DefineOwnProperty]](P,Desc)必须返回false。 也就是说,不可扩展的目标对象无法使用新属性进行扩展。

[[HasProperty]] ( P )

  • 返回值的类型必须为布尔值。
  • 如果P先前被视为目标的不可配置数据或访问者自己的属性,则[[HasProperty]]必须返回true。

[[Get]] (P, Receiver)

  • 如果P先前被视为具有值v的目标的不可配置的不可写入的(non-configurable, non-writable)自身数据属性,则[[Get]]必须返回SameValue
  • 如果P先前被视为[[Get]]属性未定义的目标的不可配置的自己的执行者属性,则[[Get]]操作必须返回undefined。

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

  • 返回值的类型必须为布尔值。
  • 如果P先前被视为目标的不可配置的,不可写的自己的数据属性,则[[Set]]必须返回false,除非V是SameValueP的[[Value]]属性。
  • 如果P先前被观察为[[Set]]属性未定义的目标的不可配置的自己的访问器属性,则[[Set]]操作必须返回false。

[[Delete]] ( P )

  • 返回值的类型必须为布尔值。
  • 如果以前观察到P是目标的不可配置的(non-configurable)自己的数据或访问器属性,则[[Delete]]必须返回false。

[[OwnPropertyKeys]] ( )

  • 返回值必须为 List.
  • 返回的List的每个元素必须是String或Symbol。
  • 返回的List必须至少包含以前已被观察到的所有不可配置的(non-configurable)自己的属性的键。
  • 如果对象不可扩展,则返回的List必须只包含使用[[GetOwnProperty]]可观察到的对象的所有属性的键。

[[Construct]] ( )

  • 返回值的类型必须为Object。

6.1.7.4知名的内在对象(Well-Known Intrinsic Objects)#

知名的内在性是本规范的算法明确引用的内置对象,通常有领域(realm)-特定身份。 除非另有说明,每个内在对象实际上对应于一组相似的对象,一个领域(realm).

在本规范中,诸如%name%的引用意味着与当前领域(realm)相关联的内在对象对应名称。 确定领域(realm)及其内在函数在8.3。 一些著名的特性列在Table 7中。

Table 7: 知名的内置对象
Intrinsic Name Global Name ECMAScript Language Association
%Array% Array The Array constructor (22.1.1)
%ArrayBuffer% ArrayBuffer The ArrayBuffer constructor (24.1.2)
%ArrayBufferPrototype% ArrayBuffer.prototype The initial value of the prototype data property of %ArrayBuffer%.
%ArrayIteratorPrototype% The prototype of Array iterator objects (22.1.5)
%ArrayPrototype% Array.prototype The initial value of the prototype data property of %Array% (22.1.3)
%ArrayProto_values% Array.prototype.values The initial value of the values data property of %ArrayPrototype% (22.1.3.30)
%Boolean% Boolean The Boolean constructor (19.3.1)
%BooleanPrototype% Boolean.prototype The initial value of the prototype data property of %Boolean% (19.3.3)
%DataView% DataView The DataView constructor (24.2.2)
%DataViewPrototype% DataView.prototype The initial value of the prototype data property of %DataView%
%Date% Date The Date constructor (20.3.2)
%DatePrototype% Date.prototype The initial value of the prototype data property of %Date%.
%decodeURI% decodeURI The decodeURI function (18.2.6.2)
%decodeURIComponent% decodeURIComponent The decodeURIComponent function (18.2.6.3)
%encodeURI% encodeURI The encodeURI function (18.2.6.4)
%encodeURIComponent% encodeURIComponent The encodeURIComponent function (18.2.6.5)
%Error% Error The Error constructor (19.5.1)
%ErrorPrototype% Error.prototype The initial value of the prototype data property of %Error%
%eval% eval The eval function (18.2.1)
%EvalError% EvalError The EvalError constructor (19.5.5.1)
%EvalErrorPrototype% EvalError.prototype The initial value of the prototype property of %EvalError%
%Float32Array% Float32Array The Float32Array constructor (22.2)
%Float32ArrayPrototype% Float32Array.prototype The initial value of the prototype data property of %Float32Array%.
%Float64Array% Float64Array The Float64Array constructor (22.2)
%Float64ArrayPrototype% Float64Array.prototype The initial value of the prototype data property of %Float64Array%
%Function% Function The Function constructor (19.2.1)
%FunctionPrototype% Function.prototype The initial value of the prototype data property of %Function%
%Generator% The initial value of the prototype property of %GeneratorFunction%
%GeneratorFunction% The constructor of generator objects (25.2.1)
%GeneratorPrototype% The initial value of the prototype property of %Generator%
%Int8Array% Int8Array The Int8Array constructor (22.2)
%Int8ArrayPrototype% Int8Array.prototype The initial value of the prototype data property of %Int8Array%
%Int16Array% Int16Array The Int16Array constructor (22.2)
%Int16ArrayPrototype% Int16Array.prototype The initial value of the prototype data property of %Int16Array%
%Int32Array% Int32Array The Int32Array constructor (22.2)
%Int32ArrayPrototype% Int32Array.prototype The initial value of the prototype data property of %Int32Array%
%isFinite% isFinite The isFinite function (18.2.2)
%isNaN% isNaN The isNaN function (18.2.3)
%IteratorPrototype% An object that all standard built-in iterator objects indirectly inherit from 所有标准的内置迭代器对象间接继承的对象
%JSON% JSON The JSON object (24.3)
%Map% Map The Map constructor (23.1.1)
%MapIteratorPrototype% The prototype of Map iterator objects (23.1.5)
%MapPrototype% Map.prototype The initial value of the prototype data property of %Map%
%Math% Math The Math object (20.2)
%Number% Number The Number constructor (20.1.1)
%NumberPrototype% Number.prototype The initial value of the prototype property of %Number%
%Object% Object The Object constructor (19.1.1)
%ObjectPrototype% Object.prototype The initial value of the prototype data property of %Object%. (19.1.3)
%ObjProto_toString% Object.prototype.toString The initial value of the toString data property of %ObjectPrototype% (19.1.3.6)
%ObjProto_valueOf% Object.prototype.valueOf The initial value of the valueOf data property of %ObjectPrototype% (19.1.3.7)
%parseFloat% parseFloat The parseFloat function (18.2.4)
%parseInt% parseInt The parseInt function (18.2.5)
%Promise% Promise The Promise constructor (25.4.3)
%PromisePrototype% Promise.prototype The initial value of the prototype data property of %Promise%
%Proxy% Proxy The Proxy constructor (26.2.1)
%RangeError% RangeError The RangeError constructor (19.5.5.2)
%RangeErrorPrototype% RangeError.prototype The initial value of the prototype property of %RangeError%
%ReferenceError% ReferenceError The ReferenceError constructor (19.5.5.3)
%ReferenceErrorPrototype% ReferenceError.prototype The initial value of the prototype property of %ReferenceError%
%Reflect% Reflect The Reflect object (26.1)
%RegExp% RegExp The RegExp constructor (21.2.3)
%RegExpPrototype% RegExp.prototype The initial value of the prototype data property of %RegExp%
%Set% Set The Set constructor (23.2.1)
%SetIteratorPrototype% The prototype of Set iterator objects (23.2.5)
%SetPrototype% Set.prototype The initial value of the prototype data property of %Set%
%String% String The String constructor (21.1.1)
%StringIteratorPrototype% The prototype of String iterator objects (21.1.5)
%StringPrototype% String.prototype The initial value of the prototype data property of %String%
%Symbol% Symbol The Symbol constructor (19.4.1)
%SymbolPrototype% Symbol.prototype The initial value of the prototype data property of %Symbol%. (19.4.3)
%SyntaxError% SyntaxError The SyntaxError constructor (19.5.5.4)
%SyntaxErrorPrototype% SyntaxError.prototype The initial value of the prototype property of %SyntaxError%
%ThrowTypeError% A function object that unconditionally throws a new instance of %TypeError%
%TypedArray% The super class of all typed Array constructors (22.2.1)
%TypedArrayPrototype% The initial value of the prototype property of %TypedArray%
%TypeError% TypeError The TypeError constructor (19.5.5.5)
%TypeErrorPrototype% TypeError.prototype The initial value of the prototype property of %TypeError%
%Uint8Array% Uint8Array The Uint8Array constructor (22.2)
%Uint8ArrayPrototype% Uint8Array.prototype The initial value of the prototype data property of %Uint8Array%
%Uint8ClampedArray% Uint8ClampedArray The Uint8ClampedArray constructor (22.2)
%Uint8ClampedArrayPrototype% Uint8ClampedArray.prototype The initial value of the prototype data property of %Uint8ClampedArray%
%Uint16Array% Uint16Array The Uint16Array constructor (22.2)
%Uint16ArrayPrototype% Uint16Array.prototype The initial value of the prototype data property of %Uint16Array%
%Uint32Array% Uint32Array The Uint32Array constructor (22.2)
%Uint32ArrayPrototype% Uint32Array.prototype The initial value of the prototype data property of %Uint32Array%
%URIError% URIError The URIError constructor (19.5.5.6)
%URIErrorPrototype% URIError.prototype The initial value of the prototype property of %URIError%
%WeakMap% WeakMap The WeakMap constructor (23.3.1)
%WeakMapPrototype% WeakMap.prototype The initial value of the prototype data property of %WeakMap%
%WeakSet% WeakSet The WeakSet constructor (23.4.1)
%WeakSetPrototype% WeakSet.prototype The initial value of the prototype data property of %WeakSet%

6.2ECMAScript规范类型(ECMAScript Specification Types)#

规范类型对应于在算法中用于描述ECMAScript语言结构和ECMAScript语言类型的语义的元值。规范类型为ReferenceList, Completion, Property Descriptor, 词法环境(Lexical Environment), 环境记录(Environment Record), and 数据块(Data Block)。规范类型值是不一定对应于ECMAScript实现中的任何特定实体的规范品。规范类型值可用于描述ECMAScript表达式执行的中间结果,但这些值不能作为ECMAScript语言变量的对象或值的属性存储

6.2.1列表和记录规范类型(The List and Record Specification Types)#

列表类型用于解释参数列表的执行(请参阅12.3.6)在new表达式中,在函数调用中以及需要简单的有序值列表的其他算法中。 列表类型的值是包含单个值的列表元素的简单有序序列。 这些序列可以是任何长度的。 可以使用0起始索引随机访问列表的元素。 为了方便起见,可以使用类数组的语法来访问List元素。 例如,arguments[2]是表示List arguments的第三个 rd 元素的缩写。

为了在本说明书内方便使用,文字语法可用于表示新的List值。 例如,«1,2»定义了一个List值,它具有两个元素,每个元素被初始化为一个特定的值。 一个新的空列表可以表示为«»。

Record 类型用于描述本规范算法中的数据聚合。 记录类型值由一个或多个命名字段组成。 每个字段的值都是ECMAScript值或由与Record类型相关联的名称表示的抽象值。 字段名称始终用双括号括起来,例如[[value]]。

为了在本说明书中表示方便,可以使用类似文字的语法来表示记录值。 例如,{[[Field1]]:42,[[Field2]]: false ,[[Field3]]: empty 定义一个具有三个字段的记录值,每个字段都被初始化为一个特定值。 字段名称顺序不重要。 任何未明确列出的字段都被视为不存在。

在规范文本和算法中,可以使用点符号来表示记录值的特定字段。 例如,如果R是上一段所示的记录,则R.[[Field2]]是“名为[[Field2]]的R的字段的缩写。

可以命名常用记录字段组合的模式,并且该名称可以用作字面记录值的前缀,以标识正在描述的特定类型的聚合。 例如:PropertyDescriptor {[[Value]]:42,[[Writable]]: false ,[[Configurable]]: true }。

6.2.2完成记录规范类型(The Completion Record Specification Type)#

完成类型是Record用于解释值和控制流的运行时传播,例如语句的行为(break, continue, return and throw),执行控制的非本地转移。

完成类型的值为Record其字段由Table 8定义。 这些值被称为完成记录(Completion Record)

Table 8: Completion Record Fields
Field Value 含义
[[Type]] normal, break, continue, return, 或 throw其中之一 发生的完成类型。
[[Value]] 任何 ECMAScript language valueempty 产生的value
[[Target]] 任何 ECMAScript string 或 empty 用于定向控制传输的目标标签。

术语“突然完成”是指除[ normal 之外的[[Type]]值的任何完成。

6.2.2.1正常完成(NormalCompletion)#

具有单个argument的抽象操作NormalCompletion,如:

  1. Return NormalCompletion(argument).

是一个速记,定义如下:

  1. Return Completion{[[Type]]: normal, [[Value]]: argument, [[Target]]: empty}.

6.2.2.2隐性完成值(Implicit Completion Values)#

本规范的算法通常隐含地返回CompletionRecords其[[Type]]是normal。 除非从上下文中显而易见,否则返回不是Completion Record,如:

  1. Return "Infinity".

意思是同样的事情:

  1. Return NormalCompletion("Infinity").

但是,如果“return”语句的值表达式为完成记录 结构文字,结果完成记录会被返回。 如果值表达式是对抽象操作的调用,则“返回”语句只返回由抽象操作产生的完成记录

抽象操作完成(completionRecord)用于强调以前计算的完成记录(Completion Record)正在返回。 完成抽象操作需要一个参数, completionRecord ,并执行以下步骤:

  1. 断言(Assert): completionRecord 是一个 Completion Record.
  2. Return completionRecord 作为抽象操作的Completion Record

在算法步骤中没有值的“return”语句意味着与以下相同的事情:

  1. Return NormalCompletion(undefined).

一个完成记录(Completion Record)的任何引用的上下文中的一个值,该表达式不显式地要求完整的完成记录Completion Record值相当于对[[Value]]字段的显式引用 完成记录值,除非完成记录(Completion Record)是一个突然完成(abrupt completion)

6.2.2.3抛出异常(Throw an Exception)#

算法步骤来说明抛出异常,比如

  1. Throw a TypeError exception.

意味着:

  1. Return Completion{[[Type]]: throw, [[Value]]: a newly created TypeError object, [[Target]]: empty}.

6.2.2.4如果突然返回(ReturnIfAbrupt)#

算法步骤说明等同于:

  1. ReturnIfAbrupt(argument).

意味着:

  1. If argument is an 突然完成(abrupt completion), return argument.
  2. Else if argument is a 正常完成(Completion Record), let argument be argument.[[Value]].

算法步骤说明或者等同于:

  1. ReturnIfAbrupt(AbstractOperation()).

意味着:

  1. Let hygienicTemp be AbstractOperation().
  2. If hygienicTemp is an abrupt completion, return hygienicTemp.
  3. Else if hygienicTemp is a Completion Record, let hygienicTemp be hygienicTemp.[[Value]].

hygienicTemp只是在与ReturnIfAbrupt相关的步骤中短暂的可见。

6.2.2.5UpdateEmpty ( completionRecord, value)#

带有参数 completionRecord value 的抽象操作UpdateEmpty执行以下步骤:

  1. 断言(Assert): 如果 completionRecord.[[Type]] 是 returnthrow, 那么 completionRecord.[[Value]] is not empty.
  2. 如果 completionRecord.[[Value]] 不是 empty, return Completion(completionRecord).
  3. Return Completion{[[Type]]: completionRecord.[[Type]], [[Value]]: value, [[Target]]: completionRecord.[[Target]] }.

6.2.3参考规格类型(The Reference Specification Type)#

注意

参考类型用于解释诸如 delete typeof ,赋值运算符, super 关键字和其他语言特征等运算符的行为。 例如,分配的左操作数有望产生参考。

一个参考(The Reference)是解析的名称或属性绑定。 Reference由三个组件, base 值,引用的名称(referenced name)和布尔值的严格引用(strict reference)标志组成。 base值是 undefined ,对象,布尔值,字符串,符号,数字或环境记录(Environment Record) undefined base 值表示“引用”无法解析为绑定。 引用的名称(referenced name)是一个String或Symbol值。

Super Reference是用于表示使用super关键字表达的名称绑定的参考。 Super Reference有一个额外的 thisValue 组件,其 base 值永远不会是一个环境记录(Environment Record)

本规范中使用以下抽象操作来访问引用的组件:

  • GetBase(V). Returns the base value component of the reference V.
  • GetReferencedName(V). Returns the referenced name component of the reference V.
  • IsStrictReference(V). Returns the strict reference flag component of the reference V.
  • HasPrimitiveBase(V). Returns true if Type(base) is Boolean, String, Symbol, or Number.
  • IsPropertyReference(V). Returns true if either the base value is an object or HasPrimitiveBase(V) is true; otherwise returns false.
  • IsUnresolvableReference(V). Returns true if the base value is undefined and false otherwise.
  • IsSuperReference(V). Returns true if this reference has a thisValue component.

本规范中使用以下抽象操作来对引用进行操作:

6.2.3.1GetValue (V)#

  1. ReturnIfAbrupt(V).
  2. If Type(V) is not Reference, return V.
  3. Let base be GetBase(V).
  4. If IsUnresolvableReference(V) is true, throw a ReferenceError exception.
  5. If IsPropertyReference(V) is true, then
    1. If HasPrimitiveBase(V) is true, then
      1. Assert: In this case, base will never be null or undefined.
      2. Let base be ToObject(base).
    2. Return ? base.[[Get]](GetReferencedName(V), GetThisValue(V)).
  6. Else base must be an Environment Record,
    1. Return ? base.GetBindingValue(GetReferencedName(V), IsStrictReference(V)) (参考 8.1.1).
Note

可能在步骤5.a.ii中创建的对象在上述抽象操作和普通对象[[Get]]内部方法之外是不可访问的。 实现可能会选择避免实际创建对象.

6.2.3.2PutValue (V, W)#

  1. ReturnIfAbrupt(V).
  2. ReturnIfAbrupt(W).
  3. If Type(V) is not Reference, throw a ReferenceError exception.
  4. Let base be GetBase(V).
  5. If IsUnresolvableReference(V) is true, then
    1. If IsStrictReference(V) is true, then
      1. Throw a ReferenceError exception.
    2. Let globalObj be GetGlobalObject().
    3. Return ? Set(globalObj, GetReferencedName(V), W, false).
  6. Else if IsPropertyReference(V) is true, then
    1. If HasPrimitiveBase(V) is true, then
      1. Assert: In this case, base will never be null or undefined.
      2. Set base to ToObject(base).
    2. Let succeeded be ? base.[[Set]](GetReferencedName(V), W, GetThisValue(V)).
    3. If succeeded is false and IsStrictReference(V) is true, throw a TypeError exception.
    4. Return.
  7. Else base must be an Environment Record,
    1. Return ? base.SetMutableBinding(GetReferencedName(V), W, IsStrictReference(V)) (参考 8.1.1).
注意

可以在步骤6.a.ii中创建的对象不能在上述算法和普通对象[[Set]]内部方法之外访问。 实现可能会选择避免实际创建该对象.

6.2.3.3GetThisValue (V)#

  1. Assert: IsPropertyReference(V) is true.
  2. If IsSuperReference(V) is true, then
    1. Return the value of the thisValue component of the reference V.
  3. Return GetBase(V).

6.2.3.4InitializeReferencedBinding (V, W)#

  1. ReturnIfAbrupt(V).
  2. ReturnIfAbrupt(W).
  3. Assert: Type(V) is Reference.
  4. Assert: IsUnresolvableReference(V) is false.
  5. Let base be GetBase(V).
  6. Assert: base is an Environment Record.
  7. Return base.InitializeBinding(GetReferencedName(V), W).

6.2.4属性描述符规范类型(The Property Descriptor Specification Type)#

属性描述符(Property Descriptor)类型用于解释对象属性特性(property attributes)的操作和重新定义。属性描述符类型的值为记录。每个字段的名称都是属性名称,其值是相应的属性值,如6.1.7.1。此外,任何领域可能存在或不存在。在本规范中用于标识属性描述符记录的文字描述的模式名称是“PropertyDescriptor”。

属性描述符值(Property Descriptor values)可以基于某些字段的存在或使用而进一步分类为数据属性描述符(data Property Descriptors)和访问者属性描述符(accessor Property Descriptors)。数据属性描述符是包含任何名为[[Value]]或[[Writable]]的字段。一个访问者属性描述符是包含任何名为[[Get]]或[[Set]]的字段。任何属性描述符可能包含名为[[Enumerable]]和[[Configurable]]的字段。属性描述符值可能不是数据属性描述符和访问器属性描述符。通用属性描述符是属性描述符值,它既不是数据属性描述符也不是访问器属性描述符。完全填充的属性描述符是一个访问器属性描述符或数据属性描述符,并且具有Table 2 or Table 3定义的熟悉

本规范中使用以下抽象操作来操作属性描述符值:

6.2.4.1IsAccessorDescriptor ( Desc )#

当使用属性描述符(Property Descriptor) Desc 调用抽象操作IsAccessorDescriptor时,执行以下步骤:

  1. If Desc is undefined, return false.
  2. If both Desc.[[Get]] and Desc.[[Set]] are absent, return false.
  3. Return true.

6.2.4.2IsDataDescriptor ( Desc )#

当使用Property Descriptor Desc调用抽象操作IsDataDescriptor时 ,执行以下步骤:

  1. If Desc is undefined, return false.
  2. If both Desc.[[Value]] and Desc.[[Writable]] are absent, return false.
  3. Return true.

6.2.4.3IsGenericDescriptor ( Desc )#

当使用Property Descriptor Desc调用抽象操作IsGenericDescriptor时,执行以下步骤:

  1. If Desc is undefined, return false.
  2. If IsAccessorDescriptor(Desc) and IsDataDescriptor(Desc) are both false, return true.
  3. Return false.

6.2.4.4FromPropertyDescriptor ( Desc )#

当使用Property Descriptor Desc调用抽象操作FromPropertyDescriptor时,执行以下步骤:

  1. If Desc is undefined, return undefined.
  2. Let obj be ObjectCreate(%ObjectPrototype%).
  3. Assert: obj is an extensible ordinary object with no own properties.
  4. If Desc has a [[Value]] field, then
    1. Perform CreateDataProperty(obj, "value", Desc.[[Value]]).
  5. If Desc has a [[Writable]] field, then
    1. Perform CreateDataProperty(obj, "writable", Desc.[[Writable]]).
  6. If Desc has a [[Get]] field, then
    1. Perform CreateDataProperty(obj, "get", Desc.[[Get]]).
  7. If Desc has a [[Set]] field, then
    1. Perform CreateDataProperty(obj, "set", Desc.[[Set]]).
  8. If Desc has an [[Enumerable]] field, then
    1. Perform CreateDataProperty(obj, "enumerable", Desc.[[Enumerable]]).
  9. If Desc has a [[Configurable]] field, then
    1. Perform CreateDataProperty(obj, "configurable", Desc.[[Configurable]]).
  10. Assert: all of the above CreateDataProperty operations return true.
  11. Return obj.

6.2.4.5ToPropertyDescriptor ( Obj )#

当使用对象 Obj 调用抽象操作ToPropertyDescriptor时,执行以下步骤:

  1. If Type(Obj) is not Object, throw a TypeError exception.
  2. Let desc be a new Property Descriptor that initially has no fields.
  3. Let hasEnumerable be ? HasProperty(Obj, "enumerable").
  4. If hasEnumerable is true, then
    1. Let enum be ToBoolean(? Get(Obj, "enumerable")).
    2. Set the [[Enumerable]] field of desc to enum.
  5. Let hasConfigurable be ? HasProperty(Obj, "configurable").
  6. If hasConfigurable is true, then
    1. Let conf be ToBoolean(? Get(Obj, "configurable")).
    2. Set the [[Configurable]] field of desc to conf.
  7. Let hasValue be ? HasProperty(Obj, "value").
  8. If hasValue is true, then
    1. Let value be ? Get(Obj, "value").
    2. Set the [[Value]] field of desc to value.
  9. Let hasWritable be ? HasProperty(Obj, "writable").
  10. If hasWritable is true, then
    1. Let writable be ToBoolean(? Get(Obj, "writable")).
    2. Set the [[Writable]] field of desc to writable.
  11. Let hasGet be ? HasProperty(Obj, "get").
  12. If hasGet is true, then
    1. Let getter be ? Get(Obj, "get").
    2. If IsCallable(getter) is false and getter is not undefined, throw a TypeError exception.
    3. Set the [[Get]] field of desc to getter.
  13. Let hasSet be ? HasProperty(Obj, "set").
  14. If hasSet is true, then
    1. Let setter be ? Get(Obj, "set").
    2. If IsCallable(setter) is false and setter is not undefined, throw a TypeError exception.
    3. Set the [[Set]] field of desc to setter.
  15. If either desc.[[Get]] or desc.[[Set]] is present, then
    1. If either desc.[[Value]] or desc.[[Writable]] is present, throw a TypeError exception.
  16. Return desc.

6.2.4.6CompletePropertyDescriptor ( Desc )#

当使用Property Descriptor Desc调用抽象操作CompletePropertyDescriptor时,执行以下步骤:

  1. Assert: Desc is a Property Descriptor.
  2. Let like be Record{[[Value]]: undefined, [[Writable]]: false, [[Get]]: undefined, [[Set]]: undefined, [[Enumerable]]: false, [[Configurable]]: false}.
  3. If either IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then
    1. If Desc does not have a [[Value]] field, set Desc.[[Value]] to like.[[Value]].
    2. If Desc does not have a [[Writable]] field, set Desc.[[Writable]] to like.[[Writable]].
  4. Else,
    1. If Desc does not have a [[Get]] field, set Desc.[[Get]] to like.[[Get]].
    2. If Desc does not have a [[Set]] field, set Desc.[[Set]] to like.[[Set]].
  5. If Desc does not have an [[Enumerable]] field, set Desc.[[Enumerable]] to like.[[Enumerable]].
  6. If Desc does not have a [[Configurable]] field, set Desc.[[Configurable]] to like.[[Configurable]].
  7. Return Desc.

6.2.5词法环境和环境记录规范类型#

词法环境(Lexical Environment)环境记录(Environment Record)类型用于解释嵌套函数和块中名称解析的行为。 这些类型和操作在8.1中定义。

6.2.6数据块(Data Block)#

The 数据块(Data Block) 规范类型用于描述字节大小(8位)数值的不同且可变的序列。 创建一个数据块值,固定数量的字节每个都具有初始值0。

为了在本说明书内令人满意,可以使用类似数组的语法来访问数据块值的各个字节。 该符号表示数据块值作为0始发整数索引的字节序列。 例如,如果db是5字节的数据块值,则可以使用 db [2]来访问其 第 3 个字节。

在本规范中使用以下抽象操作来对数据块值进行操作:

6.2.6.1CreateByteDataBlock (size)#

当使用整型参数 size 调用抽象操作CreateByteDataBlock时,执行以下步骤:

  1. Assert: size≥0.
  2. Let db be a new Data Block value consisting of size bytes. If it is impossible to create such a Data Block, throw a RangeError exception.
  3. Set all of the bytes of db to 0.
  4. Return db.

6.2.6.2CopyDataBlockBytes (toBlock, toIndex, fromBlock, fromIndex, count)#

当抽象操作CopyDataBlockBytes被调用时,采取以下步骤:

  1. Assert: fromBlock and toBlock are distinct Data Block values.
  2. Assert: fromIndex, toIndex, and count are integer values ≥ 0.
  3. Let fromSize be the number of bytes in fromBlock.
  4. Assert: fromIndex+countfromSize.
  5. Let toSize be the number of bytes in toBlock.
  6. Assert: toIndex+counttoSize.
  7. Repeat, while count>0
    1. Set toBlock[toIndex] to the value of fromBlock[fromIndex].
    2. Increment toIndex and fromIndex each by 1.
    3. Decrement count by 1.
  8. Return NormalCompletion(empty).

7抽象操作(Abstract Operations)#

这些操作不是ECMAScript语言的一部分; 它们在这里被定义为仅仅是为了帮助规范ECMAScript语言的语义。 在本说明书中定义了其他更专业的抽象操作。

7.1类型转换(Type Conversion)#

ECMAScript语言根据需要隐式执行自动类型转换。 为了澄清某些结构的语义,定义一组转换抽象操作是很有用的。 转换抽象操作是多态的; 他们可以接受任何ECMAScript语言类型。 但是没有其他规范类型用于这些操作。

7.1.1ToPrimitive ( input [ , PreferredType ] )#

抽象操作ToPrimitive采用 input 参数和可选参数 PreferredType 。 抽象操作ToPrimitive将其 input 参数转换为非Object类型。 如果对象能够转换为多个基本类型,则可以使用可选的提示 PreferredType 来支持该类型。 根据表9 (Table 9):

Table 9: ToPrimitive Conversions(转换)
Input Type Result
Undefined Return input.
Null Return input.
Boolean Return input.
Number Return input.
String Return input.
Symbol Return input.
Object 执行此表后面的步骤。

type input )是Object,执行以下步骤:

  1. If PreferredType was not passed, let hint be "default".
  2. Else if PreferredType is hint String, let hint be "string".
  3. Else PreferredType is hint Number, let hint be "number".
  4. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
  5. If exoticToPrim is not undefined, then
    1. Let result be ? Call(exoticToPrim, input, « hint »).
    2. If Type(result) is not Object, return result.
    3. Throw a TypeError exception.
  6. If hint is "default", let hint be "number".
  7. Return ? OrdinaryToPrimitive(input, hint).

当使用参数 O hint 调用抽象操作OrdinaryToPrimitive时,将采取以下步骤:

  1. Assert: Type(O) is Object.
  2. Assert: Type(hint) is String and its value is either "string" or "number".
  3. If hint is "string", then
    1. Let methodNames be « "toString", "valueOf" ».
  4. Else,
    1. Let methodNames be « "valueOf", "toString" ».
  5. For each name in methodNames in List order, do
    1. Let method be ? Get(O, name).
    2. If IsCallable(method) is true, then
      1. Let result be ? Call(method, O).
      2. If Type(result) is not Object, return result.
  6. Throw a TypeError exception.
注意

当ToPrimitive被调用时没有hint参数,那么它通常表现得像hint是Number一样。 但是,通过定义@@ toPrimitive方法,对象可能会覆盖此行为。 在本规范中定义的对象中只有Date对象(20.3.4.45))和Symbol对象(请参阅19.4.3.4)覆盖默认的ToPrimitive行为。 日期对象没有hint,就像hint是String一样。

7.1.2ToBoolean ( argument )#

抽象操作ToBoolean将argument转换为类型Boolean的值 Table 10:

Table 10: ToBoolean Conversions
Argument Type Result
Undefined Return false.
Null Return false.
Boolean Return argument.
Number Return false if argument is +0, -0, or NaN; otherwise return true.
String Return false if argument is the empty String (its length is zero); otherwise return true.
Symbol Return true.
Object Return true.

7.1.3ToNumber ( argument )#

抽象操作ToNumber将参数转换为类型为Number的值Table 11:

Table 11: ToNumber Conversions
Argument Type Result
Undefined Return NaN.
Null Return +0.
Boolean Return 1 if argument is true. Return +0 if argument is false.
Number Return argument (no conversion).
String 请参阅下面的语法和转换算法。
Symbol Throw a TypeError exception.
Object

应用以下步骤:

  1. Let primValue be ? ToPrimitive(argument, hint Number).
  2. Return ? ToNumber(primValue).

7.1.3.1ToNumber应用于字符串类型#

应用于字符串的ToNumber将以下语法应用于输入字符串,将其解释为UTF-16个编码代码点(6.1.4).)。 如果语法不能将字符串解释为StringNumericLiteral的扩展,那么ToNumberNaN

注意 1

该语法的终端符号全部由Unicode BMP代码点组成,因此如果字符串包含任何补充代码点或任何未配对代理代码的UTF-16编码,结果将为 NaN 点。

语法(Syntax)

StringNumericLiteral:::StrWhiteSpaceopt StrWhiteSpaceoptStrNumericLiteralStrWhiteSpaceopt StrWhiteSpace:::StrWhiteSpaceCharStrWhiteSpaceopt StrWhiteSpaceChar:::WhiteSpace LineTerminator StrNumericLiteral:::StrDecimalLiteral BinaryIntegerLiteral OctalIntegerLiteral HexIntegerLiteral StrDecimalLiteral:::StrUnsignedDecimalLiteral +StrUnsignedDecimalLiteral -StrUnsignedDecimalLiteral StrUnsignedDecimalLiteral:::Infinity DecimalDigits.DecimalDigitsoptExponentPartopt .DecimalDigitsExponentPartopt DecimalDigitsExponentPartopt

关于数字文字(numeric literals)的词汇语法,上面没有明确定义的所有语法符号,在(11.8.3中定义)

注意 2

StringNumericLiteralNumericLiteral之间的区别:

7.1.3.1.1运行时语义(Runtime Semantics): MV's#

将字符串转换为数字值总体上与确定数字文字的数字值完全相同 (参考 11.8.3), 但是一些细节是不同的,所以在这里给出了将StringNumericLiteral转换为Number类型的值的过程。 该值通过两个步骤确定:首先,数学值(MV)从StringNumericLiteral导出; 第二,这个数学值如下所述舍入。 任何语法符号上的MV(未在下面提供)是在11.8.3.1定义.

一旦字符串数字文字的确切的MV已经确定,它将被四舍五入为数字类型的值。如果MV为0,则舍入值为 +0 ,除非String数字文字中的第一个非空格代码点是“ - ”这种情况下,舍入值为 -0 。否则,舍入值必须是MV的Number值(在6.1.6),除非文字包含一个 StrUnsignedDecimalLiteral 并且文字具有20个以上的有效数字,在这种情况下,数字值可以是通过用20位替换20位之后的每个有效数字产生的字面值的MV的Number值,通过用20位替换第20位之后的每个有效数字,然后在第20位数位置递增字面值产生的字面值的MV值。如果不是 ExponentPart 的一部分,则数字很重要

  • it is not 0; or
  • 其左侧有一个非零数字,并且在它的右边有一个非零数字,不在ExponentPart中.

7.1.4ToInteger ( argument )#

抽象操作ToInteger将argument转换为整数数值。 该抽象操作的功能如下:

  1. Let number be ? ToNumber(argument).
  2. If number is NaN, return +0.
  3. If number is +0, -0, +∞, or -∞, return number.
  4. Return the number value that is the same sign as number and whose magnitude is floor(abs(number)).

7.1.5ToInt32 ( argument )#

抽象操作ToInt32将argument转换为232中的一个整数值,其范围为 - 2 31 2 31 -1 。该抽象操作的功能如下:

  1. Let number be ? ToNumber(argument).
  2. If number is NaN, +0, -0, +∞, or -∞, return +0.
  3. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)).
  4. Let int32bit be int modulo 232.
  5. If int32bit ≥ 231, return int32bit - 232; otherwise return int32bit.
注意

给定了ToInt32的上述定义:

  • ToInt32抽象操作是幂等的:如果应用于其生成的结果,则第二个应用程序使该值保持不变。
  • ToInt32(ToUint32(x))等于ToInt32(x)的所有值 x 。 (为了保留后一个属性,将 +∞-∞映射到 +0 。)
  • ToInt32 映射 -0+0.

7.1.6ToUint32 ( argument )#

抽象操作ToUint32将argument转换为232个整数之一,范围0到232-1(含)。 该抽象操作的功能如下:

  1. Let number be ? ToNumber(argument).
  2. If number is NaN, +0, -0, +∞, or -∞, return +0.
  3. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)).
  4. Let int32bit be int modulo 232.
  5. Return int32bit.
注意

给定了ToUint32的上述定义:

  • ToUint32 和 ToInt32步骤5是唯一的区别.
  • ToUint32抽象操作是幂等的:如果应用于其生成的结果,则第二个应用程序使该值保持不变。
  • ToUint32(ToInt32(x)) 是一样的 ToUint32(x) 对于所有参数 x. ( +∞-∞ 被映射到 +0.)
  • ToUint32 映射 -0+0.

7.1.7ToInt16 ( argument )#

抽象操作ToInt16将argument转换为2 16 个整数值之一,范围为-32768至32767(含)2 16 。 该抽象操作的功能如下:

  1. Let number be ? ToNumber(argument).
  2. If number is NaN, +0, -0, +∞, or -∞, return +0.
  3. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)).
  4. Let int16bit be int modulo 216.
  5. If int16bit ≥ 215, return int16bit - 216; otherwise return int16bit.

7.1.8ToUint16 ( argument )#

抽象操作ToUint16将argument转换为216个整数之一,范围0到216-1(含)。 该抽象操作的功能如下:

  1. Let number be ? ToNumber(argument).
  2. If number is NaN, +0, -0, +∞, or -∞, return +0.
  3. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)).
  4. Let int16bit be int modulo 216.
  5. Return int16bit.
注意

关于ToUint16的上述定义:

  • 在步骤4中用2 16 代替 2 32 ToUint32 和 ToUint16 的区别.
  • ToUint16 映射 -0+0.

7.1.9ToInt8 ( argument )#

抽象操作ToInt8将argument转换为28个整数之一,范围为-128 through 127。 该抽象操作的功能如下:

  1. Let number be ? ToNumber(argument).
  2. If number is NaN, +0, -0, +∞, or -∞, return +0.
  3. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)).
  4. Let int8bit be int modulo 28.
  5. If int8bit ≥ 27, return int8bit - 28; otherwise return int8bit.

7.1.10ToUint8 ( argument )#

抽象操作ToUint8将argument转换为2 8 个整数值之一,范围为0到255之间的。 该抽象操作的功能如下:

  1. Let number be ? ToNumber(argument).
  2. If number is NaN, +0, -0, +∞, or -∞, return +0.
  3. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)).
  4. Let int8bit be int modulo 28.
  5. Return int8bit.

7.1.11ToUint8Clamp ( argument )#

抽象操作抽象操作ToUint8Clamp将将argument转换为2 8 个整数值之一,范围为0到255之间的。 该抽象操作的功能如下:

  1. Let number be ? ToNumber(argument).
  2. If number is NaN, return +0.
  3. If number ≤ 0, return +0.
  4. If number ≥ 255, return 255.
  5. Let f be floor(number).
  6. If f + 0.5 < number, return f + 1.
  7. If number < f + 0.5, return f.
  8. If f is odd, return f + 1.
  9. Return f.
注意

与其他ECMAScript整数转换抽象操作不同,ToUint8Clamp循环而不是截断非整数值,并且不将 +∞转换为0. ToUint8Clamp的“一半到偶数”打破。 这与 Math.round 不同之处在于它是“一半上来”打破.

7.1.12ToString ( argument )#

抽象操作ToString将argument转换为String类型的值,根据 Table 12:

Table 12: ToString Conversions
Argument Type Result
Undefined Return "undefined".
Null Return "null".
Boolean

If argument is true, return "true".

If argument is false, return "false".

Number 参考 7.1.12.1.
String Return argument.
Symbol Throw a TypeError exception.
Object

应用以下步骤:

  1. Let primValue be ? ToPrimitive(argument, hint String).
  2. Return ? ToString(primValue).

7.1.12.1ToString应用于数字类型(ToString Applied to the Number Type)#

ToString将数字 m 转换为字符串格式步骤如下:

  1. If mis NaN, return the String "NaN".
  2. If mis +0or -0, return the String "0".
  3. If mis less than zero, return the String concatenation of the String "-"and ToString(- m).
  4. If mis +∞, return the String "Infinity".
  5. Otherwise, let n, k, and sbe integers such that k≥ 1, 10 k-1s< 10 k, the Number value for s× 10 n- kis m, and kis as small as possible. Note that kis the number of digits in the decimal representation of s, that sis not divisible by 10, and that the least significant digit of sis not necessarily uniquely determined by these criteria.
  6. If kn≤ 21, return the String consisting of the code units of the kdigits of the decimal representation of s(in order, with no leading zeroes), followed by n- koccurrences of the code unit 0x0030 (DIGIT ZERO).
  7. If 0 < n≤ 21, return the String consisting of the code units of the most significant ndigits of the decimal representation of s, followed by the code unit 0x002E (FULL STOP), followed by the code units of the remaining k- ndigits of the decimal representation of s.
  8. If -6 < n≤ 0, return the String consisting of the code unit 0x0030 (DIGIT ZERO), followed by the code unit 0x002E (FULL STOP), followed by - noccurrences of the code unit 0x0030 (DIGIT ZERO), followed by the code units of the kdigits of the decimal representation of s.
  9. Otherwise, if k= 1, return the String consisting of the code unit of the single digit of s, followed by code unit 0x0065 (LATIN SMALL LETTER E), followed by the code unit 0x002B (PLUS SIGN) or the code unit 0x002D (HYPHEN-MINUS) according to whether n-1 is positive or negative, followed by the code units of the decimal representation of the integer abs( n-1) (with no leading zeroes).
  10. Return the String consisting of the code units of the most significant digit of the decimal representation of s, followed by code unit 0x002E (FULL STOP), followed by the code units of the remaining k-1 digits of the decimal representation of s, followed by code unit 0x0065 (LATIN SMALL LETTER E), followed by code unit 0x002B (PLUS SIGN) or the code unit 0x002D (HYPHEN-MINUS) according to whether n-1 is positive or negative, followed by the code units of the decimal representation of the integer abs( n-1) (with no leading zeroes).
注意 1

以下观察结果可能作为实施指南,但不属于本标准规范性要求的一部分:

  • 如果x是除 -0 之外的任何数字值,则ToNumber(ToString(x))与x的数值完全相同.
  • s的最低有效数字并不总是由步骤5中列出的要求唯一确定。
注意 2

对于提供比上述规则更准确的转换的实现,建议将以下替代版本的步骤5用作指导:

  1. 否则,让 n k s 是整数,使得 k ≥1,10 var> k -1 s &lt; 10 k s的数值×10 n - k m k 尽可能小。 如果 s 有多种可能,请选择 s 的值 x 10 n - k 的值最接近 m 。 如果有 s 的两个这样的值,请选择一个是均匀的。 请注意, k s 的十进制表示中的位数,并且 s 不能被10整除。
注意 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). November 30, 1990. Available as
http://ampl.com/REFS/abstracts.html#rounding. Associated code available as
http://netlib.sandia.gov/fp/dtoa.c and as
http://netlib.sandia.gov/fp/g_fmt.c and may also be found at the various netlib mirror sites.

7.1.13ToObject ( argument )#

抽象操作ToObject将argument转换为Object类型的值 根据Table 13:

Table 13: ToObject Conversions
Argument Type Result
Undefined Throw a TypeError exception.
Null Throw a TypeError exception.
Boolean Return a new Boolean object whose [[BooleanData]] internal slot is set to the value of argument. See 19.3 for a description of Boolean objects.
Number Return a new Number object whose [[NumberData]] internal slot is set to the value of argument. See 20.1 for a description of Number objects.
String Return a new String object whose [[StringData]] internal slot is set to the value of argument. See 21.1 for a description of String objects.
Symbol Return a new Symbol object whose [[SymbolData]] internal slot is set to the value of argument. See 19.4 for a description of Symbol objects.
Object Return argument.

7.1.14ToPropertyKey ( argument )#

抽象操作ToPropertyKey将argument转换为可以用作属性键的值,方法是执行以下步骤:

  1. Let key be ? ToPrimitive(argument, hint String).
  2. If Type(key) is Symbol, then
    1. Return key.
  3. Return ! ToString(key).

7.1.15ToLength ( argument )#

抽象操作ToLength将argument转换为适合用作类数组对象长度的整数。 它执行以下步骤:

  1. Let len be ? ToInteger(argument).
  2. If len+0, return +0.
  3. If len is +∞, return 253-1.
  4. Return min(len, 253-1).

7.1.16CanonicalNumericIndexString ( argument )#

抽象操作CanonicalNumericIndexString将argument转换为数值,如果它是由ToString生成或字符串"-0"。 否则,它返回it returns undefined。 该抽象操作的功能如下:

  1. Assert: Type(argument) is String.
  2. If argument is "-0", return -0.
  3. Let n be ToNumber(argument).
  4. If SameValue(! ToString(n), argument) is false, return undefined.
  5. Return n.

规范数字字符串(canonical numeric string)是CanonicalNumericIndexString抽象操作任何字符串值,除了返回的 undefined .

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

7.2.1RequireObjectCoercible ( argument )#

argument是不能使用ToObject的值,那么抽象操作RequireObjectCoercible会引发错误. Table 14定义:

Table 14: RequireObjectCoercible Results
Argument Type Result
Undefined Throw a TypeError exception.
Null Throw a TypeError exception.
Boolean Return argument.
Number Return argument.
String Return argument.
Symbol Return argument.
Object Return argument.

7.2.2IsArray ( argument )#

抽象操作IsArray需要一个参数argument,并执行以下步骤:

  1. If Type(argument) is not Object, return false.
  2. If argument is an Array exotic object, return true.
  3. If argument is a Proxy exotic object, then
    1. If the value of the [[ProxyHandler]] internal slot of argument is null, throw a TypeError exception.
    2. Let target be the value of the [[ProxyTarget]] internal slot of argument.
    3. Return ? IsArray(target).
  4. Return false.

7.2.3IsCallable ( argument )#

抽象操作IsCallable决定能否用argument调用,必须是ECMAScript language value(ECMAScript language value),是具有[[Call]]内部方法的可调用函数.

  1. If Type(argument) is not Object, return false.
  2. If argument has a [[Call]] internal method, return true.
  3. Return false.

7.2.4IsConstructor ( argument )#

抽象操作IsConstructor确定是否argument可调用,它必须是 ECMAScript语言值(ECMAScript language value)是具有[[Construct]]内部方法的函数对象.

  1. If Type(argument) is not Object, return false.
  2. If argument has a [[Construct]] internal method, return true.
  3. Return false.

7.2.5IsExtensible (O)#

抽象操作IsExtensible用于确定是否可以向 O 的对象添加附加属性。 返回一个布尔值。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Return ? O.[[IsExtensible]]().

7.2.6IsInteger ( argument )#

抽象操作IsInteger确定argument是否是有限整数数值.

  1. If Type(argument) is not Number, return false.
  2. If argument is NaN, +∞, or -∞, return false.
  3. If floor(abs(argument)) ≠ abs(argument), return false.
  4. Return true.

7.2.7IsPropertyKey ( argument )#

抽象操作IsPropertyKey确定是否argument,它必须是 ECMAScript语言值(ECMAScript language value),是可以用作属性键的值.

  1. If Type(argument) is String, return true.
  2. If Type(argument) is Symbol, return true.
  3. Return false.

7.2.8IsRegExp ( argument )#

带参数argument的抽象操作IsRegExp执行以下步骤:

  1. If Type(argument) is not Object, return false.
  2. Let isRegExp be ? Get(argument, @@match).
  3. If isRegExp is not undefined, return ToBoolean(isRegExp).
  4. If argument has a [[RegExpMatcher]] internal slot, return true.
  5. Return false.

7.2.9SameValue (x, y)#

内部比较抽象操作SameValue( x y ),其中 x y 是ECMAScript语言值, 结果为 true false 。 这样的比较如下进行:

  1. If Type(x) is different from Type(y), return false.
  2. If Type(x) is Number, then
    1. If x is NaN and y is NaN, return true.
    2. If x is +0 and y is -0, return false.
    3. If x is -0 and y is +0, return false.
    4. If x is the same Number value as y, return true.
    5. Return false.
  3. Return SameValueNonNumber(x, y).
注意

该算法不同于严格平等比较(Strict Equality Comparison) 其处理中的算法 签名zeroes and NaNs.

7.2.10SameValueZero (x, y)#

内部比较抽象操作SameValueZero( x y ),其中 x y 是ECMAScript语言值, 结果为 true false 。 这样的比较如下进行:

  1. If Type(x) is different from Type(y), return false.
  2. If Type(x) is Number, then
    1. If x is NaN and y is NaN, return true.
    2. If x is +0 and y is -0, return true.
    3. If x is -0 and y is +0, return true.
    4. If x is the same Number value as y, return true.
    5. Return false.
  3. Return SameValueNonNumber(x, y).
注意

SameValueZero 和 SameValue 的不同点:对待 +0-0.

7.2.11SameValueNonNumber (x, y)#

内部比较抽象操作SameValueNonNumber(x, y),其中 x y 都不是Number值, 结果为 true false 。 这样的比较如下进行:

  1. Assert: Type(x) is not Number.
  2. Assert: Type(x) is the same as Type(y).
  3. If Type(x) is Undefined, return true.
  4. If Type(x) is Null, return true.
  5. If Type(x) is String, then
    1. If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false.
  6. If Type(x) is Boolean, then
    1. If x and y are both true or both false, return true; otherwise, return false.
  7. If Type(x) is Symbol, then
    1. If x and y are both the same Symbol value, return true; otherwise, return false.
  8. Return true if x and y are the same Object value. Otherwise, return false.

7.2.12Abstract Relational Comparison#

比较 x &lt; y ,其中 x y 是值,生成 true false undefined (表示至少有一个操作数是 NaN )。除了 x y ,算法将一个名为 LeftFirst 的布尔标志作为参数。该标志用于控制在 x y 上执行具有潜在可见副作用的操作的顺序。这是必要的,因为ECMAScript指定从左到右的表达式的执行。 LeftFirst 的默认值为 true ,表示 x 参数对应于 y 参数的相应表达式。如果 LeftFirst false ,则反之亦然,必须在 y 之前执行操作,然后再在 x 。这样的比较如下进行:

  1. If the LeftFirst flag is true, then
    1. Let px be ? ToPrimitive(x, hint Number).
    2. Let py be ? ToPrimitive(y, hint Number).
  2. Else the order of evaluation needs to be reversed to preserve left to right evaluation
    1. Let py be ? ToPrimitive(y, hint Number).
    2. Let px be ? ToPrimitive(x, hint Number).
  3. If both px and py are Strings, then
    1. If py is a prefix of px, return false. (A String value p is a prefix of String value q if q can be the result of concatenating p and some other String r. Note that any String is a prefix of itself, because r may be the empty String.)
    2. If px is a prefix of py, return true.
    3. Let k be the smallest nonnegative integer such that the code unit at index k within px is different from the code unit at index k within py. (There must be such a k, for neither String is a prefix of the other.)
    4. Let m be the integer that is the code unit value at index k within px.
    5. Let n be the integer that is the code unit value at index k within py.
    6. If m < n, return true. Otherwise, return false.
  4. Else,
    1. Let nx be ? ToNumber(px). Because px and py are primitive values evaluation order is not important.
    2. Let ny be ? ToNumber(py).
    3. If nx is NaN, return undefined.
    4. If ny is NaN, return undefined.
    5. If nx and ny are the same Number value, return false.
    6. If nx is +0 and ny is -0, return false.
    7. If nx is -0 and ny is +0, return false.
    8. If nx is +∞, return false.
    9. If ny is +∞, return true.
    10. If ny is -∞, return false.
    11. If nx is -∞, return true.
    12. If the mathematical value of nx is less than the mathematical value of ny —note that these mathematical values are both finite and not both zero—return true. Otherwise, return false.
注意 1

步骤3与步骤7不同:在加法运算符的算法中 + (12.8.3)在使用“and”而不是“or”.

注意 2

字符串的比较在代码单元值序列上使用简单的词典排序。 没有尝试使用在Unicode规范中定义的更复杂,语义上定义的字符或字符串相等和整理顺序。 因此,根据Unicode标准在规范上相等的字符串值可以测试为不相等。 实际上,该算法假定两个字符串已经处于标准化形式。 另外请注意,对于包含补充字符的字符串,UTF-16码单元值序列的字典排序与代码点值序列不同.

7.2.13Abstract Equality Comparison#

比较 x == y ,其中 x y 是值,产生 true false 。 这样的比较如下进行:

  1. If Type(x) is the same as Type(y), then
    1. Return the result of performing Strict Equality Comparison x === y.
  2. If x is null and y is undefined, return true.
  3. If x is undefined and y is null, return true.
  4. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
  5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
  6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
  7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
  8. If Type(x) is either String, Number, or Symbol and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
  9. If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison ToPrimitive(x) == y.
  10. Return false.

7.2.14Strict Equality Comparison#

比较x === y,其中 x y 是值,生成 true false 。 这样的比较如下进行:

  1. If Type(x) is different from Type(y), return false.
  2. If Type(x) is Number, then
    1. If x is NaN, return false.
    2. If y is NaN, return false.
    3. If x is the same Number value as y, return true.
    4. If x is +0 and y is -0, return true.
    5. If x is -0 and y is +0, return true.
    6. Return false.
  3. Return SameValueNonNumber(x, y).
注意

该算法与其处理有符号零和NaN的 SameValue 不同。

7.3Operations on Objects#

7.3.1Get (O, P)#

抽象操作Get用于检索对象的特定属性的值。 使用参数 O P 调用该操作,其中 O 是对象, P 是属性键。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Assert: IsPropertyKey(P) is true.
  3. Return ? O.[[Get]](P, O).

7.3.2GetV (V, P)#

抽象操作GetV用于检索 ECMAScript语言的特定属性的值。 如果值不是对象,则使用适合该值类型的包装器对象来执行属性查找。 使用参数 V P 调用该操作,其中 V 是值, P 是属性键。 此抽象操作执行以下步骤:

  1. Assert: IsPropertyKey(P) is true.
  2. Let O be ? ToObject(V).
  3. Return ? O.[[Get]](P, V).

7.3.3Set (O, P, V, Throw)#

抽象操作集合用于设置对象的特定属性的值。 使用参数 O P V Throw 调用该操作,其中 O 是对象, P 是属性键, V 是属性的新值, Throw 是一个布尔标志。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Assert: IsPropertyKey(P) is true.
  3. Assert: Type(Throw) is Boolean.
  4. Let success be ? O.[[Set]](P, V, O).
  5. If success is false and Throw is true, throw a TypeError exception.
  6. Return success.

7.3.4CreateDataProperty (O, P, V)#

抽象操作CreateDataProperty用于创建对象的新的属性。 使用参数 O P V 调用该操作,其中 O 是对象, P 是属性键, V 是属性的值。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Assert: IsPropertyKey(P) is true.
  3. Let newDesc be the PropertyDescriptor{[[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}.
  4. Return ? O.[[DefineOwnProperty]](P, newDesc).
注意

此抽象操作创建一个属性,其属性设置为与由ECMAScript语言赋值运算符创建的属性相同的默认值。 通常,该属性将不会存在。 如果它存在并且不可配置,或者如果 O 不可扩展(extensible),[[DefineOwnProperty]]将返回 false .

7.3.5CreateMethodProperty (O, P, V)#

抽象操作CreateMethodProperty用于创建对象的新属性。 使用参数 O P V 调用该操作,其中 O 是对象, P 是属性键, V 是属性的值。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Assert: IsPropertyKey(P) is true.
  3. Let newDesc be the PropertyDescriptor{[[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}.
  4. Return ? O.[[DefineOwnProperty]](P, newDesc).
注意

此抽象操作创建一个属性,其属性设置为与使用类声明语法定义的内置方法和方法相同的默认值。 通常,该属性将不会存在。 如果它存在并且不可配置(configurable),或者如果 O 不可扩展(extensible),[[DefineOwnProperty]]将返回 false .

7.3.6CreateDataPropertyOrThrow (O, P, V)#

抽象操作CreateDataPropertyOrThrow用于创建对象的新的自己的属性。 如果无法执行请求的属性更新,它将抛出一个 TypeError 异常。 使用参数 O P V 调用该操作,其中 O 是对象, P 是属性键, V 是属性的值。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Assert: IsPropertyKey(P) is true.
  3. Let success be ? CreateDataProperty(O, P, V).
  4. If success is false, throw a TypeError exception.
  5. Return success.
注意

此抽象操作创建一个属性,其属性设置为与由ECMAScript语言赋值运算符创建的属性相同的默认值。 通常,该属性将不会存在。 如果它存在并且不可配置,或者如果 O 不可扩展,[[DefineOwnProperty]]将返回 false ,导致此操作抛出 TypeError 异常.

7.3.7DefinePropertyOrThrow (O, P, desc)#

抽象操作DefinePropertyOrThrow用于调用对象的[[DefineOwnProperty]]内部方法,方法是在不能执行请求的属性更新时引发 TypeError 异常。 使用参数 O P desc 调用操作,其中 O 是对象, P 是属性键, desc 属性描述符(Property Descriptor) 。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Assert: IsPropertyKey(P) is true.
  3. Let success be ? O.[[DefineOwnProperty]](P, desc).
  4. If success is false, throw a TypeError exception.
  5. Return success.

7.3.8DeletePropertyOrThrow (O, P)#

抽象操作DeletePropertyOrThrow用于删除对象的特定自己的属性。 如果属性不可配置,它将抛出异常。 使用参数 O P 调用该操作,其中 O 是对象, P 是属性键。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Assert: IsPropertyKey(P) is true.
  3. Let success be ? O.[[Delete]](P).
  4. If success is false, throw a TypeError exception.
  5. Return success.

7.3.9GetMethod (V, P)#

抽象操作GetMethod用于获取 ECMAScript语言的特定属性的值 值,当属性的值预计是一个函数。 使用参数 V P 调用该操作,其中 V ECMAScript语言值 P 是属性键。 此抽象操作执行以下步骤:

  1. Assert: IsPropertyKey(P) is true.
  2. Let func be ? GetV(V, P).
  3. If func is either undefined or null, return undefined.
  4. If IsCallable(func) is false, throw a TypeError exception.
  5. Return func.

7.3.10HasProperty (O, P)#

抽象操作HasProperty用于确定对象是否具有指定属性键的属性。 该熟悉可能是自己的或继承的。 返回一个布尔值。 使用参数 O P 调用该操作,其中 O 是对象, P 是属性键。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Assert: IsPropertyKey(P) is true.
  3. Return ? O.[[HasProperty]](P).

7.3.11HasOwnProperty (O, P)#

抽象操作HasOwnProperty用于确定对象是否具有指定属性键的自己的属性。 返回一个布尔值。 使用参数 O P 调用该操作,其中 O 是对象, P 是属性键。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Assert: IsPropertyKey(P) is true.
  3. Let desc be ? O.[[GetOwnProperty]](P).
  4. If desc is undefined, return false.
  5. Return true.

7.3.12Call (F, V [ , argumentsList ])#

抽象操作Call用于调用函数对象的[[Call]]内部方法。 使用参数 F V 和可选的 argumentsList 调用该操作,其中 F 是函数对象, V 是一个emu-xref href="#sec-ecmascript-language-types"> ECMAScript语言值 这是[[Call]]的this值,而 argumentsList 是传递给内部方法的相应参数的值。 如果 argumentsList 不存在,则新的空List用作其值。 此抽象操作执行以下步骤:

  1. If argumentsList was not passed, let argumentsList be a new empty List.
  2. If IsCallable(F) is false, throw a TypeError exception.
  3. Return ? F.[[Call]](V, argumentsList).

7.3.13Construct (F [ , argumentsList [ , newTarget ]])#

抽象操作Construct用于调用函数对象的[[Construct]]内部方法。 使用参数 F 和可选的 argumentsList newTarget 调用该操作,其中 F 是函数对象。 argumentsList newTarget 是要作为内部方法的相应参数传递的值。 如果 argumentsList 不存在,则新的空List用作其值。 如果 newTarget 不存在,则使用 F 作为其值。 此抽象操作执行以下步骤:

  1. If newTarget was not passed, let newTarget be F.
  2. If argumentsList was not passed, let argumentsList be a new empty List.
  3. Assert: IsConstructor(F) is true.
  4. Assert: IsConstructor(newTarget) is true.
  5. Return ? F.[[Construct]](argumentsList, newTarget).
Note

If newTarget is not passed, this operation is equivalent to: new F(...argumentsList)

7.3.14SetIntegrityLevel (O, level)#

抽象操作SetIntegrityLevel用于修复对象的属性集。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Assert: level is either "sealed" or "frozen".
  3. Let status be ? O.[[PreventExtensions]]().
  4. If status is false, return false.
  5. Let keys be ? O.[[OwnPropertyKeys]]().
  6. If level is "sealed", then
    1. Repeat for each element k of keys,
      1. Perform ? DefinePropertyOrThrow(O, k, PropertyDescriptor{[[Configurable]]: false}).
  7. Else level is "frozen",
    1. Repeat for each element k of keys,
      1. Let currentDesc be ? O.[[GetOwnProperty]](k).
      2. If currentDesc is not undefined, then
        1. If IsAccessorDescriptor(currentDesc) is true, then
          1. Let desc be the PropertyDescriptor{[[Configurable]]: false}.
        2. Else,
          1. Let desc be the PropertyDescriptor { [[Configurable]]: false, [[Writable]]: false }.
        3. Perform ? DefinePropertyOrThrow(O, k, desc).
  8. Return true.

7.3.15TestIntegrityLevel (O, level)#

抽象操作TestIntegrityLevel用于确定对象的属性的集合是否固定。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Assert: level is either "sealed" or "frozen".
  3. Let status be ? IsExtensible(O).
  4. If status is true, return false.
  5. NOTE If the object is extensible, none of its properties are examined.
  6. Let keys be ? O.[[OwnPropertyKeys]]().
  7. Repeat for each element k of keys,
    1. Let currentDesc be ? O.[[GetOwnProperty]](k).
    2. If currentDesc is not undefined, then
      1. If currentDesc.[[Configurable]] is true, return false.
      2. If level is "frozen" and IsDataDescriptor(currentDesc) is true, then
        1. If currentDesc.[[Writable]] is true, return false.
  8. Return true.

7.3.16CreateArrayFromList (elements)#

T抽象操作CreateArrayFromList用于创建一个Array对象,其元素由List提供。 此抽象操作执行以下步骤:

  1. Assert: elements is a List whose elements are all ECMAScript language values.
  2. Let array be ArrayCreate(0).
  3. Let n be 0.
  4. For each element e of elements
    1. Let status be CreateDataProperty(array, ! ToString(n), e).
    2. Assert: status is true.
    3. Increment n by 1.
  5. Return array.

7.3.17CreateListFromArrayLike (obj [ , elementTypes ] )#

抽象操作CreateListFromArrayLike用于创建一个List,其元素由类数组对象的索引属性 obj 提供的值。 可选参数 elementTypes 是一个List,其中包含ECMAScript语言类型的名称,该类型允许使用List的值。 此抽象操作执行以下步骤:

  1. If elementTypes was not passed, let elementTypes be « Undefined, Null, Boolean, String, Symbol, Number, Object ».
  2. If Type(obj) is not Object, throw a TypeError exception.
  3. Let len be ? ToLength(? Get(obj, "length")).
  4. Let list be a new empty List.
  5. Let index be 0.
  6. Repeat while index < len
    1. Let indexName be ! ToString(index).
    2. Let next be ? Get(obj, indexName).
    3. If Type(next) is not an element of elementTypes, throw a TypeError exception.
    4. Append next as the last element of list.
    5. Set index to index + 1.
  7. Return list.

7.3.18Invoke (V, P [ , argumentsList ])#

抽象操作Invoke用于调用 ECMAScript语言值(ECMAScript language value)。 使用参数 V P 和可选的 argumentsList 调用该操作,其中 V 用作查找属性和提供调用的this值, P 是属性键, argumentsList 是传递的参数值的列表 的方法。 如果 argumentsList 不存在,则新的空List用作其值。 此抽象操作执行以下步骤:

  1. Assert: IsPropertyKey(P) is true.
  2. If argumentsList was not passed, let argumentsList be a new empty List.
  3. Let func be ? GetV(V, P).
  4. Return ? Call(func, V, argumentsList).

7.3.19OrdinaryHasInstance (C, O)#

抽象操作OrdinaryHasInstance实现了用于确定对象 O 是否从构造函数 C 提供的实例对象继承路径继承的默认算法。 此抽象操作执行以下步骤:

  1. If IsCallable(C) is false, return false.
  2. If C has a [[BoundTargetFunction]] internal slot, then
    1. Let BC be the value of C's [[BoundTargetFunction]] internal slot.
    2. Return ? InstanceofOperator(O, BC).
  3. If Type(O) is not Object, return false.
  4. Let P be ? Get(C, "prototype").
  5. If Type(P) is not Object, throw a TypeError exception.
  6. Repeat
    1. Let O be ? O.[[GetPrototypeOf]]().
    2. If O is null, return false.
    3. If SameValue(P, O) is true, return true.

7.3.20SpeciesConstructor ( O, defaultConstructor )#

抽象操作SpeciesConstructor用于检索应用于创建从参数对象 O 派生的新对象的构造函数。 如果从 O 开始不能找到构造函数@@ species属性,则 defaultConstructor 参数是使用的构造函数。 此抽象操作执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Let C be ? Get(O, "constructor").
  3. If C is undefined, return defaultConstructor.
  4. If Type(C) is not Object, throw a TypeError exception.
  5. Let S be ? Get(C, @@species).
  6. If S is either undefined or null, return defaultConstructor.
  7. If IsConstructor(S) is true, return S.
  8. Throw a TypeError exception.

7.3.21EnumerableOwnNames (O)#

当使用Object O 调用抽象操作EnumerableOwnNames时,执行以下步骤:

  1. Assert: Type(O) is Object.
  2. Let ownKeys be ? O.[[OwnPropertyKeys]]().
  3. Let names be a new empty List.
  4. Repeat, for each element key of ownKeys in List order
    1. If Type(key) is String, then
      1. Let desc be ? O.[[GetOwnProperty]](key).
      2. If desc is not undefined, then
        1. If desc.[[Enumerable]] is true, append key to names.
  5. Order the elements of names so they are in the same relative order as would be produced by the Iterator that would be returned if the EnumerateObjectProperties internal method was invoked with O.
  6. Return names.

7.3.22GetFunctionRealm ( obj )#

使用参数 obj 的抽象操作GetFunctionRealm执行以下步骤:

  1. Assert: obj is a callable object.
  2. If obj has a [[Realm]] internal slot, then
    1. Return obj's [[Realm]] internal slot.
  3. If obj is a Bound Function exotic object, then
    1. Let target be obj's [[BoundTargetFunction]] internal slot.
    2. Return ? GetFunctionRealm(target).
  4. If obj is a Proxy exotic object, then
    1. If the value of the [[ProxyHandler]] internal slot of obj is null, throw a TypeError exception.
    2. Let proxyTarget be the value of obj's [[ProxyTarget]] internal slot.
    3. Return ? GetFunctionRealm(proxyTarget).
  5. Return the current Realm Record.
注意

仅当 target 是不具有[[Realm]]内部插槽的非标准异常函数对象时,步骤5才会到达.

7.4Operations on Iterator Objects#

请参阅常见迭代接口 (25.1).

7.4.1GetIterator ( obj [ , method ] )#

参数 obj 和可选参数method的抽象操作GetIterator执行以下步骤:

  1. If method was not passed, then
    1. Let method be ? GetMethod(obj, @@iterator).
  2. Let iterator be ? Call(method, obj).
  3. If Type(iterator) is not Object, throw a TypeError exception.
  4. Return iterator.

7.4.2IteratorNext ( iterator [ , value ] )#

参数 iterator 和可选参数value的抽象操作IteratorNext执行以下步骤:

  1. If value was not passed, then
    1. Let result be ? Invoke(iterator, "next", « »).
  2. Else,
    1. Let result be ? Invoke(iterator, "next", « value »).
  3. If Type(result) is not Object, throw a TypeError exception.
  4. Return result.

7.4.3IteratorComplete ( iterResult )#

参数 iterResult 的抽象操作IteratorComplete执行以下步骤

  1. Assert: Type(iterResult) is Object.
  2. Return ToBoolean(? Get(iterResult, "done")).

7.4.4IteratorValue ( iterResult )#

参数 iterResult 的抽象操作IteratorValue执行以下步骤:

  1. Assert: Type(iterResult) is Object.
  2. Return ? Get(iterResult, "value").

7.4.5IteratorStep ( iterator )#

参数 iterator 的抽象操作IteratorStep请求 iterator 中的下一个值,如果下一个值可用,返回指示迭代器已到达结束的 false 或IteratorResult对象。 IteratorStep执行以下步骤:

  1. Let result be ? IteratorNext(iterator).
  2. Let done be ? IteratorComplete(result).
  3. If done is true, return false.
  4. Return result.

7.4.6IteratorClose ( iterator, completion )#

使用参数 iterator completion 的抽象操作IteratorClose用于通知迭代器,它应该执行在达到其完成状态时通常执行的任何操作:

  1. Assert: Type(iterator) is Object.
  2. Assert: completion is a Completion Record.
  3. Let return be ? GetMethod(iterator, "return").
  4. If return is undefined, return Completion(completion).
  5. Let innerResult be Call(return, iterator, « »).
  6. If completion.[[Type]] is throw, return Completion(completion).
  7. If innerResult.[[Type]] is throw, return Completion(innerResult).
  8. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
  9. Return Completion(completion).

7.4.7CreateIterResultObject ( value, done )#

带有参数 value done 的抽象操作CreateIterResultObject通过执行以下步骤创建一个支持IteratorResult接口的对象:

  1. Assert: Type(done) is Boolean.
  2. Let obj be ObjectCreate(%ObjectPrototype%).
  3. Perform CreateDataProperty(obj, "value", value).
  4. Perform CreateDataProperty(obj, "done", done).
  5. Return obj.

7.4.8CreateListIterator ( list )#

使用参数 list 的抽象操作CreateListIterator创建一个Iterator(25.1.1.2)对象,其下一个方法返回 list 的连续元素。 它执行以下步骤:

  1. Let iterator be ObjectCreate(%IteratorPrototype%, « [[IteratorNext]], [[IteratedList]], [[ListIteratorNextIndex]] »).
  2. Set iterator's [[IteratedList]] internal slot to list.
  3. Set iterator's [[ListIteratorNextIndex]] internal slot to 0.
  4. Let next be a new built-in function object as defined in ListIterator next (7.4.8.1).
  5. Set iterator's [[IteratorNext]] internal slot to next.
  6. Perform CreateMethodProperty(iterator, "next", next).
  7. Return iterator.

7.4.8.1ListIterator next( )#

ListIterator next 方法是标准的内置函数对象(条文17),执行以下步骤:

  1. Let O be the this value.
  2. Let f be the active function object.
  3. If O does not have a [[IteratorNext]] internal slot, throw a TypeError exception.
  4. Let next be the value of the [[IteratorNext]] internal slot of O.
  5. If SameValue(f, next) is false, throw a TypeError exception.
  6. If O does not have an [[IteratedList]] internal slot, throw a TypeError exception.
  7. Let list be the value of the [[IteratedList]] internal slot of O.
  8. Let index be the value of the [[ListIteratorNextIndex]] internal slot of O.
  9. Let len be the number of elements of list.
  10. If indexlen, then
    1. Return CreateIterResultObject(undefined, true).
  11. Set the value of the [[ListIteratorNextIndex]] internal slot of O to index+1.
  12. Return CreateIterResultObject(list[index], false).
注意

如果应用于除了最初关联的任何对象之外的任何对象,ListIterator next 方法将抛出异常.

8可执行代码和执行上下文(Executable Code and Execution Contexts)#

8.1词法环境(Lexical Environments)#

词法环境是一种规范类型,用于定义标识符(Identifier)与特定的关联,基于ECMAScript代码的词法嵌套结构的变量和函数。 词法环境由环境记录(Environment Record)和可能为null引用外部词法环境。 通常,词法环境与ECMAScript代码的某些特定语法结构相关联,例如FunctionDeclarationBlockStatement,或Catch跟随 TryStatement的语句,每次执行此代码时都会创建一个新的词法环境.

环境记录(Environment Record)记录在其相关词法环境范围内创建的标识符绑定。 它被称为词法环境的 EnvironmentRecord

外部环境引用用于建模词法环境值的逻辑嵌套。 (内部)词法环境的外部引用是对逻辑上围绕内部词法环境的词法环境的引用。 外部词法环境当然可以有自己的外部词法环境。 词法环境可以作为多个内部词法环境的外部环境。 例如,如果FunctionDeclaration包含两个嵌套的FunctionDeclaration然后,每一个嵌套函数的词法环境都将作为其外部词法环境的当前执行方法.

全局环境(global environment)是一个没有外部环境的词法环境。 全局环境的外部环境引用是 null 。 全局环境的EnvironmentRecord可以用标识符绑定预先填充,并且包含一个关联的全局对象(global object),其属性提供了一些全局环境的标识符绑定。 随着执行ECMAScript代码,可以向全局对象添加其他属性,并且可能会修改初始属性.

一个模块环境(module environment)是一个词法环境,它包含一个顶级声明的绑定模块(Module)。 它还包含由模块(Module)显式导入的绑定。 模块环境的外部环境是一个全局环境(global environment).

函数环境(function environment)是与ECMAScript函数对象的调用相对应的词法环境。 一个函数环境可以建立一个新的this绑定。 函数环境还捕获支持继承(super)方法调用所必需的状态.

词法环境和环境记录值是纯粹的规范机制,需要 不符合ECMAScript实现的任何具体文件。 ECMAScript程序不可能直接访问或操纵这些值.

8.1.1环境记录(Environment Records)#

本规范中使用的两种主要的环境记录值:声明环境记录(Environment Record)对象环境记录(object Environment Records)。声明式环境记录用于定义ECMAScript语言句法元素的效果,例如 FunctionDeclaration s, VariableDeclaration s和 Catch 直接将标识符绑定与ECMAScript语言值相关联的子句。对象环境记录用于定义ECMAScript元素的影响,例如 WithStatement ,将标识符绑定与某些属性目的。全局环境记录和功能环境记录是专门用于 脚本(Script) 全局声明和function内的顶级声明.

为了规范目的,环境记录值是记录(Record)规范类型,可以被认为是存在于一个简单的面向对象层次结构中,其中Environment Record是一个具有三个具体子类的抽象类,声明性环境记录(declarative Environment Record),对象环境记录(object Environment Record)和全局环境记录(global Environment Record)。 函数环境记录和模块环境记录是声明性环境记录的子类。 抽象类包括在Table 15中定义的抽象规范方法。 这些抽象方法对于每个具体的子类都有不同的具体算法.

Table 15: 环境记录抽象方法(Abstract Methods of Environment Records)
Method Purpose
HasBinding(N) 确定环境记录是否具有String值 N 的绑定。 如果没有,请返回 true ,否则为 false
CreateMutableBinding(N, D) (创建可变绑定) 在环境记录中创建一个新的但未初始化的可变绑定。 String值 N 是绑定名称的文本。 如果布尔参数 D true ,则绑定可能随后被删除.
CreateImmutableBinding(N, S) (设置不可变绑定) 在环境记录中创建一个新的但未初始化的不可变绑定。 String值 N 是绑定名称的文本。 如果 S true ,那么尝试在初始化之前访问绑定的值,或者在初始化之后对其进行设置将始终引发异常, 无论严格模式是否设置,对于该绑定.
InitializeBinding(N, V) 在环境记录中设置已存在但未初始化的绑定的值。 String值 N 是绑定名称的文本。 V 是绑定的值,是任何 ECMAScript语言类型 .
SetMutableBinding(N, V, S) 在环境记录中设置已经存在的可变绑定的值。 String值 N 是绑定名称的文本。 V 是绑定的值,可以是任何 ECMAScript语言类型 S 是一个布尔标志。 如果 S true ,并且绑定不能设置,则抛出一个 TypeError 异常.
GetBindingValue(N, S) 从环境记录中返回已经存在的绑定的值。 String值 N 是绑定名称的文本。 S 用于标识源自严格模式代码(strict mode code) ,否则需要严格的模式引用语义。 如果 S true ,绑定不存在则引发一个 ReferenceError 异常。 如果绑定存在但未初始化,则抛出 ReferenceError ,而不管 S 的值如何.
DeleteBinding(N) 从环境记录中删除绑定。 String值 N 是绑定名称的文本。 如果存在 N 的绑定,则删除绑定并返回 true 。 如果绑定存在但不能被删除返回 false 。 如果绑定不存在返回 true .
HasThisBinding() 确定环境记录是否建立了一个this绑定。 如果没有,请返回 true ,否则为 false .
HasSuperBinding() 确定环境记录是否建立了一个super方法绑定。 如果没有,请返回 true ,否则为 false .
WithBaseObject() 如果此环境记录与with语句相关联,则返回with对象。 否则返回 undefined .

8.1.1.1声明性环境记录(Declarative Environment Records)#

每个声明式的环境记录(Environment Record)与ECMAScript程序范围相关联,其中包含 变量(variable),常量(constant),let,class,module,import 和/或 函数声明(function declarations)。 环境记录 绑定了一系列声明包含在其作用域(scope)内.

声明性环境记录的具体规范方法的行为由以下算法定义.

8.1.1.1.1HasBinding (N)#

具体的环境记录(Environment Record)方法HasBinding用于声明性环境记录的简单地确定参数标识符是否是由记录绑定的标识符之一:

  1. Let envRec be the declarative Environment Record for which the method was invoked.
  2. If envRec has a binding for the name that is the value of N, return true.
  3. Return false.

8.1.1.1.2CreateMutableBinding (N, D)#

具体的环境记录(Environment Record)方法用于声明性环境记录的CreateMutableBinding创建一个 未初始化的名称 N 的新的可变绑定。 环境记录(Environment Record)中的N必须不存在。 如果布尔参数 D 具有值 true ,则新绑定被标记为未来可被删除.

  1. Let envRec be the declarative Environment Record for which the method was invoked.
  2. Assert: envRec does not already have a binding for N.
  3. 在envRec中为N创建可变绑定,并记录它是未初始化的。 如果D为true,则记录新创建的绑定可能会被随后的删除绑定调用删除(Create a mutable binding in envRec for N and record that it is uninitialized. If D is true, record that the newly created binding may be deleted by a subsequent DeleteBinding call.)
  4. Return NormalCompletion(empty).

8.1.1.1.3CreateImmutableBinding (N, S)#

具体的环境记录Environment Record方法CreateImmutableBinding用于声明性环境记录创建一个 未初始化的名称 N 的新的不可变绑定。 环境记录中必须不存在N。 如果布尔参数 S 具有值 true ,则新绑定被标记为严格绑定.

  1. Let envRec be the declarative Environment Record for which the method was invoked.
  2. Assert: envRec does not already have a binding for N.
  3. Create an immutable binding in envRec for N and record that it is uninitialized. If S is true, record that the newly created binding is a strict binding.
  4. Return NormalCompletion(empty).

8.1.1.1.4InitializeBinding (N, V)#

具体的环境记录Environment Record方法使用声明性环境记录的InitializeBinding 将名称为参数 N 的值的标识符的当前绑定的绑定值设置为参数 V 的值。 N 的未初始化绑定必须已经存在.

  1. Let envRec be the declarative Environment Record for which the method was invoked.
  2. Assert: envRec must have an uninitialized binding for N.
  3. Set the bound value for N in envRec to V.
  4. Record that the binding for N in envRec has been initialized.
  5. Return NormalCompletion(empty).

8.1.1.1.5SetMutableBinding (N, V, S)#

具体的环境记录Environment RecordSetMutableBinding方法用于声明性环境记录的尝试将名称为参数 N 的值的标识符的当前绑定的绑定值更改为参数 V 的值。 通常已经存在 N 的绑定,但在极少数情况下可能不存在。 如果绑定是不可变绑定,则如果 S true ,则抛出 TypeError .

  1. Let envRec be the declarative Environment Record for which the method was invoked.
  2. If envRec does not have a binding for N, then
    1. If S is true, throw a ReferenceError exception.
    2. Perform envRec.CreateMutableBinding(N, true).
    3. Perform envRec.InitializeBinding(N, V).
    4. Return NormalCompletion(empty).
  3. If the binding for N in envRec is a strict binding, let S be true.
  4. If the binding for N in envRec has not yet been initialized, throw a ReferenceError exception.
  5. Else if the binding for N in envRec is a mutable binding, change its bound value to V.
  6. Else this must be an attempt to change the value of an immutable binding so if S is true, throw a TypeError exception.
  7. Return NormalCompletion(empty).
注意

导致步骤2中缺少绑定的ECMAScript代码的示例是:

function f(){eval("var x; x = (delete x, 0);")}

8.1.1.1.6GetBindingValue (N, S)#

具体的环境记录Environment Record方法用于声明性环境记录的GetBindingValue方法只返回 其绑定标识符的值为参数 N 的值。 如果绑定存在但未初始化,则抛出 ReferenceError ,而不管 S 的值如何.

  1. Let envRec be the declarative Environment Record for which the method was invoked.
  2. Assert: envRec has a binding for N.
  3. If the binding for N in envRec is an uninitialized binding, throw a ReferenceError exception.
  4. Return the value currently bound to N in envRec.

8.1.1.1.7DeleteBinding (N)#

具体的环境记录Environment Record方法用于声明性环境记录的DeleteBinding只能 删除已被明确指定为要删除的绑定.

  1. Let envRec be the declarative Environment Record for which the method was invoked.
  2. Assert: envRec has a binding for the name that is the value of N.
  3. If the binding for N in envRec cannot be deleted, return false.
  4. Remove the binding for N from envRec.
  5. Return true.

8.1.1.1.8HasThisBinding ()#

常规声明性环境记录不提供this绑定.

  1. Return false.

8.1.1.1.9HasSuperBinding ()#

常规声明性环境记录不提供super绑定.

  1. Return false.

8.1.1.1.10WithBaseObject ()#

常规声明性环境记录总是返回undefined 运行WithBaseObject时.

  1. Return undefined.

8.1.1.2对象环境记录(Object Environment Records)#

每个对象环境记录与一个被称为绑定对象(binding object)的对象联系在一起。一个对象环境记录绑定一组字符串标识符名称,直接对应于其绑定对象的属性名称。不属于IdentifierName 形式的字符串的属性键不包含在绑定标识符集合中。不管他们的[[Enumerable]]属性的设置如何,自己和继承的属性都包含在集合中。因为属性可以从对象中动态添加和删除,所以由对象绑定的标识符集环境记录(Environment Record)可能会作为添加或删除属性的任何操作的副作用而发生变化。作为这种副作用的结果而创建的任何绑定即使相应属性的Writable属性的值为 false 也被认为是可变绑定。对象环境记录中不存在不可变绑定.

对象环境记录使用with语句创建的(13.11)可以将其绑定对象作为隐式this值提供给函数调用。 该功能由与每个对象相关联的 withEnvironment 布尔值控制环境记录(Environment Record)。 默认情况下,对于任何对象, withEnvironment 的值为 false 对于对象 环境记录(Environment Record).

对象环境记录的具体规范方法的行为由以下算法定义.

8.1.1.2.1HasBinding (N)#

对象环境记录的具体的环境记录(Environment Record)方法HasBinding决定是 其关联的绑定对象具有名称为参数 N 的值的属性:

  1. Let envRec be the object Environment Record for which the method was invoked.
  2. Let bindings be the binding object for envRec.
  3. Let foundBinding be ? HasProperty(bindings, N).
  4. If foundBinding is false, return false.
  5. If the withEnvironment flag of envRec is false, return true.
  6. Let unscopables be ? Get(bindings, @@unscopables).
  7. If Type(unscopables) is Object, then
    1. Let blocked be ToBoolean(? Get(unscopables, N)).
    2. If blocked is true, return false.
  8. Return true.

8.1.1.2.2CreateMutableBinding (N, D)#

对象环境记录的具体的环境记录(Environment Record)方法CreateMutableBinding创建在一个环境记录 的关联绑定对象的一个属性名称为 是String值,并将其初始化为值 undefined 。 如果布尔参数 D 具有值 true ,则新属性的[[Configurable]]属性设置为 true ; 否则设置为 false .

  1. Let envRec be the object Environment Record for which the method was invoked.
  2. Let bindings be the binding object for envRec.
  3. If D is true, let configValue be true; otherwise let configValue be false.
  4. Return ? DefinePropertyOrThrow(bindings, N, PropertyDescriptor{[[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: configValue}).
注意

通常, envRec 将不具有 N 的绑定,但如果是,则DefinePropertyOrThrow可能会导致现有绑定被替换或隐藏,或导致一个突然完成(abrupt completion)返回.

8.1.1.2.3CreateImmutableBinding (N, S)#

在对象环境记录中,相关联具体的环境记录(Environment Record)方法CreateImmutableBinding从未在本规范中使用 .

8.1.1.2.4InitializeBinding (N, V)#

对象环境记录的环境记录/a>方法InitializeBinding,将名称为参数 N 的值的标识符的当前绑定的绑定值设置为参数 V 的值。 N 的未初始化绑定必须已经存在.

  1. Let envRec be the object Environment Record for which the method was invoked.
  2. Assert: envRec must have an uninitialized binding for N.
  3. Record that the binding for N in envRec has been initialized.
  4. Return ? envRec.SetMutableBinding(N, V, false).
注意

在本说明书中,对于对象环境记录的CreateMutableBinding的所有使用都将立即调用同名InitializeBinding方法。 因此,实现不需要显式跟踪单个对象的初始化状态环境记录绑定.

8.1.1.2.5SetMutableBinding (N, V, S)#

对象环境记录的环境记录方法SetMutableBinding用来设置环境记录的关联绑定对象的值,属性的名称是参数 N ,值是参数 V 的值。 一个名为 N 的属性通常已经存在,但如果不存在或当前不可写,则错误处理由布尔参数 S .

  1. Let envRec be the object Environment Record for which the method was invoked.
  2. Let bindings be the binding object for envRec.
  3. Return ? Set(bindings, N, V, S).

8.1.1.2.6GetBindingValue (N, S)#

对象环境记录的的环境记录方法对象的GetBindingValue环境记录返回其关联的绑定对象的属性的值为其参数标识符 N 的String值。 该属性应该已经存在,但如果没有结果取决于 S 参数的值:

  1. Let envRec be the object Environment Record for which the method was invoked.
  2. Let bindings be the binding object for envRec.
  3. Let value be ? HasProperty(bindings, N).
  4. If value is false, then
    1. If S is false, return the value undefined; otherwise throw a ReferenceError exception.
  5. Return ? Get(bindings, N).

8.1.1.2.7DeleteBinding (N)#

对象环境记录的的环境记录方法DeleteBinding只能删除与[[Configurable]]属性的值为 true 的环境对象的属性对应的绑定.

  1. Let envRec be the object Environment Record for which the method was invoked.
  2. Let bindings be the binding object for envRec.
  3. Return ? bindings.[[Delete]](N).

8.1.1.2.8HasThisBinding ()#

常规对象环境记录不提供this绑定.

  1. Return false.

8.1.1.2.9HasSuperBinding ()#

常规对象环境记录不提供super绑定.

  1. Return false.

8.1.1.2.10WithBaseObject ()#

对象环境记录返回undefined作为它们的WithBaseObject,除非它们的 withEnvironment 标志是 true .

  1. Let envRec be the object Environment Record for which the method was invoked.
  2. If the withEnvironment flag of envRec is true, return the binding object for envRec.
  3. Otherwise, return undefined.

8.1.1.3函数环境记录(Function Environment Records)#

函数环境记录是一个声明式的环境记录,用于表示函数的顶层范围, 如果该函数不是 箭头函数 ,则提供this绑定。 如果函数不是 箭头函数 函数和引用 super ,其函数环境记录 还包含用于内部函数执行 super 方法的状态。.

Table 16: Function Environment Records 的附加字段
Field Name Value Meaning
[[ThisValue]] Any 这是用于此函数调用的this值.
[[ThisBindingStatus]] "lexical" | "initialized" | "uninitialized" 如果值为"lexical",则这是 ArrowFunction ,并且没有本地this值。
[[FunctionObject]] Object 函数对象被调用导致这个Environment Record 被创建。
[[HomeObject]] Object | undefined 如果相关函数具有super属性访问,并且不是 ArrowFunction ,[[HomeObject ]]是函数绑定到一个方法的对象。 [[HomeObject]]的默认值为 undefined
[[NewTarget]] Object | undefined 如果这个Environment Record 是由[[Construct] ]内部方法创建,[[NewTarget]]是[[Construct]] newTarget 参数的值。 否则,其值为 undefined

函数环境记录支持所有声明性的Environment Record 列出的方法 在Table 15 中,除了HasThisBinding和HasSuperBinding之外,共享所有这些方法的相同规范 。 另外,环境记录功能支持Table 17中列出的方法:

Table 17: Additional Methods of Function Environment Records
Method Purpose
BindThisValue(V) 设置[[ThisValue]]并记录它已被初始化。
GetThisBinding() 返回此Environment Recordthis绑定。 如果this绑定尚未初始化,则抛出 ReferenceError
GetSuperBase() 返回在Environment Record中作为 super 属性访问绑定的基础的对象。该对象源于此Environment Record的[[ HomeObject]]字段。 值 undefined 表示super属性访问将产生运行时错误.

函数环境记录的附加具体规范方法的行为由以下算法定义:

8.1.1.3.1BindThisValue (V)#

  1. Let envRec be the function Environment Record for which the method was invoked.
  2. Assert: envRec.[[ThisBindingStatus]] is not "lexical".
  3. If envRec.[[ThisBindingStatus]] is "initialized", throw a ReferenceError exception.
  4. Set envRec.[[ThisValue]] to V.
  5. Set envRec.[[ThisBindingStatus]] to "initialized".
  6. Return V.

8.1.1.3.2HasThisBinding ()#

  1. Let envRec be the function Environment Record for which the method was invoked.
  2. If envRec.[[ThisBindingStatus]] is "lexical", return false; otherwise, return true.

8.1.1.3.3HasSuperBinding ()#

  1. Let envRec be the function Environment Record for which the method was invoked.
  2. If envRec.[[ThisBindingStatus]] is "lexical", return false.
  3. If envRec.[[HomeObject]] has the value undefined, return false; otherwise, return true.

8.1.1.3.4GetThisBinding ()#

  1. Let envRec be the function Environment Record for which the method was invoked.
  2. Assert: envRec.[[ThisBindingStatus]] is not "lexical".
  3. If envRec.[[ThisBindingStatus]] is "uninitialized", throw a ReferenceError exception.
  4. Return envRec.[[ThisValue]].

8.1.1.3.5GetSuperBase ()#

  1. Let envRec be the function Environment Record for which the method was invoked.
  2. Let home be the value of envRec.[[HomeObject]].
  3. If home has the value undefined, return undefined.
  4. Assert: Type(home) is Object.
  5. Return ? home.[[GetPrototypeOf]]().

8.1.1.4全局环境记录(Global Environment Records)#

globa Environment Record用于表示最外层的范围由所有ECMAScript Script共享的元素,这些元素在常用的领域(realm)。全局环境记录提供了内置全局变量的绑定(18),global object属性,以及所有在脚本中的顶级声明(13.2.8, 13.2.10).

全局环境记录在逻辑上是单个记录,但它被指定为封装对象环境记录和声明性环境记录的组合。 对象“环境记录”以其基础对象为关联的领域记录的全局对象。 这个全局对象是全局环境记录的GetThisBinding具体方法返回的值。 全局环境记录的对象Environment Record组件包含所有内置全局变量(第18节)的绑定以及由全局代码中包含的FunctionDeclaration,GeneratorDeclaration或VariableStatement引入的所有绑定。 全局代码中所有其他ECMAScript声明的绑定包含在全局环境记录的声明性环境记录组件中.

可以直接在全局对象上创建属性。 因此,全局环境记录的对象“环境记录”组件可能包含通过FunctionDeclaration,GeneratorDeclaration或VariableDeclaration声明创建的绑定以及隐式创建为全局对象属性的绑定。 为了识别使用声明明确创建的绑定,全局环境记录使用其CreateGlobalVarBinding和CreateGlobalFunctionBinding具体方法维护绑定名称的列表.

全球环境记录在表18中列出了附加领域和表19中列出的附加方法。.

Table 18: Additional Fields of Global Environment Records
Field Name Value Meaning
[[ObjectRecord]] Object Environment Record 绑定对象是global object。 它包含全局内置绑定以及FunctionDeclaration, GeneratorDeclaration, and VariableDeclaration在全局代码中绑定 相关联的领域(realm).
[[GlobalThisValue]] Object 在全局范围内返回的值。 主机(hosts)可以提供任何ECMAScript对象值。
[[DeclarativeRecord]] Declarative Environment Record 包含除了FunctionDeclaration,GeneratorDeclaration和VariableDeclaration绑定之外的关联领域代码的全局代码中的所有声明的绑定.
[[VarNames]] List of String 由相关领域的全局代码中的FunctionDeclaration,GeneratorDeclaration和VariableDeclaration声明绑定的字符串名称。
Table 19: Additional Methods of Global Environment Records
Method Purpose
GetThisBinding() 返回此环境记录的this绑定的值。
HasVarDeclaration (N) 确定参数标识符是否在此环境记录中使用VariableDeclaration,FunctionDeclaration或GeneratorDeclaration创建的绑定。
HasLexicalDeclaration (N) 确定参数标识符是否在此环境记录中使用词法声明(如LexicalDeclaration或ClassDeclaration)创建的绑定。
HasRestrictedGlobalProperty (N) 确定参数是否是全局对象属性的名称,该属性可能不被全局词法绑定所遮蔽。
CanDeclareGlobalVar (N) 确定相应的CreateGlobalVarBinding调用是否成功,如果调用相同的参数N.
CanDeclareGlobalFunction (N) 确定如果相同的参数N被调用,相应的CreateGlobalFunctionBinding调用将成功。
CreateGlobalVarBinding(N, D) 用于在全局环境记录的[[ObjectRecord]]组件中创建和初始化未定义的全局变量绑定。 绑定将是一个可变绑定。 相应的全局对象属性将具有适用于var的属性值。 字符串值N是绑定名称。 如果D为真,绑定可能会被删除。 逻辑上等同于CreateMutableBinding,后跟SetMutableBinding,但它允许var声明接受特殊处理。
CreateGlobalFunctionBinding(N, V, D) 在全局环境记录的[[ObjectRecord]]组件中创建并初始化全局函数绑定。 绑定将是一个可变绑定。 相应的全局对象属性将具有适用于某个函数的属性值。 字符串值N是绑定名称。 V是初始化值。 如果布尔参数D为真,绑定可能会被删除。 逻辑上等同于CreateMutableBinding,后跟SetMutableBinding,但它允许函数声明接受特殊处理。

全局环境记录的具体规范方法的行为由以下算法定义.

8.1.1.4.1HasBinding (N)#

具体的环境记录方法HasBinding for global Environment Records简单地确定参数标识符是否是由记录绑定的标识之一:

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let DclRec be envRec.[[DeclarativeRecord]].
  3. If DclRec.HasBinding(N) is true, return true.
  4. Let ObjRec be envRec.[[ObjectRecord]].
  5. Return ? ObjRec.HasBinding(N).

8.1.1.4.2CreateMutableBinding (N, D)#

具体的环境记录方法CreateMutableBinding用于全局环境记录为未初始化的名称N创建一个新的可变绑定。 绑定在相关的DeclarativeRecord中创建。 在DeclarativeRecord中不能存在N的绑定。 如果布尔参数D的值为true,则新的绑定被标记为被删除。

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let DclRec be envRec.[[DeclarativeRecord]].
  3. If DclRec.HasBinding(N) is true, throw a TypeError exception.
  4. Return DclRec.CreateMutableBinding(N, D).

8.1.1.4.3CreateImmutableBinding (N, S)#

具体的环境记录方法CreateImmutableBinding for global Environment Records为未初始化的名称N创建一个新的不可变绑定。 此N环境记录中不能存在绑定。如果布尔参数S的值为true,则新绑定将被标记为严格绑定。

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let DclRec be envRec.[[DeclarativeRecord]].
  3. If DclRec.HasBinding(N) is true, throw a TypeError exception.
  4. Return DclRec.CreateImmutableBinding(N, S).

8.1.1.4.4InitializeBinding (N, V)#

具体的环境记录方法InitializeBinding for global Environment Records用于将名称为参数N的值的标识符的当前绑定的绑定值设置为参数V的值。N的未初始化绑定必须已存在。

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let DclRec be envRec.[[DeclarativeRecord]].
  3. If DclRec.HasBinding(N) is true, then
    1. Return DclRec.InitializeBinding(N, V).
  4. Assert: If the binding exists, it must be in the object Environment Record.
  5. Let ObjRec be envRec.[[ObjectRecord]].
  6. Return ? ObjRec.InitializeBinding(N, V).

8.1.1.4.5SetMutableBinding (N, V, S)#

具体的环境记录方法SetMutableBinding用于全局环境记录尝试将名称为参数N的值的标识符的当前绑定的绑定值更改为参数V的值。如果绑定是不可变绑定,则TypeError为 如果S为真,则抛出。 名为N的属性通常已经存在,但如果不存在或当前不可写,则错误处理由布尔参数S的值确定.

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let DclRec be envRec.[[DeclarativeRecord]].
  3. If DclRec.HasBinding(N) is true, then
    1. Return DclRec.SetMutableBinding(N, V, S).
  4. Let ObjRec be envRec.[[ObjectRecord]].
  5. Return ? ObjRec.SetMutableBinding(N, V, S).

8.1.1.4.6GetBindingValue (N, S)#

具体的环境记录方法GetBindingValue用于全局环境记录返回其绑定标识符的值,该名称是参数N的值。如果绑定是未初始化的绑定,则引用一个ReferenceError异常。 名为N的属性通常已经存在,但如果不存在或当前不可写,则错误处理由布尔参数S的值确定。

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let DclRec be envRec.[[DeclarativeRecord]].
  3. If DclRec.HasBinding(N) is true, then
    1. Return DclRec.GetBindingValue(N, S).
  4. Let ObjRec be envRec.[[ObjectRecord]].
  5. Return ? ObjRec.GetBindingValue(N, S).

8.1.1.4.7DeleteBinding (N)#

具体的环境记录方法全局环境记录中的DeleteBinding只能删除明确指定为要删除的绑定。

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let DclRec be envRec.[[DeclarativeRecord]].
  3. If DclRec.HasBinding(N) is true, then
    1. Return DclRec.DeleteBinding(N).
  4. Let ObjRec be envRec.[[ObjectRecord]].
  5. Let globalObject be the binding object for ObjRec.
  6. Let existingProp be ? HasOwnProperty(globalObject, N).
  7. If existingProp is true, then
    1. Let status be ? ObjRec.DeleteBinding(N).
    2. If status is true, then
      1. Let varNames be envRec.[[VarNames]].
      2. If N is an element of varNames, remove that element from the varNames.
    3. Return status.
  8. Return true.

8.1.1.4.8HasThisBinding ()#

  1. Return true.

8.1.1.4.9HasSuperBinding ()#

  1. Return false.

8.1.1.4.10WithBaseObject ()#

全局环境记录始终返回undefined为其WithBaseObject。

  1. Return undefined.

8.1.1.4.11GetThisBinding ()#

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Return envRec.[[GlobalThisValue]].

8.1.1.4.12HasVarDeclaration (N)#

具体的环境记录方法HasVarDeclaration用于全局环境记录确定参数标识符是否具有使用VariableStatement或FunctionDeclaration创建的此记录中的绑定:

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let varDeclaredNames be envRec.[[VarNames]].
  3. If varDeclaredNames contains the value of N, return true.
  4. Return false.

8.1.1.4.13HasLexicalDeclaration (N)#

具体的环境记录方法HasLexicalDeclaration用于全局环境记录确定参数标识符是否具有使用词法声明(如LexicalDeclaration或ClassDeclaration)创建的此记录中的绑定:

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let DclRec be envRec.[[DeclarativeRecord]].
  3. Return DclRec.HasBinding(N).

8.1.1.4.14HasRestrictedGlobalProperty (N)#

具体的环境记录方法HasRestrictedGlobalProperty用于全局环境记录确定参数标识符是全局对象的属性的名称,不能被全局词法绑定所遮蔽:

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let ObjRec be envRec.[[ObjectRecord]].
  3. Let globalObject be the binding object for ObjRec.
  4. Let existingProp be ? globalObject.[[GetOwnProperty]](N).
  5. If existingProp is undefined, return false.
  6. If existingProp.[[Configurable]] is true, return false.
  7. Return true.
注意

属性可能存在于直接创建的全局对象上,而不是使用var或函数声明进行声明。 可能不会创建与全局对象的不可配置属性具有相同名称的全局词法绑定。 全局属性未定义是这种属性的一个例子。

8.1.1.4.15CanDeclareGlobalVar (N)#

具体的环境记录方法CanDeclareGlobalVar用于全局环境记录,可以确定相应的CreateGlobalVarBinding调用是否成功,如果调用相同的参数N.对于预先存在的全局对象属性,可以使用冗余变量声明和变量声明。

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let ObjRec be envRec.[[ObjectRecord]].
  3. Let globalObject be the binding object for ObjRec.
  4. Let hasProperty be ? HasOwnProperty(globalObject, N).
  5. If hasProperty is true, return true.
  6. Return ? IsExtensible(globalObject).

8.1.1.4.16CanDeclareGlobalFunction (N)#

具体的环境记录方法CanDeclareGlobalFunction用于全局环境记录确定相应的CreateGlobalFunctionBinding调用是否成功,如果调用相同的参数N.

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let ObjRec be envRec.[[ObjectRecord]].
  3. Let globalObject be the binding object for ObjRec.
  4. Let existingProp be ? globalObject.[[GetOwnProperty]](N).
  5. If existingProp is undefined, return ? IsExtensible(globalObject).
  6. If existingProp.[[Configurable]] is true, return true.
  7. If IsDataDescriptor(existingProp) is true and existingProp has attribute values {[[Writable]]: true, [[Enumerable]]: true}, return true.
  8. Return false.

8.1.1.4.17CreateGlobalVarBinding (N, D)#

具体的环境记录方法CreateGlobalVarBinding为全局环境记录创建和初始化相关对象环境记录中的可变绑定,并记录关联的[[VarNames]]列表中的绑定名称。 如果一个绑定已经存在,它被重用并被假定为初始化。

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let ObjRec be envRec.[[ObjectRecord]].
  3. Let globalObject be the binding object for ObjRec.
  4. Let hasProperty be ? HasOwnProperty(globalObject, N).
  5. Let extensible be ? IsExtensible(globalObject).
  6. If hasProperty is false and extensible is true, then
    1. Perform ? ObjRec.CreateMutableBinding(N, D).
    2. Perform ? ObjRec.InitializeBinding(N, undefined).
  7. Let varDeclaredNames be envRec.[[VarNames]].
  8. If varDeclaredNames does not contain the value of N, then
    1. Append N to varDeclaredNames.
  9. Return NormalCompletion(empty).

8.1.1.4.18CreateGlobalFunctionBinding (N, V, D)#

具体的环境记录方法CreateGlobalFunctionBinding为全局环境记录创建和初始化相关对象环境记录中的可变绑定,并记录关联的[[VarNames]]列表中的绑定名称。 如果绑定已经存在,则被替换。

  1. Let envRec be the global Environment Record for which the method was invoked.
  2. Let ObjRec be envRec.[[ObjectRecord]].
  3. Let globalObject be the binding object for ObjRec.
  4. Let existingProp be ? globalObject.[[GetOwnProperty]](N).
  5. If existingProp is undefined or existingProp.[[Configurable]] is true, then
    1. Let desc be the PropertyDescriptor{[[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D}.
  6. Else,
    1. Let desc be the PropertyDescriptor{[[Value]]: V }.
  7. Perform ? DefinePropertyOrThrow(globalObject, N, desc).
  8. Record that the binding for N in ObjRec has been initialized.
  9. Perform ? Set(globalObject, N, V, false).
  10. Let varDeclaredNames be envRec.[[VarNames]].
  11. If varDeclaredNames does not contain the value of N, then
    1. Append N to varDeclaredNames.
  12. Return NormalCompletion(empty).
注意

全局函数声明始终表示为全局对象的自身属性。 如果可能,将重新配置现有的自有属性以具有一组标准的属性值。 步骤10-12相当于调用InitializeBinding具体方法会做什么,如果globalObject是Proxy将产生与代理陷阱调用相同的序列。

8.1.1.5模块环境记录(Module Environment Records)#

模块环境记录是一个声明性环境用于表示ECMAScript模块外部范围的记录。 除了正常的可变和不可变绑定之外,模块环境还提供了不可变的导入绑定,这些绑定是提供对另一个环境记录中存在的目标绑定的间接访问的绑定。

模块环境记录支持表15中列出的所有声明性环境记录方法,并且除了GetBindingValue,DeleteBinding,HasThisBinding和GetThisBinding之外,共享与所有这些方法相同的规范。 此外,模块环境记录支持表20中列出的方法::

Table 20: Additional Methods of Module Environment Records
Method Purpose
CreateImportBinding(N, M, N2) 在模块环境记录中创建不可变的间接绑定。 字符串值N是绑定名称的文本。 M是模块记录,N2是M的模块环境记录中存在的绑定。
GetThisBinding() 返回此环境记录的this绑定的值。

T模块环境记录的附加具体规范方法的行为由以下算法定义:

8.1.1.5.1GetBindingValue (N, S)#

具体的环境记录方法GetBindingValue用于模块环境记录返回其绑定标识符的值,该名称是参数N的值。但是,如果绑定是间接绑定,则返回目标绑定的值。 如果绑定存在但未初始化,则抛出ReferenceError,而不考虑S的值。

  1. Let envRec be the module Environment Record for which the method was invoked.
  2. Assert: envRec has a binding for N.
  3. If the binding for N is an indirect binding, then
    1. Let M and N2 be the indirection values provided when this binding for N was created.
    2. Let targetEnv be M.[[Environment]].
    3. If targetEnv is undefined, throw a ReferenceError exception.
    4. Let targetER be targetEnv's EnvironmentRecord.
    5. Return ? targetER.GetBindingValue(N2, S).
  4. If the binding for N in envRec is an uninitialized binding, throw a ReferenceError exception.
  5. Return the value currently bound to N in envRec.
Note

Because a Module is always strict mode code, calls to GetBindingValue should always pass true as the value of S.

8.1.1.5.2DeleteBinding (N)#

具体的环境记录方法DeleteBinding为模块环境记录拒绝删除绑定。

  1. Let envRec be the module Environment Record for which the method was invoked.
  2. If envRec does not have a binding for the name that is the value of N, return true.
  3. Return false.
注意

模块环境记录的绑定不可删除。

8.1.1.5.3HasThisBinding ()#

模块环境记录提供了这种绑定。

  1. Return true.

8.1.1.5.4GetThisBinding ()#

  1. Return undefined.

8.1.1.5.5CreateImportBinding (N, M, N2)#

T具体的环境记录方法CreateImportBinding for modules Environment Records为名称N创建一个新的初始化的不可变间接绑定。此环境记录中不能存在绑定N. M是模块记录,N2是绑定的名称 存在于M的模块环境记录中。 访问新绑定的值将间接访问绑定的绑定值。

  1. Let envRec be the module Environment Record for which the method was invoked.
  2. Assert: envRec does not already have a binding for N.
  3. Assert: M is a Module Record.
  4. Assert: When M.[[Environment]] is instantiated it will have a direct binding for N2.
  5. Create an immutable indirect binding in envRec for N that references M and N2 as its target binding and record that the binding is initialized.
  6. Return NormalCompletion(empty).

8.1.2词法环境操作(Lexical Environment Operations)#

本规范中使用以下抽象操作来操作词法环境:

8.1.2.1GetIdentifierReference (lex, name, strict)#

抽象操作GetIdentifierReference使用Lexical Environment lex,String name和布尔标志strict来调用。 lex的值可能为null。 调用时,执行以下步骤:

  1. If lex is the value null, then
    1. Return a value of type Reference whose base value is undefined, whose referenced name is name, and whose strict reference flag is strict.
  2. Let envRec be lex's EnvironmentRecord.
  3. Let exists be ? envRec.HasBinding(name).
  4. If exists is true, then
    1. Return a value of type Reference whose base value is envRec, whose referenced name is name, and whose strict reference flag is strict.
  5. Else,
    1. Let outer be the value of lex's outer environment reference.
    2. Return ? GetIdentifierReference(outer, name, strict).

8.1.2.2NewDeclarativeEnvironment (E)#

当使用词法环境调用抽象操作New Declarative Environment作为参数E时,执行以下步骤:

  1. Let env be a new Lexical Environment.
  2. Let envRec be a new declarative Environment Record containing no bindings.
  3. Set env's EnvironmentRecord to envRec.
  4. Set the outer lexical environment reference of env to E.
  5. Return env.

8.1.2.3NewObjectEnvironment (O, E)#

当使用Object O和词法环境E作为参数调用抽象操作NewObjectEnvironment时,执行以下步骤:

  1. Let env be a new Lexical Environment.
  2. Let envRec be a new object Environment Record containing O as the binding object.
  3. Set env's EnvironmentRecord to envRec.
  4. Set the outer lexical environment reference of env to E.
  5. Return env.

8.1.2.4NewFunctionEnvironment ( F, newTarget )#

当使用参数F和newTarget调用抽象操作NewFunctionEnvironment时,执行以下步骤:

  1. Assert: F is an ECMAScript function.
  2. Assert: Type(newTarget) is Undefined or Object.
  3. Let env be a new Lexical Environment.
  4. Let envRec be a new function Environment Record containing no bindings.
  5. Set envRec.[[FunctionObject]] to F.
  6. If F's [[ThisMode]] internal slot is lexical, set envRec.[[ThisBindingStatus]] to "lexical".
  7. Else, set envRec.[[ThisBindingStatus]] to "uninitialized".
  8. Let home be the value of F's [[HomeObject]] internal slot.
  9. Set envRec.[[HomeObject]] to home.
  10. Set envRec.[[NewTarget]] to newTarget.
  11. Set env's EnvironmentRecord to envRec.
  12. Set the outer lexical environment reference of env to the value of F's [[Environment]] internal slot.
  13. Return env.

8.1.2.5NewGlobalEnvironment ( G, thisValue )#

当使用参数G和thisValue调用抽象操作NewGlobalEnvironment时,执行以下步骤:

  1. Let env be a new Lexical Environment.
  2. Let objRec be a new object Environment Record containing G as the binding object.
  3. Let dclRec be a new declarative Environment Record containing no bindings.
  4. Let globalRec be a new global Environment Record.
  5. Set globalRec.[[ObjectRecord]] to objRec.
  6. Set globalRec.[[GlobalThisValue]] to thisValue.
  7. Set globalRec.[[DeclarativeRecord]] to dclRec.
  8. Set globalRec.[[VarNames]] to a new empty List.
  9. Set env's EnvironmentRecord to globalRec.
  10. Set the outer lexical environment reference of env to null.
  11. Return env.

8.1.2.6NewModuleEnvironment (E)#

当使用Lexical Environment参数E调用抽象操作NewModuleEnvironment时,执行以下步骤:

  1. Let env be a new Lexical Environment.
  2. Let envRec be a new module Environment Record containing no bindings.
  3. Set env's EnvironmentRecord to envRec.
  4. Set the outer lexical environment reference of env to E.
  5. Return env.

8.2领域(Realms)#

在执行之前,所有ECMAScript代码必须与领域相关联。 在概念上,一个领域由一组内在对象,一个ECMAScriptglobal环境,所有在该全局环境的范围内加载的ECMAScript代码以及其他关联的状态和资源组成。

A realm is represented in this specification as a Realm Record with the fields specified in Table 21:

Table 21: Realm Record Fields
Field Name Value Meaning
[[Intrinsics]] Record whose field names are intrinsic keys and whose values are objects 与该领域相关联的代码使用的内在值
[[GlobalObject]] Object The global object for this realm
[[GlobalEnv]] Lexical Environment The global environment for this realm
[[TemplateMap]] A List of Record { [[Strings]]: List, [[Array]]: Object}. 模板对象使用其Realm Record的[[TemplateMap]]为每个领域单独规范化。 每个[[Strings]]值是一个以源文本顺序包含已被执行的TemplateLiteral的raw String值的列表。 相关的[[Array]]值是传递给标签函数的相应模板对象。

实现可以定义其他实现特定字段。

8.2.1CreateRealm ( )#

没有参数的抽象操作CreateRealm执行以下步骤:

  1. Let realmRec be a new Realm Record.
  2. Perform CreateIntrinsics(realmRec).
  3. Set realmRec.[[GlobalObject]] to undefined.
  4. Set realmRec.[[GlobalEnv]] to undefined.
  5. Set realmRec.[[TemplateMap]] to a new empty List.
  6. Return realmRec.

8.2.2CreateIntrinsics ( realmRec )#

当抽象操作CreateIntrinsics与参数realmRec执行以下步骤:

  1. Let intrinsics be a new Record.
  2. Set realmRec.[[Intrinsics]] to intrinsics.
  3. Let objProto be ObjectCreate(null).
  4. Set intrinsics.[[%ObjectPrototype%]] to objProto.
  5. Let throwerSteps be the algorithm steps specified in 9.2.7.1 for the %ThrowTypeError% function.
  6. Let thrower be CreateBuiltinFunction(realmRec, throwerSteps, null).
  7. Set intrinsics.[[%ThrowTypeError%]] to thrower.
  8. Let noSteps be an empty sequence of algorithm steps.
  9. Let funcProto be CreateBuiltinFunction(realmRec, noSteps, objProto).
  10. Set intrinsics.[[%FunctionPrototype%]] to funcProto.
  11. Call thrower.[[SetPrototypeOf]](funcProto).
  12. Perform AddRestrictedFunctionProperties(funcProto, realmRec).
  13. 使用表7中列出的尚未在上面处理的值设置内在函数的字段。 字段名称是表中第一列中列出的名称。 每个字段的值是一个全新的对象值,并且递归地填充了第18〜26章中每个对象的规范定义的属性值。 所有对象属性值都是新创建的对象值。 所有内置函数对象的值都是通过执行CreateBuiltinFunction(realmRec, <steps>, <prototype>, <slots>)创建的,其中是本规范提供的该函数的定义,是指定的 功能的[[Prototype]]内部插槽和的值是功能指定内部插槽的名称(如果有)的列表。 必须命令创建内在函数及其属性,以避免对尚未创建的对象的任何依赖关系。
  14. Return intrinsics.

8.2.3SetRealmGlobalObject ( realmRec, globalObj, thisValue )#

参数realmRec,globalObj和thisValue的抽象操作SetRealmGlobalObject执行以下步骤:

  1. If globalObj is undefined, then
    1. Let intrinsics be realmRec.[[Intrinsics]].
    2. Let globalObj be ObjectCreate(intrinsics.[[%ObjectPrototype%]]).
  2. Assert: Type(globalObj) is Object.
  3. If thisValue is undefined, let thisValue be globalObj.
  4. Set realmRec.[[GlobalObject]] to globalObj.
  5. Let newGlobalEnv be NewGlobalEnvironment(globalObj, thisValue).
  6. Set realmRec.[[GlobalEnv]] to newGlobalEnv.
  7. Return realmRec.

8.2.4SetDefaultGlobalBindings ( realmRec )#

参数realmRec的抽象操作SetDefaultGlobalBindings执行以下步骤:

  1. Let global be realmRec.[[GlobalObject]].
  2. For each property of the Global Object specified in clause 18, do
    1. Let name be the String value of the property name.
    2. Let desc be the fully populated data property descriptor for the property containing the specified attributes for the property. For properties listed in 18.2, 18.3, or 18.4 the value of the [[Value]] attribute is the corresponding intrinsic object from realmRec.
    3. Perform ? DefinePropertyOrThrow(global, name, desc).
  3. Return global.

8.3执行上下文(Execution Contexts)#

执行上下文是用于通过ECMAScript实现跟踪代码的运行时执行的规范设备。 在任何时间点,最多只有一个执行上下文正在执行代码。 这被称为运行执行上下文。

执行上下文堆栈(The execution context stack)用于跟踪执行上下文。 运行执行上下文始终是此堆栈的顶级元素。 每当控制从与当前运行的执行上下文相关联的可执行代码传送到与执行上下文不相关联的可执行代码时,就会创建一个新的执行上下文。 新创建的执行上下文被推送到堆栈,并成为正在运行的执行上下文。

执行上下文包含跟踪其关联代码的执行进度所需的任何实现特定状态。 每个执行上下文至少具有表22中列出的状态组件。

Table 22: State Components for All Execution Contexts
Component Purpose
code evaluation state 执行,暂停和恢复与该执行上下文相关联的代码的执行所需的任何状态。
Function 如果这个执行环境正在执行函数对象的代码,那么这个组件的值就是该函数对象。 如果上下文执行脚本或模块的代码,则该值为null。
Realm 相关代码访问ECMAScript资源的Realm Record
ScriptOrModule Module Record or Script Record来自哪个相关代码。 如果没有原始脚本或模块,那么在InitializeHostDefinedRealm,值为null

通过运行执行上下文对代码的执行可以在本说明书中定义的各个点暂停。 一旦运行的执行上下文被暂停,不同的执行上下文可能成为正在运行的执行上下文,并开始执行其代码。 在稍后的时间,暂停的执行上下文可能再次成为正在运行的执行上下文,并且在先前被暂停的位置继续执行其代码。 在执行上下文中运行执行上下文状态的转换通常以堆栈类似的先进先出方式发生。 然而,一些ECMAScript功能需要运行执行上下文的非LIFO转换。

运行执行上下文的Realm组件的值也称为当前的Realm Record。 运行执行上下文的Function组件的值也称为活动函数对象.

Execution contexts for ECMAScript code have the additional state components listed in Table 23.

Table 23: Additional State Components for ECMAScript Code Execution Contexts
Component Purpose
LexicalEnvironment 标识用于解析在此执行上下文中由代码创建的标识符引用的词法环境。
VariableEnvironment 标识其EnvironmentRecord保存由VariableStatements在此执行上下文中创建的绑定的词法环境。

执行环境的LexicalEnvironment和VariableEnvironment组件总是词法环境。 当执行上下文创建时,其LexicalEnvironment和VariableEnvironment组件最初具有相同的值。

表示generator objects 执行的执行上下文具有表24中列出的附加状态组件。

Table 24: Additional State Components for Generator Execution Contexts
Component Purpose
Generator 该执行上下文正在执行的GeneratorObject。

在大多数情况下,只有运行的执行上下文(执行上下文堆栈的顶部)才能由本规范中的算法直接操作。 因此,当术语“LexicalEnvironment”和“VariableEnvironment”在没有资格的情况下被使用时,它们是引用运行执行上下文的那些组件。

执行上下文纯粹是一个规范机制,不需要对应于ECMAScript实现的任何特定的工件。 ECMAScript代码不可能直接访问或观察执行上下文。

8.3.1GetActiveScriptOrModule ()#

GetActiveScriptOrModule抽象操作用于基于活动的功能对象来确定运行的脚本或模块。 GetActiveScriptOrModule执行以下步骤:

  1. If the execution context stack is empty, return null.
  2. Let ec be the topmost execution context on the execution context stack whose Function component's [[ScriptOrModule]] component is not null.
  3. If such an execution context exists, return ec's Function component's [[ScriptOrModule]] slot's value.
  4. Otherwise, let ec be the running execution context.
  5. Assert: ec's ScriptOrModule component is not null.
  6. Return ec's ScriptOrModule component.

8.3.2ResolveBinding ( name [ , env ] )#

ResolveBinding抽象操作用于确定作为String值传递的名称的绑定。 可选参数env可用于显式提供要搜索绑定的词法环境。 在执行ECMAScript代码期间,使用以下算法执行ResolveBinding:

  1. If env was not passed or if env is undefined, then
    1. Let env be the running execution context's LexicalEnvironment.
  2. Assert: env is a Lexical Environment.
  3. If the code matching the syntactic production that is being evaluated is contained in strict mode code, let strict be true, else let strict be false.
  4. Return ? GetIdentifierReference(env, name, strict).
Note

The result of ResolveBinding is always a Reference value with its referenced name component equal to the name argument.

8.3.3GetThisEnvironment ( )#

抽象操作GetThisEnvironment查找当前提供关键字绑定的环境记录。 GetThisEnvironment执行以下步骤:

  1. Let lex be the running execution context's LexicalEnvironment.
  2. Repeat
    1. Let envRec be lex's EnvironmentRecord.
    2. Let exists be envRec.HasThisBinding().
    3. If exists is true, return envRec.
    4. Let outer be the value of lex's outer environment reference.
    5. Let lex be outer.
注意

步骤2中的循环将始终终止,因为环境列表总是以具有此绑定的全局环境结束。

8.3.4ResolveThisBinding ( )#

抽象操作ResolveThisBinding使用运行执行上下文的LexicalEnvironment来确定关键字的绑定。 ResolveThisBinding执行以下步骤:

  1. Let envRec be GetThisEnvironment( ).
  2. Return ? envRec.GetThisBinding().

8.3.5GetNewTarget ( )#

抽象操作GetNewTarget使用运行执行上下文的LexicalEnvironment来确定NewTarget值。 GetNewTarget执行以下步骤:

  1. Let envRec be GetThisEnvironment( ).
  2. Assert: envRec has a [[NewTarget]] field.
  3. Return envRec.[[NewTarget]].

8.3.6GetGlobalObject ( )#

抽象操作GetGlobalObject返回当前运行的执行上下文使用的全局对象。 GetGlobalObject执行以下步骤:

  1. Let ctx be the running execution context.
  2. Let currentRealm be ctx's Realm.
  3. Return currentRealm.[[GlobalObject]].

8.4工作和作业排队(Jobs and Job Queues)#

作业是一个抽象的操作,当没有其他ECMAScript计算当前正在进行时启动ECMAScript计算。 作业抽象操作可以被定义为接受任意一组作业参数。

只有当没有运行执行上下文并且执行上下文堆栈为空时,才能启动作业的执行。 PendingJob是将来执行作业的请求。 PendingJob是一个内部记录,其字段在表25中指定。一旦作业执行启动,作业总是执行完成。 在当前运行的作业完成之前,不能启动任何其他作业。 但是,当前正在运行的作业或外部事件可能导致在完成当前正在运行的作业之后的某个时间可能启动的其他PendingJob的入队。

Table 25: PendingJob Record Fields
Field Name Value Meaning
[[Job]] The name of a Job abstract operation 这是在启动此PendingJob的执行时执行的抽象操作。 作业是使用NextJob而不是Return表示它们已经完成的抽象操作。
[[Arguments]] A List 激活时要传递给[[Job]]的参数值列表。
[[Realm]] A Realm Record 当此PendingJob启动时,用于初始执行上下文的领域记录。
[[ScriptOrModule]] A Script Record or Module Record 当此PendingJob启动时,用于初始执行上下文的脚本或模块。
[[HostDefined]] Any, default value is undefined. 字段保留供主要环境使用,需要将附加信息与挂起的作业相关联。

作业队列是PendingJob记录的FIFO队列。 每个作业队列都有一个名称,可用作业队列的完整集由ECMAScript实现定义。 每个ECMAScript实现至少具有表26中定义的作业队列。

Table 26: Required Job Queues
Name Purpose
ScriptJobs 验证和执行ECMAScript脚本和模块源文本的作业。 见第10和15章节。
PromiseJobs 解决承诺(Promise)的作业(见25.4)。

通过在作业队列中排队包含作业抽象操作名称和任何必需的参数值的PendingJob记录来进行将来执行作业的请求。 当没有运行执行上下文并且执行上下文堆栈为空时,ECMAScript实现从作业队列中移除第一个PendingJob,并使用其中包含的信息来创建执行上下文并开始执行相关的Job抽象操作。

Note

来自单个作业队列的PendingJob记录始终以FIFO顺序启动。 此规范未定义多个作业队列被服务的顺序。 ECMAScript实现可以将作业队列的PendingJob记录的FIFO执行与一个或多个其他作业队列的PendingJob记录进行执行。 实现必须定义当没有运行的执行上下文和所有作业队列都为空时发生的情况。

以下抽象操作用于创建和管理作业和作业队列:

8.4.1EnqueueJob (queueName, job, arguments)#

EnqueueJob抽象操作需要三个参数:queueName,job和arguments。它执行以下步骤:

  1. Assert: Type(queueName) 是String,其值是此实现识别的作业队列的名称。
  2. Assert: job is the name of a Job.
  3. Assert: arguments is a List that has the same number of elements as the number of parameters required by job.
  4. Let callerContext be the running execution context.
  5. Let callerRealm be callerContext's Realm.
  6. Let callerScriptOrModule be callerContext's ScriptOrModule.
  7. Let pending be PendingJob{ [[Job]]: job, [[Arguments]]: arguments, [[Realm]]: callerRealm, [[ScriptOrModule]]: callerScriptOrModule, [[HostDefined]]: undefined }.
  8. Perform any implementation or host environment defined processing of pending. This may include modifying the [[HostDefined]] field or any other field of pending.
  9. Add pending at the back of the Job Queue named by queueName.
  10. Return NormalCompletion(empty).

8.4.2NextJob#

算法步骤如:

  1. NextJob result.

用于作业抽象操作代替:

  1. Return result.

J作业抽象操作不能包含返回步骤或ReturnIfAbrupt步骤。 NextJob结果操作等效于以下步骤:

  1. If result is an abrupt completion, perform HostReportErrorsresult.[[Value]] »).
  2. Suspend the running execution context and remove it from the execution context stack.
  3. Assert: The execution context stack is now empty.
  4. Let nextQueue be a non-empty Job Queue chosen in an implementation defined manner. If all Job Queues are empty, the result is implementation defined.
  5. Let nextPending be the PendingJob record at the front of nextQueue. Remove that record from nextQueue.
  6. Let newContext be a new execution context.
  7. Set newContext's Function to null.
  8. Set newContext's Realm to nextPending.[[Realm]].
  9. Set newContext's ScriptOrModule to nextPending.[[ScriptOrModule]].
  10. Push newContext onto the execution context stack; newContext is now the running execution context.
  11. Perform any implementation or host environment defined job initialization using nextPending.
  12. Perform the abstract operation named by nextPending.[[Job]] using the elements of nextPending.[[Arguments]] as its arguments.

8.5InitializeHostDefinedRealm ( )#

抽象操作InitializeHostDefinedRealm执行以下步骤:

  1. Let realm be CreateRealm().
  2. Let newContext be a new execution context.
  3. Set the Function of newContext to null.
  4. Set the Realm of newContext to realm.
  5. Set the ScriptOrModule of newContext to null.
  6. Push newContext onto the execution context stack; newContext is now the running execution context.
  7. If the host requires use of an exotic object to serve as realm's global object, let global be such an object created in an implementation defined manner. Otherwise, let global be undefined, indicating that an ordinary object should be created as the global object.
  8. If the host requires that the this binding in realm's global scope return an object other than the global object, let thisValue be such an object created in an implementation defined manner. Otherwise, let thisValue be undefined, indicating that realm's global this binding should be the global object.
  9. Perform SetRealmGlobalObject(realm, global, thisValue).
  10. Let globalObj be ? SetDefaultGlobalBindings(realm).
  11. Create any implementation defined global object properties on globalObj.
  12. In an implementation dependent manner, obtain the ECMAScript source texts (see clause 10) and any associated host-defined values for zero or more ECMAScript scripts and/or ECMAScript modules. For each such sourceText and hostDefined,
    1. If sourceText is the source code of a script, then
      1. Perform EnqueueJob("ScriptJobs", ScriptEvaluationJob, « sourceText, hostDefined »).
    2. Else sourceText is the source code of a module,
      1. Perform EnqueueJob("ScriptJobs", TopLevelModuleEvaluationJob, « sourceText, hostDefined »).
  13. NextJob NormalCompletion(undefined).

9普通和非普通对象行为(Ordinary and Exotic Objects Behaviours)#

9.1普通对象内部方法和内部插槽(Ordinary Object Internal Methods and Internal Slots)#

所有普通的对象都有一个名为[[Prototype]]的内部插槽。该内部插槽的值为null或一个对象,用于实现继承。 [[Prototype]]对象的数据属性被继承(作为子对象的属性可见),用于获取访问权限,但不能用于设置访问。访问者属性被继承用于访问和设置访问。 每个普通对象都有一个布尔值的[[Extensible]]内部插槽,用于控制属性是否可以添加到对象。如果[[可扩展]]内部插槽的值为false,则可能不会将其他属性添加到对象。另外,如果[[可扩展]]为false,对象的[[Prototype]]内部插槽的值可能不会被修改。一旦对象的[[Extensible]]内部插槽的值设置为false,它可能不会随后更改为true。 在下面的算法描述中,假设O是普通对象,P是属性键值,V是任何ECMAScript语言值,Desc是属性描述符记录。 每个普通的对象内部方法委托给类似命名的抽象操作。如果这样的抽象操作取决于另一个内部方法,那么内部方法在O上被调用,而不是直接调用类似命名的抽象操作。这些语义确保异常对象在应用普通对象内部方法时调用其重写的内部方法

9.1.1[[GetPrototypeOf]] ( )#

当调用O [[GetPrototypeOf]]内部方法时,执行以下步骤:

  1. Return ! OrdinaryGetPrototypeOf(O).

9.1.1.1OrdinaryGetPrototypeOf (O)#

当使用Object O调用抽象操作OrdinaryGetPrototypeOf时,执行以下步骤:

  1. Return the value of the [[Prototype]] internal slot of O.

9.1.2[[SetPrototypeOf]] (V)#

当使用参数V调用O [[SetPrototypeOf]]内部方法时,将执行以下步骤:

  1. Return ! OrdinarySetPrototypeOf(O, V).

9.1.2.1OrdinarySetPrototypeOf (O, V)#

当使用Object O和值V调用抽象操作OrdinarySetPrototypeOf时,执行以下步骤:

  1. Assert: Either Type(V) is Object or Type(V) is Null.
  2. Let extensible be the value of the [[Extensible]] internal slot of O.
  3. Let current be the value of the [[Prototype]] internal slot of O.
  4. If SameValue(V, current) is true, return true.
  5. If extensible is false, return false.
  6. Let p be V.
  7. Let done be false.
  8. Repeat while done is false,
    1. If p is null, let done be true.
    2. Else, if SameValue(p, O) is true, return false.
    3. Else,
      1. If the [[GetPrototypeOf]] internal method of p is not the ordinary object internal method defined in 9.1.1, let done be true.
      2. Else, let p be the value of p's [[Prototype]] internal slot.
  9. Set the value of the [[Prototype]] internal slot of O to V.
  10. Return true.
Note

步骤8中的循环保证在任何原型链中不存在只包含使用[[GetPrototypeOf]]和[[SetPrototypeOf]]的普通对象定义的对象的循环。

9.1.3[[IsExtensible]] ( )#

当调用O [[IsExtensible]]内部方法时,执行以下步骤:

  1. Return ! OrdinaryIsExtensible(O).

9.1.3.1OrdinaryIsExtensible (O)#

当使用Object O调用抽象操作OrdinaryIsExtensible时,执行以下步骤:

  1. Return the value of the [[Extensible]] internal slot of O.

9.1.4[[PreventExtensions]] ( )#

当调用O [[PreventExtensions]]内部方法时,执行以下步骤:

  1. Return ! OrdinaryPreventExtensions(O).

9.1.4.1OrdinaryPreventExtensions (O)#

当使用Object O调用抽象操作OrdinaryPreventExtensions时,执行以下步骤:

  1. Set the value of the [[Extensible]] internal slot of O to false.
  2. Return true.

9.1.5[[GetOwnProperty]] (P)#

当使用属性键P调用O [[GetOwnProperty]]内部方法时,将执行以下步骤:

  1. Return ! OrdinaryGetOwnProperty(O, P).

9.1.5.1OrdinaryGetOwnProperty (O, P)#

当使用Object O 和属性键 P 调用抽象操作OrdinaryGetOwnProperty时,执行以下步骤:

  1. Assert: IsPropertyKey(P) is true.
  2. If O does not have an own property with key P, return undefined.
  3. Let D be a newly created Property Descriptor with no fields.
  4. Let X be O's own property whose key is P.
  5. If X is a data property, then
    1. Set D.[[Value]] to the value of X's [[Value]] attribute.
    2. Set D.[[Writable]] to the value of X's [[Writable]] attribute.
  6. Else X is an accessor property, so
    1. Set D.[[Get]] to the value of X's [[Get]] attribute.
    2. Set D.[[Set]] to the value of X's [[Set]] attribute.
  7. Set D.[[Enumerable]] to the value of X's [[Enumerable]] attribute.
  8. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute.
  9. Return D.

9.1.6[[DefineOwnProperty]] (P, Desc)#

当使用属性键P和属性描述符Desc调用O [[DefineOwnProperty]]内部方法时,将执行以下步骤:

  1. Return ? OrdinaryDefineOwnProperty(O, P, Desc).

9.1.6.1OrdinaryDefineOwnProperty (O, P, Desc)#

当使用Object O,属性键P和属性描述符Desc调用抽象操作OrdinaryDefineOwnProperty时,执行以下步骤:

  1. Let current be ? O.[[GetOwnProperty]](P).
  2. Let extensible be the value of the [[Extensible]] internal slot of O.
  3. Return ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current).

9.1.6.2IsCompatiblePropertyDescriptor (Extensible, Desc, Current)#

当抽象操作IsCompatiblePropertyDescriptor被调用Boolean值可扩展,属性描述符Desc和Current时,执行以下步骤:

  1. Return ValidateAndApplyPropertyDescriptor(undefined, undefined, Extensible, Desc, Current).

9.1.6.3ValidateAndApplyPropertyDescriptor (O, P, extensible, Desc, current)#

当抽象操作ValidateAndApplyPropertyDescriptor被调用Object O,属性键P,布尔值可扩展和属性描述符Desc和当前时,采取以下步骤:

该算法包含测试特定值的属性描述符描述符的各个字段的步骤。 以这种方式测试的字段不需要实际存在于Desc中。 如果一个字段不存在,那么它的值被认为是false。

Note 1

如果undefined作为O参数传递,则仅执行验证,并且不执行对象更新。

  1. Assert: If O is not undefined, then IsPropertyKey(P) is true.
  2. If current is undefined, then
    1. If extensible is false, return false.
    2. Assert: extensible is true.
    3. If IsGenericDescriptor(Desc) is true or IsDataDescriptor(Desc) is true, then
      1. If O is not undefined, create an own data property named P of object O whose [[Value]], [[Writable]], [[Enumerable]] and [[Configurable]] attribute values are described by Desc. If the value of an attribute field of Desc is absent, the attribute of the newly created property is set to its default value.
    4. Else Desc must be an accessor Property Descriptor,
      1. If O is not undefined, create an own accessor property named P of object O whose [[Get]], [[Set]], [[Enumerable]] and [[Configurable]] attribute values are described by Desc. If the value of an attribute field of Desc is absent, the attribute of the newly created property is set to its default value.
    5. Return true.
  3. Return true, if every field in Desc is absent.
  4. Return true, if every field in Desc also occurs in current and the value of every field in Desc is the same value as the corresponding field in current when compared using the SameValue algorithm.
  5. If the [[Configurable]] field of current is false, then
    1. Return false, if the [[Configurable]] field of Desc is true.
    2. Return false, if the [[Enumerable]] field of Desc is present and the [[Enumerable]] fields of current and Desc are the Boolean negation of each other.
  6. If IsGenericDescriptor(Desc) is true, no further validation is required.
  7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) have different results, then
    1. Return false, if the [[Configurable]] field of current is false.
    2. If IsDataDescriptor(current) is true, then
      1. If O is not undefined, convert the property named P of object O from a data property to an accessor property. Preserve the existing values of the converted property's [[Configurable]] and [[Enumerable]] attributes and set the rest of the property's attributes to their default values.
    3. Else,
      1. If O is not undefined, convert the property named P of object O from an accessor property to a data property. Preserve the existing values of the converted property's [[Configurable]] and [[Enumerable]] attributes and set the rest of the property's attributes to their default values.
  8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both true, then
    1. If the [[Configurable]] field of current is false, then
      1. Return false, if the [[Writable]] field of current is false and the [[Writable]] field of Desc is true.
      2. If the [[Writable]] field of current is false, then
        1. Return false, if the [[Value]] field of Desc is present and SameValue(Desc.[[Value]], current.[[Value]]) is false.
    2. Else the [[Configurable]] field of current is true, so any change is acceptable.
  9. Else IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc) are both true,
    1. If the [[Configurable]] field of current is false, then
      1. Return false, if the [[Set]] field of Desc is present and SameValue(Desc.[[Set]], current.[[Set]]) is false.
      2. Return false, if the [[Get]] field of Desc is present and SameValue(Desc.[[Get]], current.[[Get]]) is false.
  10. If O is not undefined, then
    1. For each field of Desc that is present, set the corresponding attribute of the property named P of object O to the value of the field.
  11. Return true.
Note 2

如果当前的[[Configurable]]字段为真,则步骤8.b允许Desc的任何字段与当前的相应字段不同。 这甚至允许更改[[Writable]]属性为false的属性的[[Value]]。 这是允许的,因为一个true [[Configurable]]属性将允许等同的调用序列,其中[[Writable]]首先设置为true,设置一个新的[[Value]],然后设置[[Writable]] 为false

9.1.7[[HasProperty]](P)#

当使用属性键P调用O [[HasProperty]]内部方法时,执行以下步骤:

  1. Return ? OrdinaryHasProperty(O, P).

9.1.7.1OrdinaryHasProperty (O, P)#

当使用Object O和属性键P调用抽象操作OrdinaryHasProperty时,执行以下步骤:

  1. Assert: IsPropertyKey(P) is true.
  2. Let hasOwn be ? O.[[GetOwnProperty]](P).
  3. If hasOwn is not undefined, return true.
  4. Let parent be ? O.[[GetPrototypeOf]]().
  5. If parent is not null, then
    1. Return ? parent.[[HasProperty]](P).
  6. Return false.

9.1.8[[Get]] (P, Receiver)#

当使用属性键P和ECMAScript语言值Receiver调用O [[Get]]内部方法时,执行以下步骤:

  1. Return ? OrdinaryGet(O, P, Receiver).

9.1.8.1OrdinaryGet (O, P, Receiver)#

当使用Object O,属性键P和ECMAScript语言值Receiver调用抽象操作OrdinaryGet时,执行以下步骤:

  1. Assert: IsPropertyKey(P) is true.
  2. Let desc be ? O.[[GetOwnProperty]](P).
  3. If desc is undefined, then
    1. Let parent be ? O.[[GetPrototypeOf]]().
    2. If parent is null, return undefined.
    3. Return ? parent.[[Get]](P, Receiver).
  4. If IsDataDescriptor(desc) is true, return desc.[[Value]].
  5. Assert: IsAccessorDescriptor(desc) is true.
  6. Let getter be desc.[[Get]].
  7. If getter is undefined, return undefined.
  8. Return ? Call(getter, Receiver).

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

当使用属性键P,值V和ECMAScript语言值Receiver调用O [[Set]]内部方法时,执行以下步骤:

  1. Return ? OrdinarySet(O, P, V, Receiver).

9.1.9.1OrdinarySet (O, P, V, Receiver)#

当使用Object O,属性键P,值V和ECMAScript语言值Receiver调用抽象操作OrdinarySet时,执行以下步骤:

  1. Assert: IsPropertyKey(P) is true.
  2. Let ownDesc be ? O.[[GetOwnProperty]](P).
  3. If ownDesc is undefined, then
    1. Let parent be ? O.[[GetPrototypeOf]]().
    2. If parent is not null, then
      1. Return ? parent.[[Set]](P, V, Receiver).
    3. Else,
      1. Let ownDesc be the PropertyDescriptor{[[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}.
  4. If IsDataDescriptor(ownDesc) is true, then
    1. If ownDesc.[[Writable]] is false, return false.
    2. If Type(Receiver) is not Object, return false.
    3. Let existingDescriptor be ? Receiver.[[GetOwnProperty]](P).
    4. If existingDescriptor is not undefined, then
      1. If IsAccessorDescriptor(existingDescriptor) is true, return false.
      2. If existingDescriptor.[[Writable]] is false, return false.
      3. Let valueDesc be the PropertyDescriptor{[[Value]]: V}.
      4. Return ? Receiver.[[DefineOwnProperty]](P, valueDesc).
    5. Else Receiver does not currently have a property P,
      1. Return ? CreateDataProperty(Receiver, P, V).
  5. Assert: IsAccessorDescriptor(ownDesc) is true.
  6. Let setter be ownDesc.[[Set]].
  7. If setter is undefined, return false.
  8. Perform ? Call(setter, Receiver, « V »).
  9. Return true.

9.1.10[[Delete]] (P)#

当使用属性键P调用O [[Delete]]内部方法时,将执行以下步骤:

  1. Return ? OrdinaryDelete(O, P).

9.1.10.1OrdinaryDelete (O, P)#

当使用Object O和属性键P调用抽象操作OrdinaryDelete时,执行以下步骤:

  1. Assert: IsPropertyKey(P) is true.
  2. Let desc be ? O.[[GetOwnProperty]](P).
  3. If desc is undefined, return true.
  4. If desc.[[Configurable]] is true, then
    1. Remove the own property with name P from O.
    2. Return true.
  5. Return false.

9.1.11[[OwnPropertyKeys]] ( )#

当调用O [[OwnPropertyKeys]]内部方法时,执行以下步骤:

  1. Return ! OrdinaryOwnPropertyKeys(O).

9.1.11.1OrdinaryOwnPropertyKeys (O)#

当使用Object O调用抽象操作OrdinaryOwnPropertyKeys时,将执行以下步骤:

  1. Let keys be a new empty List.
  2. 对于作为整数索引的每个自己的属性键P,以升序的数字索引顺序
    1. Add P as the last element of keys.
  3. 对于属于String的 O 的每个自己的属性键 P ,但不是整数索引,按照属性创建的升序顺序
    1. Add P as the last element of keys.
  4. 对于作为Symbol的 O 的每个自己的属性键 P ,按照属性创建的升序顺序
    1. Add P as the last element of keys.
  5. Return keys.

9.1.12ObjectCreate (proto [ , internalSlotsList ])#

使用参数proto(一个对象或null)的抽象操作ObjectCreate用于指定新的普通对象的运行时创建。 可选参数internalSlotsList是必须定义为对象一部分的附加内部插槽的名称列表。 如果未提供列表,则使用新的空列表。 此抽象操作执行以下步骤:

  1. If internalSlotsList was not provided, let internalSlotsList be a new empty List.
  2. Let obj be a newly created object with an internal slot for each name in internalSlotsList.
  3. Set obj's essential internal methods to the default ordinary object definitions specified in 9.1.
  4. Set the [[Prototype]] internal slot of obj to proto.
  5. Set the [[Extensible]] internal slot of obj to true.
  6. Return obj.

9.1.13OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )#

抽象操作OrdinaryCreateFromConstructor创建一个普通对象,该对象的[[Prototype]]值从构造函数的prototype属性中检索(如果存在)。 否则,使用intrinsicDefaultProto命名的内在函数用于[[Prototype]]。 可选的internalSlotsList是必须定义为对象一部分的附加内部插槽的名称列表。 如果未提供列表,则使用新的空列表。 此抽象操作执行以下步骤:

  1. Assert: intrinsicDefaultProto 是一个String值,它是此规范的内在对象的名称。 相应的对象必须是一个内在函数,它被用作对象的[[Prototype]]值。
  2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto).
  3. Return ObjectCreate(proto, internalSlotsList).

9.1.14GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )#

抽象操作GetPrototypeFromConstructor确定应该用于创建与特定构造函数对应的对象的[[Prototype]]值。 该值从构造函数的prototype属性中检索(如果存在)。 否则,使用intrinsicDefaultProto命名的内在函数用于[[Prototype]]。 此抽象操作执行以下步骤:

  1. Assert: intrinsicDefaultProto 是一个String值,它是此规范的内在对象的名称。 相应的对象必须是一个内在函数,它被用作对象的[[Prototype]]值。
  2. Assert: IsCallable(constructor) is true.
  3. Let proto be ? Get(constructor, "prototype").
  4. If Type(proto) is not Object, then
    1. Let realm be ? GetFunctionRealm(constructor).
    2. Let proto be realm's intrinsic object named intrinsicDefaultProto.
  5. Return proto.
Note

如果构造函数不提供[[Prototype]]值,则使用的默认值从realm构造函数获得,而不是从 运行执行上下文

9.2ECMAScript函数对象(ECMAScript Function Objects)#

ECMAScript函数对象将参数化ECMAScript代码封装在词法环境中,并支持该代码的动态执行。 ECMAScript函数对象是普通对象,并且具有与其他普通对象相同的内部插槽和相同的内部方法。 ECMAScript函数对象的代码可能是严格模式代码(10.2.1)或非严格模式代码。 代码为严格模式代码的ECMAScript函数对象称为严格函数。 其代码不是严格模式代码的人称为非严格函数。

ECMAScript函数对象具有表27中列出的附加内部插槽

Table 27: Internal Slots of ECMAScript Function Objects
Internal Slot Type Description
[[Environment]] Lexical Environment 功能关闭的词法环境。在执行函数的代码时用作外部环境。
[[FormalParameters]] Parse Node 源文本的根解析节点定义函数的形式参数列表。
[[FunctionKind]] String “normal”,“classConstructor”或“generator”
[[ECMAScriptCode]] Parse Node 定义函数体的源文本的根解析节点。
[[ConstructorKind]] String "base" 或 "derived".
[[Realm]] Realm Record 创建函数的领域,并提供在执行函数时访问的任何内在对象。
[[ScriptOrModule]] Script Record or Module Record 创建函数的脚本或模块。
[[ThisMode]] (lexical, strict, global) 定义如何在函数的形式参数和代码体内解释引用。 词汇意味着这是指一个词汇封闭函数的这个值。 strict意味着该值完全按照函数调用的方式使用。 全局意味着这个未定义的值被解释为对全局对象的引用。
[[Strict]] Boolean 如果这是严格的模式函数,则为真,如果不是严格的模式函数,则为false。
[[HomeObject]] Object 如果函数使用super,这是[[GetPrototypeOf]]提供super属性查找开始的对象的对象。

所有ECMAScript函数对象都具有这里定义的[[Call]]内部方法。 另外也是构造函数的ECMAScript函数具有[[Construct]]内部方法。

9.2.1[[Call]] ( thisArgument, argumentsList)#

使用参数thisArgument和argumentsList(一个ECMAScript语言值列表)调用ECMAScript函数对象F的[[Call]]内部方法。 采取以下步骤:

  1. Assert: F is an ECMAScript function object.
  2. If F's [[FunctionKind]] internal slot is "classConstructor", throw a TypeError exception.
  3. Let callerContext be the running execution context.
  4. Let calleeContext be PrepareForOrdinaryCall(F, undefined).
  5. Assert: calleeContext is now the running execution context.
  6. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument).
  7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
  8. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
  9. If result.[[Type]] is return, return NormalCompletion(result.[[Value]]).
  10. ReturnIfAbrupt(result).
  11. Return NormalCompletion(undefined).
Note

当在步骤8中从执行上下文堆栈中删除calleeContext时,如果它被挂起并保留以供可访问的生成器对象稍后恢复,则不能将其消除。

9.2.1.1PrepareForOrdinaryCall ( F, newTarget )#

当使用函数对象F和ECMAScript语言值newTarget调用抽象操作PrepareForOrdinaryCall时,执行以下步骤:

  1. Assert: Type(newTarget) is Undefined or Object.
  2. Let callerContext be the running execution context.
  3. Let calleeContext be a new ECMAScript code execution context.
  4. Set the Function of calleeContext to F.
  5. Let calleeRealm be the value of F's [[Realm]] internal slot.
  6. Set the Realm of calleeContext to calleeRealm.
  7. Set the ScriptOrModule of calleeContext to the value of F's [[ScriptOrModule]] internal slot.
  8. Let localEnv be NewFunctionEnvironment(F, newTarget).
  9. Set the LexicalEnvironment of calleeContext to localEnv.
  10. Set the VariableEnvironment of calleeContext to localEnv.
  11. If callerContext is not already suspended, suspend callerContext.
  12. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
  13. NOTE Any exception objects produced after this point are associated with calleeRealm.
  14. Return calleeContext.

9.2.1.2OrdinaryCallBindThis ( F, calleeContext, thisArgument )#

当抽象操作OrdinaryCallBindThis用函数对象F调用时,执行上下文calleeContext和ECMAScript值为thisArgument,执行以下步骤:

  1. Let thisMode be the value of F's [[ThisMode]] internal slot.
  2. If thisMode is lexical, return NormalCompletion(undefined).
  3. Let calleeRealm be the value of F's [[Realm]] internal slot.
  4. Let localEnv be the LexicalEnvironment of calleeContext.
  5. If thisMode is strict, let thisValue be thisArgument.
  6. Else,
    1. If thisArgument is null or undefined, then
      1. Let globalEnv be calleeRealm.[[GlobalEnv]].
      2. Let globalEnvRec be globalEnv's EnvironmentRecord.
      3. Let thisValue be globalEnvRec.[[GlobalThisValue]].
    2. Else,
      1. Let thisValue be ! ToObject(thisArgument).
      2. NOTE ToObject produces wrapper objects using calleeRealm.
  7. Let envRec be localEnv's EnvironmentRecord.
  8. Assert: The next step never returns an abrupt completion because envRec.[[ThisBindingStatus]] is not "initialized".
  9. Return envRec.BindThisValue(thisValue).

9.2.1.3OrdinaryCallEvaluateBody ( F, argumentsList )#

当使用函数对象F和List argumentsList调用抽象操作OrdinaryCallEvaluateBody时,执行以下步骤:

  1. Perform ? FunctionDeclarationInstantiation(F, argumentsList).
  2. Return the result of EvaluateBody of the parsed code that is the value of F's [[ECMAScriptCode]] internal slot passing F as the argument.

9.2.2[[Construct]] ( argumentsList, newTarget)#

使用参数argumentsList和newTarget调用ECMAScript Function对象F的[[Construct]]内部方法。 argumentsList是可能为空的ECMAScript语言值列表。 采取以下步骤:

  1. Assert: F is an ECMAScript function object.
  2. Assert: Type(newTarget) is Object.
  3. Let callerContext be the running execution context.
  4. Let kind be F's [[ConstructorKind]] internal slot.
  5. If kind is "base", then
    1. Let thisArgument be ? OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%").
  6. Let calleeContext be PrepareForOrdinaryCall(F, newTarget).
  7. Assert: calleeContext is now the running execution context.
  8. If kind is "base", perform OrdinaryCallBindThis(F, calleeContext, thisArgument).
  9. Let constructorEnv be the LexicalEnvironment of calleeContext.
  10. Let envRec be constructorEnv's EnvironmentRecord.
  11. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
  12. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
  13. If result.[[Type]] is return, then
    1. If Type(result.[[Value]]) is Object, return NormalCompletion(result.[[Value]]).
    2. If kind is "base", return NormalCompletion(thisArgument).
    3. If result.[[Value]] is not undefined, throw a TypeError exception.
  14. Else, ReturnIfAbrupt(result).
  15. Return ? envRec.GetThisBinding().

9.2.3FunctionAllocate (functionPrototype, strict, functionKind)#

抽象操作FunctionAllocate需要三个参数functionPrototype,strict和functionKind。 FunctionAllocate执行以下步骤:

  1. Assert: Type(functionPrototype) is Object.
  2. Assert: functionKind is either "normal", "non-constructor" or "generator".
  3. If functionKind is "normal", let needsConstruct be true.
  4. Else, let needsConstruct be false.
  5. If functionKind is "non-constructor", let functionKind be "normal".
  6. Let F be a newly created ECMAScript function object with the internal slots listed in Table 27. All of those internal slots are initialized to undefined.
  7. Set F's essential internal methods to the default ordinary object definitions specified in 9.1.
  8. Set F's [[Call]] internal method to the definition specified in 9.2.1.
  9. If needsConstruct is true, then
    1. Set F's [[Construct]] internal method to the definition specified in 9.2.2.
    2. Set the [[ConstructorKind]] internal slot of F to "base".
  10. Set the [[Strict]] internal slot of F to strict.
  11. Set the [[FunctionKind]] internal slot of F to functionKind.
  12. Set the [[Prototype]] internal slot of F to functionPrototype.
  13. Set the [[Extensible]] internal slot of F to true.
  14. Set the [[Realm]] internal slot of F to the current Realm Record.
  15. Return F.

9.2.4FunctionInitialize (F, kind, ParameterList, Body, Scope)#

抽象操作FunctionInitialize需要参数:一个函数对象 F kind 它是(Normal,Method,Arrow)之一,由ParameterList指定的参数列表生成 ,由 Body 指定的正文生产,Lexical Environment Scope 指定。 FunctionInitialize执行以下步骤:

  1. Assert: F is an extensible object that does not have a length own property.
  2. Let len be the ExpectedArgumentCount of ParameterList.
  3. Perform ! DefinePropertyOrThrow(F, "length", PropertyDescriptor{[[Value]]: len, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}).
  4. Let Strict be the value of the [[Strict]] internal slot of F.
  5. Set the [[Environment]] internal slot of F to the value of Scope.
  6. Set the [[FormalParameters]] internal slot of F to ParameterList.
  7. Set the [[ECMAScriptCode]] internal slot of F to Body.
  8. Set the [[ScriptOrModule]] internal slot of F to GetActiveScriptOrModule().
  9. If kind is Arrow, set the [[ThisMode]] internal slot of F to lexical.
  10. Else if Strict is true, set the [[ThisMode]] internal slot of F to strict.
  11. Else set the [[ThisMode]] internal slot of F to global.
  12. Return F.

9.2.5FunctionCreate (kind, ParameterList, Body, Scope, Strict [ , prototype ])#

抽象操作FunctionCreate需要参数:kind,它是(Normal,Method,Arrow)之一,ParameterList指定的参数列表生成,Body指定的主体生成,Scope指定的Lexical Environment,布尔标志Strict,以及可选地 ,一个对象原型。 FunctionCreate执行以下步骤:

  1. If the prototype argument was not passed, then
    1. Let prototype be the intrinsic object %FunctionPrototype%.
  2. If kind is not Normal, let allocKind be "non-constructor".
  3. Else let allocKind be "normal".
  4. Let F be FunctionAllocate(prototype, Strict, allocKind).
  5. Return FunctionInitialize(F, kind, ParameterList, Body, Scope).

9.2.6GeneratorFunctionCreate (kind, ParameterList, Body, Scope, Strict)#

抽象操作GeneratorFunctionCreate需要参数:kind,它是(Normal,Method)之一,ParameterList指定的参数列表生成,Body指定的主体生成,Scope指定的Lexical Environment以及布尔标志Strict。 GeneratorFunctionCreate执行以下步骤:

  1. Let functionPrototype be the intrinsic object %Generator%.
  2. Let F be FunctionAllocate(functionPrototype, Strict, "generator").
  3. Return FunctionInitialize(F, kind, ParameterList, Body, Scope).

9.2.7AddRestrictedFunctionProperties ( F, realm )#

抽象操作AddRestrictedFunctionProperties被调用与函数对象F和Realm Record realm作为其参数。 它执行以下步骤:

  1. Assert: realm.[[Intrinsics]].[[%ThrowTypeError%]] exists and has been initialized.
  2. Let thrower be realm.[[Intrinsics]].[[%ThrowTypeError%]].
  3. Perform ! DefinePropertyOrThrow(F, "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true}).
  4. Return ! DefinePropertyOrThrow(F, "arguments", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true}).

9.2.7.1%ThrowTypeError% ( )#

%ThrowTypeError%intrinsic是一个匿名的内置函数对象,每个领域定义一次。 当%ThrowTypeError%被调用时,它执行以下步骤:

  1. Throw a TypeError exception.

%ThrowTypeError%函数的[[Extensible]]内部插槽的值为false。

The length property of a %ThrowTypeError% function has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

9.2.8MakeConstructor (F [ , writablePrototype, prototype ])#

抽象操作MakeConstructor需要一个Function参数F,并且可以选择一个Boolean writablePrototype和一个对象原型。 如果提供原型,则假设已经包含值为F的“构造函数”属性(如果需要)。此操作通过执行以下步骤将F转换为构造函数:

  1. Assert: F is an ECMAScript function object.
  2. Assert: F has a [[Construct]] internal method.
  3. Assert: F is an extensible object that does not have a prototype own property.
  4. If the writablePrototype argument was not provided, let writablePrototype be true.
  5. If the prototype argument was not provided, then
    1. Let prototype be ObjectCreate(%ObjectPrototype%).
    2. Perform ! DefinePropertyOrThrow(prototype, "constructor", PropertyDescriptor{[[Value]]: F, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: true }).
  6. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: false}).
  7. Return NormalCompletion(undefined).

9.2.9MakeClassConstructor ( F)#

参数F的抽象操作MakeClassConstructor执行以下步骤:

  1. Assert: F is an ECMAScript function object.
  2. Assert: F's [[FunctionKind]] internal slot is "normal".
  3. Set F's [[FunctionKind]] internal slot to "classConstructor".
  4. Return NormalCompletion(undefined).

9.2.10MakeMethod ( F, homeObject)#

参数F和homeObject的抽象操作MakeMethod通过执行以下步骤将F配置为方法:

  1. Assert: F is an ECMAScript function object.
  2. Assert: Type(homeObject) is Object.
  3. Set the [[HomeObject]] internal slot of F to homeObject.
  4. Return NormalCompletion(undefined).

9.2.11SetFunctionName (F, name [ , prefix ])#

抽象操作SetFunctionName需要一个Function参数F,一个String或Symbol参数名称和可选的String参数前缀。 此操作通过执行以下步骤将名称属性添加到F中:

  1. Assert: F is an extensible object that does not have a name own property.
  2. Assert: Type(name) is either Symbol or String.
  3. Assert: If prefix was passed, then Type(prefix) is String.
  4. If Type(name) is Symbol, then
    1. Let description be name's [[Description]] value.
    2. If description is undefined, let name be the empty String.
    3. Else, let name be the concatenation of "[", description, and "]".
  5. If prefix was passed, then
    1. Let name be the concatenation of prefix, code unit 0x0020 (SPACE), and name.
  6. Return ! DefinePropertyOrThrow(F, "name", PropertyDescriptor{[[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}).

9.2.12FunctionDeclarationInstantiation (func, argumentsList)#

Note 1

当建立一个执行上下文来执行ECMAScript函数时,将创建一个新的函数环境记录,并在该环境记录中实例化每个形式参数的绑定。 函数体中的每个声明也被实例化。 如果函数的形式参数不包含任何默认值初始化函数,那么在与参数相同的环境记录中实例化body声明。 如果默认值参数初始化器存在,则为body声明创建第二个环境记录。 正式参数和函数作为FunctionDeclarationInstantiation的一部分进行初始化。 所有其他绑定在函数体的执行过程中初始化。

FunctionDeclarationInstantiation使用参数func和argumentsList执行如下。 func是正在建立执行上下文的函数对象。

  1. Let calleeContext be the running execution context.
  2. Let env be the LexicalEnvironment of calleeContext.
  3. Let envRec be env's EnvironmentRecord.
  4. Let code be the value of the [[ECMAScriptCode]] internal slot of func.
  5. Let strict be the value of the [[Strict]] internal slot of func.
  6. Let formals be the value of the [[FormalParameters]] internal slot of func.
  7. Let parameterNames be the BoundNames of formals.
  8. If parameterNames has any duplicate entries, let hasDuplicates be true. Otherwise, let hasDuplicates be false.
  9. Let simpleParameterList be IsSimpleParameterList of formals.
  10. Let hasParameterExpressions be ContainsExpression of formals.
  11. Let varNames be the VarDeclaredNames of code.
  12. Let varDeclarations be the VarScopedDeclarations of code.
  13. Let lexicalNames be the LexicallyDeclaredNames of code.
  14. Let functionNames be a new empty List.
  15. Let functionsToInitialize be a new empty List.
  16. For each d in varDeclarations, in reverse list order do
    1. If d is neither a VariableDeclaration or a ForBinding, then
      1. Assert: d is either a FunctionDeclaration or a GeneratorDeclaration.
      2. Let fn be the sole element of the BoundNames of d.
      3. If fn is not an element of functionNames, then
        1. Insert fn as the first element of functionNames.
        2. NOTE If there are multiple FunctionDeclarations or GeneratorDeclarations for the same name, the last declaration is used.
        3. Insert d as the first element of functionsToInitialize.
  17. Let argumentsObjectNeeded be true.
  18. If the value of the [[ThisMode]] internal slot of func is lexical, then
    1. NOTE Arrow functions never have an arguments objects.
    2. Let argumentsObjectNeeded be false.
  19. Else if "arguments" is an element of parameterNames, then
    1. Let argumentsObjectNeeded be false.
  20. Else if hasParameterExpressions is false, then
    1. If "arguments" is an element of functionNames or if "arguments" is an element of lexicalNames, then
      1. Let argumentsObjectNeeded be false.
  21. For each String paramName in parameterNames, do
    1. Let alreadyDeclared be envRec.HasBinding(paramName).
    2. NOTE Early errors ensure that duplicate parameter names can only occur in non-strict functions that do not have parameter default values or rest parameters.
    3. If alreadyDeclared is false, then
      1. Perform ! envRec.CreateMutableBinding(paramName, false).
      2. If hasDuplicates is true, then
        1. Perform ! envRec.InitializeBinding(paramName, undefined).
  22. If argumentsObjectNeeded is true, then
    1. If strict is true or if simpleParameterList is false, then
      1. Let ao be CreateUnmappedArgumentsObject(argumentsList).
    2. Else,
      1. NOTE mapped argument object is only provided for non-strict functions that don't have a rest parameter, any parameter default value initializers, or any destructured parameters.
      2. Let ao be CreateMappedArgumentsObject(func, formals, argumentsList, envRec).
    3. If strict is true, then
      1. Perform ! envRec.CreateImmutableBinding("arguments", false).
    4. Else,
      1. Perform ! envRec.CreateMutableBinding("arguments", false).
    5. Call envRec.InitializeBinding("arguments", ao).
    6. Append "arguments" to parameterNames.
  23. Let iteratorRecord be Record {[[Iterator]]: CreateListIterator(argumentsList), [[Done]]: false}.
  24. If hasDuplicates is true, then
    1. Perform ? IteratorBindingInitialization for formals with iteratorRecord and undefined as arguments.
  25. Else,
    1. Perform ? IteratorBindingInitialization for formals with iteratorRecord and env as arguments.
  26. If hasParameterExpressions is false, then
    1. NOTE Only a single lexical environment is needed for the parameters and top-level vars.
    2. Let instantiatedVarNames be a copy of the List parameterNames.
    3. For each n in varNames, do
      1. If n is not an element of instantiatedVarNames, then
        1. Append n to instantiatedVarNames.
        2. Perform ! envRec.CreateMutableBinding(n, false).
        3. Call envRec.InitializeBinding(n, undefined).
    4. Let varEnv be env.
    5. Let varEnvRec be envRec.
  27. Else,
    1. NOTE A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body.
    2. Let varEnv be NewDeclarativeEnvironment(env).
    3. Let varEnvRec be varEnv's EnvironmentRecord.
    4. Set the VariableEnvironment of calleeContext to varEnv.
    5. Let instantiatedVarNames be a new empty List.
    6. For each n in varNames, do
      1. If n is not an element of instantiatedVarNames, then
        1. Append n to instantiatedVarNames.
        2. Perform ! varEnvRec.CreateMutableBinding(n, false).
        3. If n is not an element of parameterNames or if n is an element of functionNames, let initialValue be undefined.
        4. Else,
          1. Let initialValue be ! envRec.GetBindingValue(n, false).
        5. Call varEnvRec.InitializeBinding(n, initialValue).
        6. NOTE vars whose names are the same as a formal parameter, initially have the same value as the corresponding initialized parameter.
  28. NOTE: Annex B.3.3.1 adds additional steps at this point.
  29. If strict is false, then
    1. Let lexEnv be NewDeclarativeEnvironment(varEnv).
    2. NOTE: Non-strict functions use a separate lexical Environment Record for top-level lexical declarations so that a direct eval can determine whether any var scoped declarations introduced by the eval code conflict with pre-existing top-level lexically scoped declarations. This is not needed for strict functions because a strict direct eval always places all declarations into a new Environment Record.
  30. Else, let lexEnv be varEnv.
  31. Let lexEnvRec be lexEnv's EnvironmentRecord.
  32. Set the LexicalEnvironment of calleeContext to lexEnv.
  33. Let lexDeclarations be the LexicallyScopedDeclarations of code.
  34. For each element d in lexDeclarations do
    1. NOTE A lexically declared name cannot be the same as a function/generator declaration, formal parameter, or a var name. Lexically declared names are only instantiated here but not initialized.
    2. For each element dn of the BoundNames of d do
      1. If IsConstantDeclaration of d is true, then
        1. Perform ! lexEnvRec.CreateImmutableBinding(dn, true).
      2. Else,
        1. Perform ! lexEnvRec.CreateMutableBinding(dn, false).
  35. For each parsed grammar phrase f in functionsToInitialize, do
    1. Let fn be the sole element of the BoundNames of f.
    2. Let fo be the result of performing InstantiateFunctionObject for f with argument lexEnv.
    3. Perform ! varEnvRec.SetMutableBinding(fn, fo, false).
  36. Return NormalCompletion(empty).
Note 2

B.3.3 提供了上述算法的扩展,这是与ECMAScript 2015之前的ECMAScript的Web浏览器实现的向后兼容性所必需的。

Note 3

参数初始化程序可能包含直接eval表达式。 这些evals的任何顶级声明只对eval代码可见(10.2)。 14.1.19描述了这种声明的创建环境。

9.3内置函数对象(Built-in Function Objects)#

在本说明书中定义的内置函数对象可以实现为ECMAScript函数对象(9.2),其行为是使用ECMAScript代码提供的,或者作为实现提供异常函数对象,其行为以其他方式提供。 在这两种情况下,调用这些函数的效果必须符合其规格。 实现还可以提供在本说明书中未定义的附加内置函数对象。

如果一个内置的函数对象被实现为一个异乎寻常的对象,它必须具有9.1中规定的普通对象行为。 所有这些异常的功能对象也有[[Prototype]],[[Extensible]],[[Realm]]和[[ScriptOrModule]]内部插槽。

除非另有说明,否则每个内置函数对象都将%FunctionPrototype%对象作为其[[Prototype]]内部插槽的初始值。

通过算法步骤或其他方法为每个内置函数指定的行为是函数的[[Call]]和[[Construct]]调用的函数体行为的规范。但是,所有内置函数都不支持[[Construct]]调用。对于每个内置函数,当使用[[Call]]调用时,[[Call]] thisArgument提供此值,[[Call]] argumentsList提供命名参数,NewTarget值未定义。当使用[[Construct]]调用时,该值未初始化,[[Construct]] argumentsList提供命名参数,[[Construct]] newTarget参数提供NewTarget值。如果内置函数被实现为ECMAScript函数对象,则该指定的行为必须由作为函数正文的ECMAScript代码实现。 ECMAScript函数对象的内置函数必须是严格的模式函数。如果内置构造函数具有除了抛出TypeError异常之外的任何[[Call]]行为,则必须以不会导致函数的[[FunctionKind]]内部插槽具有该值的方式完成该函数的ECMAScript实现“classConstructor”。

没有标识为构造函数的内置函数对象不会实现[[Construct]]内部方法,除非在特定函数的描述中另有规定。 当内建构造函数被调用为新表达式的一部分时,调用的[[Construct]]内部方法的argumentsList参数提供了内置构造函数的命名参数的值。

不是构造函数的内置函数没有原型属性,除非在特定函数的描述中另有规定。

如果内置函数对象未实现为ECMAScript函数,则必须提供符合以下定义的[[Call]]和[[Construct]]内部方法:

9.3.1[[Call]] ( thisArgument, argumentsList)#

使用参数thisArgument和argumentsList(一个ECMAScript语言值列表)调用内置函数对象F的[[Call]]内部方法。 采取以下步骤:

  1. Let callerContext be the running execution context.
  2. If callerContext is not already suspended, suspend callerContext.
  3. Let calleeContext be a new ECMAScript code execution context.
  4. Set the Function of calleeContext to F.
  5. Let calleeRealm be the value of F's [[Realm]] internal slot.
  6. Set the Realm of calleeContext to calleeRealm.
  7. Set the ScriptOrModule of calleeContext to the value of F's [[ScriptOrModule]] internal slot.
  8. Perform any necessary implementation defined initialization of calleeContext.
  9. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
  10. Let result be the Completion Record that is the result of evaluating F in an implementation defined manner that conforms to the specification of F. thisArgument is the this value, argumentsList provides the named parameters, and the NewTarget value is undefined.
  11. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
  12. Return result.
Note

当calleeContext从执行上下文堆栈中删除时,如果已被暂停并由可访问的生成器对象保留以供稍后恢复,则不能将其删除。

9.3.2[[Construct]] (argumentsList, newTarget)#

内置函数对象F的[[Construct]]内部方法使用参数argumentsList和newTarget进行调用。 执行的步骤与[Call]](见9.3.1)相同,步骤10替换为:

  1. Let result be the Completion Record that is the result of evaluating F in an implementation defined manner that conforms to the specification of F. The this value is uninitialized, argumentsList provides the named parameters, and newTarget provides the NewTarget value.

9.3.3CreateBuiltinFunction (realm, steps, prototype [ , internalSlotsList ])#

抽象操作CreateBuiltinFunction接受arguments realm, prototype, and steps。 可选参数internalSlotsList是必须定义为对象一部分的附加内部插槽的名称列表。 如果未提供列表,则使用新的空列表。 CreateBuiltinFunction返回通过以下步骤创建的内置函数对象:

  1. Assert: realm is a Realm Record.
  2. Assert: steps is either a set of algorithm steps or other definition of a function's behaviour provided in this specification.
  3. Let func be a new built-in function object that when called performs the action described by steps. The new function object has internal slots whose names are the elements of internalSlotsList. The initial value of each of those internal slots is undefined.
  4. Set the [[Realm]] internal slot of func to realm.
  5. Set the [[Prototype]] internal slot of func to prototype.
  6. Set the [[Extensible]] internal slot of func to true.
  7. Set the [[ScriptOrModule]] internal slot of func to null.
  8. Return func.

在本规范中定义的每个内置函数都是通过调用CreateBuiltinFunction抽象操作来创建的,除非另有说明。

9.4内置非普通对象内部方法和插槽(Built-in Exotic Object Internal Methods and Slots)#

此规范定义了几种内置的非普通对象。 除了一些具体情况外,这些物体通常表现得与普通物体相似。 以下非普通对象使用普通对象内部方法,除非以下明确指定:

9.4.1绑定函数非普通对象(Bound Function Exotic Objects)#

绑定函数是一个外来对象,它包装另一个函数对象。 绑定函数是可调用的(它具有[[Call]]内部方法,并且可以具有[[Construct]]内部方法)。 调用绑定函数通常会调用其包装函数。

绑定函数对象没有表27中定义的ECMAScript函数对象的内部插槽,而是在表28中定义了内部插槽。

Table 28: Internal Slots of Exotic Bound Function Objects
Internal Slot Type Description
[[BoundTargetFunction]] Callable Object 包装的函数对象。
[[BoundThis]] Any 当调用包装函数时,始终作为this值传递的值。
[[BoundArguments]] List of Any 一个值的列表,其元素被用作对包装函数的任何调用的第一个参数。

绑定函数对象提供9.1中规定的所有内部方法。 但是,它们对函数对象的基本内部方法使用以下定义。

9.4.1.1[[Call]] ( thisArgument, argumentsList)#

当使用bind函数创建的异常绑定函数对象的[[Call]]内部方法使用参数thisArgument和argumentsList(一个ECMAScript语言值列表)调用时,执行以下步骤:

  1. Let target be the value of F's [[BoundTargetFunction]] internal slot.
  2. Let boundThis be the value of F's [[BoundThis]] internal slot.
  3. Let boundArgs be the value of F's [[BoundArguments]] internal slot.
  4. Let args be a new list containing the same values as the list boundArgs in the same order followed by the same values as the list argumentsList in the same order.
  5. Return ? Call(target, boundThis, args).

9.4.1.2[[Construct]] (argumentsList, newTarget)#

当异构绑定函数对象的[[Construct]]内部方法使用bind函数创建的F被调用时带有argumentsList和newTarget的参数列表,执行以下步骤:

  1. Let target be the value of F's [[BoundTargetFunction]] internal slot.
  2. Assert: target has a [[Construct]] internal method.
  3. Let boundArgs be the value of F's [[BoundArguments]] internal slot.
  4. Let args be a new list containing the same values as the list boundArgs in the same order followed by the same values as the list argumentsList in the same order.
  5. If SameValue(F, newTarget) is true, let newTarget be target.
  6. Return ? Construct(target, args, newTarget).

9.4.1.3BoundFunctionCreate (targetFunction, boundThis, boundArgs)#

带有参数targetFunction,boundThis和boundArgs的抽象操作BoundFunctionCreate用于指定创建新的Bound Function异常对象。 它执行以下步骤:

  1. Assert: Type(targetFunction) is Object.
  2. Let proto be ? targetFunction.[[GetPrototypeOf]]().
  3. Let obj be a newly created object.
  4. Set obj's essential internal methods to the default ordinary object definitions specified in 9.1.
  5. Set the [[Call]] internal method of obj as described in 9.4.1.1.
  6. If targetFunction has a [[Construct]] internal method, then
    1. Set the [[Construct]] internal method of obj as described in 9.4.1.2.
  7. Set the [[Prototype]] internal slot of obj to proto.
  8. Set the [[Extensible]] internal slot of obj to true.
  9. Set the [[BoundTargetFunction]] internal slot of obj to targetFunction.
  10. Set the [[BoundThis]] internal slot of obj to the value of boundThis.
  11. Set the [[BoundArguments]] internal slot of obj to boundArgs.
  12. Return obj.

9.4.2数组非普通对象(Array Exotic Objects)#

Array对象是一个异乎寻常的对象,可以对数组索引属性键进行特殊处理(见6.1.7)。属性名称是数组索引的属性也称为元素。每个Array对象都有一个length属性,其值始终是小于232的非负整数。length属性的值在数值上大于名称为数组索引的每个属性的名称;每当创建或更改Array对象的一个属性时,根据需要调整其他属性以维护此不变量。具体来说,每当添加名称为数组索引的自己的属性时,如果需要,更改length属性的值是该数组索引的数字值以上的值;并且每当更改length属性的值时,将删除其值不小于新长度的名称为数组索引的每个自身属性。此约束仅适用于Array对象的自己的属性,并且不受长度或数组索引属性的影响,该属性可能从其原型中继承。

Note

字符串属性名称P是数组索引,当且仅当ToString(ToUint32(P))等于P且ToUint32(P)不等于232-1时。

数组非普通对象始终具有名为“length”的不可配置属性.

A数组非普通对象为[[DefineOwnProperty]]内部方法提供了一个替代定义。 除了内部方法外,Array异常对象提供了9.1中规定的所有其他基本内部方法。

9.4.2.1[[DefineOwnProperty]] ( P, Desc)#

当使用属性键P和属性描述符Desc调用Array非普通对象A的[[DefineOwnProperty]]内部方法时,将执行以下步骤:

  1. Assert: IsPropertyKey(P) is true.
  2. If P is "length", then
    1. Return ? ArraySetLength(A, Desc).
  3. Else if P is an array index, then
    1. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
    2. Assert: oldLenDesc will never be undefined or an accessor descriptor because Array objects are created with a length data property that cannot be deleted or reconfigured.
    3. Let oldLen be oldLenDesc.[[Value]].
    4. Let index be ! ToUint32(P).
    5. If indexoldLen and oldLenDesc.[[Writable]] is false, return false.
    6. Let succeeded be ! OrdinaryDefineOwnProperty(A, P, Desc).
    7. If succeeded is false, return false.
    8. If indexoldLen, then
      1. Set oldLenDesc.[[Value]] to index + 1.
      2. Let succeeded be OrdinaryDefineOwnProperty(A, "length", oldLenDesc).
      3. Assert: succeeded is true.
    9. Return true.
  4. Return OrdinaryDefineOwnProperty(A, P, Desc).

9.4.2.2ArrayCreate (length [ , proto ])#

带有参数长度(0或正整数)和可选参数proto的抽象操作ArrayCreate用于指定新的Array异构对象的创建。 它执行以下步骤:

  1. Assert: length is an integer Number ≥ 0.
  2. If length is -0, let length be +0.
  3. If length>232-1, throw a RangeError exception.
  4. If the proto argument was not passed, let proto be the intrinsic object %ArrayPrototype%.
  5. Let A be a newly created Array exotic object.
  6. Set A's essential internal methods except for [[DefineOwnProperty]] to the default ordinary object definitions specified in 9.1.
  7. Set the [[DefineOwnProperty]] internal method of A as specified in 9.4.2.1.
  8. Set the [[Prototype]] internal slot of A to proto.
  9. Set the [[Extensible]] internal slot of A to true.
  10. Perform ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor{[[Value]]: length, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  11. Return A.

9.4.2.3ArraySpeciesCreate (originalArray, length)#

使用参数originalArray和length的抽象操作ArraySpeciesCreate用于指定使用从originalArray派生的构造函数来创建新的Array对象。 它执行以下步骤:

  1. Assert: length is an integer Number ≥ 0.
  2. If length is -0, let length be +0.
  3. Let C be undefined.
  4. Let isArray be ? IsArray(originalArray).
  5. If isArray is true, then
    1. Let C be ? Get(originalArray, "constructor").
    2. If IsConstructor(C) is true, then
      1. Let thisRealm be the current Realm Record.
      2. Let realmC be ? GetFunctionRealm(C).
      3. If thisRealm and realmC are not the same Realm Record, then
        1. If SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) is true, let C be undefined.
    3. If Type(C) is Object, then
      1. Let C be ? Get(C, @@species).
      2. If C is null, let C be undefined.
  6. If C is undefined, return ? ArrayCreate(length).
  7. If IsConstructor(C) is false, throw a TypeError exception.
  8. Return ? Construct(C, « length »).
Note

如果originalArray是使用标准内置的Array构造函数创建的,而不是运行执行上下文的领域,则使用正在运行的执行上下文的领域创建一个新的Array。 这维护与Web浏览器的兼容性,该浏览器历来对于现在使用ArraySpeciesCreate定义的Array.prototype方法具有这种行为。

9.4.2.4ArraySetLength (A, Desc)#

当使用Array非普通对象A和Property Descriptor Desc调用抽象操作ArraySetLength时,执行以下步骤:

  1. If the [[Value]] field of Desc is absent, then
    1. Return OrdinaryDefineOwnProperty(A, "length", Desc).
  2. Let newLenDesc be a copy of Desc.
  3. Let newLen be ? ToUint32(Desc.[[Value]]).
  4. Let numberLen be ? ToNumber(Desc.[[Value]]).
  5. If newLennumberLen, throw a RangeError exception.
  6. Set newLenDesc.[[Value]] to newLen.
  7. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
  8. Assert: oldLenDesc will never be undefined or an accessor descriptor because Array objects are created with a length data property that cannot be deleted or reconfigured.
  9. Let oldLen be oldLenDesc.[[Value]].
  10. If newLenoldLen, then
    1. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc).
  11. If oldLenDesc.[[Writable]] is false, return false.
  12. If newLenDesc.[[Writable]] is absent or has the value true, let newWritable be true.
  13. Else,
    1. Need to defer setting the [[Writable]] attribute to false in case any elements cannot be deleted.
    2. Let newWritable be false.
    3. Set newLenDesc.[[Writable]] to true.
  14. Let succeeded be ! OrdinaryDefineOwnProperty(A, "length", newLenDesc).
  15. If succeeded is false, return false.
  16. While newLen < oldLen repeat,
    1. Set oldLen to oldLen - 1.
    2. Let deleteSucceeded be ! A.[[Delete]](! ToString(oldLen)).
    3. If deleteSucceeded is false, then
      1. Set newLenDesc.[[Value]] to oldLen + 1.
      2. If newWritable is false, set newLenDesc.[[Writable]] to false.
      3. Let succeeded be ! OrdinaryDefineOwnProperty(A, "length", newLenDesc).
      4. Return false.
  17. If newWritable is false, then
    1. Return OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor{[[Writable]]: false}). This call will always return true.
  18. Return true.
Note

在步骤3和4中,如果Desc.[[Value]]是一个对象,那么它的valueOf方法被调用两次。 这是从本规范的第二版开始的具有此效果的传统行为。

9.4.3字符串非普通对象(String Exotic Objects)#

String对象是一个异乎寻常的对象,它封装了一个String值,并且公开了与String值的各个代码单元元素相对应的虚拟整数索引数据属性。 Exotic String对象始终具有名为“length”的数据属性,其值是封装的String值中的代码单元元素的数量。 代码单元数据属性和“length”属性都是不可写和不可配置的。

非普通字符串对象与普通对象具有相同的内部插槽。 它们还有一个[[StringData]]内部插槽。

Exotic String对象为以下内部方法提供了替代定义。 下面没有定义的所有其他异常String对象的基本内部方法都是在9.1中指定的。

9.4.3.1[[GetOwnProperty]] ( P )#

当使用属性键P调用String对象S的[[GetOwnProperty]]内部方法时,将执行以下步骤:

  1. Assert: IsPropertyKey(P) is true.
  2. Let desc be OrdinaryGetOwnProperty(S, P).
  3. If desc is not undefined, return desc.
  4. If Type(P) is not String, return undefined.
  5. Let index be ! CanonicalNumericIndexString(P).
  6. If index is undefined, return undefined.
  7. If IsInteger(index) is false, return undefined.
  8. If index = -0, return undefined.
  9. Let str be the String value of the [[StringData]] internal slot of S.
  10. Let len be the number of elements in str.
  11. If index < 0 or lenindex, return undefined.
  12. Let resultStr be a String value of length 1, containing one code unit from str, specifically the code unit at index index.
  13. Return a PropertyDescriptor{[[Value]]: resultStr, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false}.

9.4.3.2[[OwnPropertyKeys]] ( )#

当调用String非普通对象O的[[OwnPropertyKeys]]内部方法时,将执行以下步骤:

  1. Let keys be a new empty List.
  2. Let str be the String value of the [[StringData]] internal slot of O.
  3. Let len be the number of elements in str.
  4. For each integer i starting with 0 such that i < len, in ascending order,
    1. Add ! ToString(i) as the last element of keys.
  5. For each own property key P of O such that P is an integer index and ToInteger(P) ≥ len, in ascending numeric index order,
    1. Add P as the last element of keys.
  6. For each own property key P of O such that Type(P) is String and P is not an integer index, in ascending chronological order of property creation,
    1. Add P as the last element of keys.
  7. For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation,
    1. Add P as the last element of keys.
  8. Return keys.

9.4.3.3StringCreate ( value, prototype)#

带有参数value和prototype的抽象操作StringCreate用于指定新的非普通String对象的创建。 它执行以下步骤:

  1. Assert: Type(value) is String.
  2. Let S be a newly created String exotic object.
  3. Set the [[StringData]] internal slot of S to value.
  4. Set S's essential internal methods to the default ordinary object definitions specified in 9.1.
  5. Set the [[GetOwnProperty]] internal method of S as specified in 9.4.3.1.
  6. Set the [[OwnPropertyKeys]] internal method of S as specified in 9.4.3.2.
  7. Set the [[Prototype]] internal slot of S to prototype.
  8. Set the [[Extensible]] internal slot of S to true.
  9. Let length be the number of code unit elements in value.
  10. Perform ! DefinePropertyOrThrow(S, "length", PropertyDescriptor{[[Value]]: length, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }).
  11. Return S.

9.4.4Arguments非普通对象(Arguments Exotic Objects)#

大多数ECMAScript函数使参数对象可用于其代码。 根据函数定义的特性,其参数对象既可以是普通对象,也可以是非普通对象。 参数非普通对象是一个非普通对象,其数组索引属性映射到其关联的ECMAScript函数的调用的形式参数绑定。

参数非普通的对象与普通对象具有相同的内部插槽。 它们还有一个[[ParameterMap]]内部插槽。 普通参数对象还有一个[[ParameterMap]]内部插槽,其值始终未定义。 对于普通参数对象,[[ParameterMap]]内部插槽仅由Object.prototype.toString(19.1.3.6)用于标识它们。

参数异常对象为以下内部方法提供了替代定义。 所有其他非普通参数对象反映了以下未定义的基本内部方法,如9.1中所述

Note 1

对于非严格函数,其数值名称小于相应函数对象的形式参数数的参数对象的整数索引数据属性最初与函数执行上下文中的相应参数绑定共享其值。 这意味着更改属性会更改参数绑定的相应值,反之亦然。 如果这样的属性被删除然后被重新定义,或者该属性被改变为访问器属性,则该对应关系被破坏。 对于严格模式函数,参数对象属性的值只是传递给函数的参数的一个副本,并且属性值和形式参数值之间没有动态链接。

Note 2

ParameterMap对象及其属性值用作指定参数绑定对象的参数的设备。 ParameterMap对象和作为其属性值的对象不能从ECMAScript代码直接观察到。 ECMAScript实现不需要实际创建或使用这样的对象来实现指定的语义。

Note 3

用于严格模式函数的Arguments定义了名为“caller”和“callee”的不可配置访问器属性,它在访问时引发TypeError异常。 callee属性对于非严格功能具有更具体的含义,caller属性历史上被一些ECMAScript实现提供为实现定义的扩展。 存在这些属性的严格模式定义,以确保它们都不以任何其他方式通过符合ECMAScript实现来定义。

9.4.4.1[[GetOwnProperty]] (P)#

使用属性键P调用参数非普通对象的[[GetOwnProperty]]内部方法执行以下步骤:

  1. Let args be the arguments object.
  2. Let desc be OrdinaryGetOwnProperty(args, P).
  3. If desc is undefined, return desc.
  4. Let map be the value of the [[ParameterMap]] internal slot of the arguments object.
  5. Let isMapped be ! HasOwnProperty(map, P).
  6. If the value of isMapped is true, then
    1. Set desc.[[Value]] to Get(map, P).
  7. If IsDataDescriptor(desc) is true and P is "caller" and desc.[[Value]] is a strict mode Function object, throw a TypeError exception.
  8. Return desc.

如果一个实现不为参数异构对象提供内置的caller属性,则必须跳过该算法的第7步。

9.4.4.2[[DefineOwnProperty]] (P, Desc)#

使用属性键P和属性描述符Desc调用时,参数非普通对象的[[DefineOwnProperty]]内部方法执行以下步骤:

  1. Let args be the arguments object.
  2. Let map be the value of the [[ParameterMap]] internal slot of the arguments object.
  3. Let isMapped be HasOwnProperty(map, P).
  4. Let newArgDesc be Desc.
  5. If isMapped is true and IsDataDescriptor(Desc) is true, then
    1. If Desc.[[Value]] is not present and Desc.[[Writable]] is present and its value is false, then
      1. Let newArgDesc be a copy of Desc.
      2. Set newArgDesc.[[Value]] to Get(map, P).
  6. Let allowed be ? OrdinaryDefineOwnProperty(args, P, newArgDesc).
  7. If allowed is false, return false.
  8. If the value of isMapped is true, then
    1. If IsAccessorDescriptor(Desc) is true, then
      1. Call map.[[Delete]](P).
    2. Else,
      1. If Desc.[[Value]] is present, then
        1. Let setStatus be Set(map, P, Desc.[[Value]], false).
        2. Assert: setStatus is true because formal parameters mapped by argument objects are always writable.
      2. If Desc.[[Writable]] is present and its value is false, then
        1. Call map.[[Delete]](P).
  9. Return true.

9.4.4.3[[Get]] (P, Receiver)#

使用属性键P和ECMAScript语言值调用时,arguments非普通对象的[[Get]]内部方法执行以下步骤:

  1. Let args be the arguments object.
  2. Let map be the value of the [[ParameterMap]] internal slot of the arguments object.
  3. Let isMapped be ! HasOwnProperty(map, P).
  4. If the value of isMapped is false, then
    1. Return ? OrdinaryGet(args, P, Receiver).
  5. Else map contains a formal parameter mapping for P,
    1. Return Get(map, P).

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

使用属性键P,值V和ECMAScript语言值调用时,arguments非普通对象的[[Set]]内部方法Receiver执行以下步骤:

  1. Let args be the arguments object.
  2. If SameValue(args, Receiver) is false, then
    1. Let isMapped be false.
  3. Else,
    1. Let map be the value of the [[ParameterMap]] internal slot of the arguments object.
    2. Let isMapped be ! HasOwnProperty(map, P).
  4. If isMapped is true, then
    1. Let setStatus be Set(map, P, V, false).
    2. Assert: setStatus is true because formal parameters mapped by argument objects are always writable.
  5. Return ? OrdinarySet(args, P, V, Receiver).

9.4.4.5[[HasProperty]] ( P )#

使用属性键P调用arguments非普通对象的[[HasProperty]]内部方法时,执行以下步骤:

  1. Let args be the arguments object.
  2. If P is "caller", then
    1. Let desc be ! OrdinaryGetOwnProperty(args, P).
    2. If IsDataDescriptor(desc) is true, return true.
  3. Return ? OrdinaryHasProperty(args, P).

如果一个实现不为argument非普通对象提供内置的调用者属性,则必须跳过该算法的第2步。

9.4.4.6[[Delete]] (P)#

The [[Delete]] internal method of an arguments exotic object when called with a property key P performs the following steps:

  1. Let args be the arguments object.
  2. Let map be the value of the [[ParameterMap]] internal slot of args.
  3. Let isMapped be ! HasOwnProperty(map, P).
  4. Let result be ? OrdinaryDelete(args, P).
  5. If result is true and the value of isMapped is true, then
    1. Call map.[[Delete]](P).
  6. Return result.

9.4.4.7CreateUnmappedArgumentsObject (argumentsList)#

The abstract operation CreateUnmappedArgumentsObject called with an argument argumentsList performs the following steps:

  1. Let len be the number of elements in argumentsList.
  2. Let obj be ObjectCreate(%ObjectPrototype%, « [[ParameterMap]] »).
  3. Set obj's [[ParameterMap]] internal slot to undefined.
  4. Perform DefinePropertyOrThrow(obj, "length", PropertyDescriptor{[[Value]]: len, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}).
  5. Let index be 0.
  6. Repeat while index < len,
    1. Let val be argumentsList[index].
    2. Perform CreateDataProperty(obj, ! ToString(index), val).
    3. Let index be index + 1.
  7. Perform ! DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor {[[Value]]: %ArrayProto_values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}).
  8. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor {[[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}).
  9. Perform ! DefinePropertyOrThrow(obj, "caller", PropertyDescriptor {[[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}).
  10. Return obj.

9.4.4.8CreateMappedArgumentsObject ( func, formals, argumentsList, env )#

The abstract operation CreateMappedArgumentsObject is called with object func, parsed grammar phrase formals, List argumentsList, and Environment Record env. The following steps are performed:

  1. Assert: formals does not contain a rest parameter, any binding patterns, or any initializers. It may contain duplicate identifiers.
  2. Let len be the number of elements in argumentsList.
  3. Let obj be a newly created arguments exotic object with a [[ParameterMap]] internal slot.
  4. Set the [[GetOwnProperty]] internal method of obj as specified in 9.4.4.1.
  5. Set the [[DefineOwnProperty]] internal method of obj as specified in 9.4.4.2.
  6. Set the [[Get]] internal method of obj as specified in 9.4.4.3.
  7. Set the [[Set]] internal method of obj as specified in 9.4.4.4.
  8. Set the [[HasProperty]] internal method of obj as specified in 9.4.4.5.
  9. Set the [[Delete]] internal method of obj as specified in 9.4.4.6.
  10. Set the remainder of obj's essential internal methods to the default ordinary object definitions specified in 9.1.
  11. Set the [[Prototype]] internal slot of obj to %ObjectPrototype%.
  12. Set the [[Extensible]] internal slot of obj to true.
  13. Let map be ObjectCreate(null).
  14. Set the [[ParameterMap]] internal slot of obj to map.
  15. Let parameterNames be the BoundNames of formals.
  16. Let numberOfParameters be the number of elements in parameterNames.
  17. Let index be 0.
  18. Repeat while index < len,
    1. Let val be argumentsList[index].
    2. Perform CreateDataProperty(obj, ! ToString(index), val).
    3. Let index be index + 1.
  19. Perform DefinePropertyOrThrow(obj, "length", PropertyDescriptor{[[Value]]: len, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}).
  20. Let mappedNames be a new empty List.
  21. Let index be numberOfParameters - 1.
  22. Repeat while index ≥ 0,
    1. Let name be parameterNames[index].
    2. If name is not an element of mappedNames, then
      1. Add name as an element of the list mappedNames.
      2. If index < len, then
        1. Let g be MakeArgGetter(name, env).
        2. Let p be MakeArgSetter(name, env).
        3. Perform map.[[DefineOwnProperty]](! ToString(index), PropertyDescriptor{[[Set]]: p, [[Get]]: g, [[Enumerable]]: false, [[Configurable]]: true}).
    3. Let index be index - 1.
  23. Perform ! DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor {[[Value]]: %ArrayProto_values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}).
  24. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor {[[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}).
  25. Return obj.

9.4.4.8.1MakeArgGetter ( name, env)#

The abstract operation MakeArgGetter called with String name and Environment Record env creates a built-in function object that when executed returns the value bound for name in env. It performs the following steps:

  1. Let realm be the current Realm Record.
  2. Let steps be the steps of an ArgGetter function as specified below.
  3. Let getter be CreateBuiltinFunction(realm, steps, %FunctionPrototype%, « [[Name]], [[Env]] »).
  4. Set getter's [[Name]] internal slot to name.
  5. Set getter's [[Env]] internal slot to env.
  6. Return getter.

An ArgGetter function is an anonymous built-in function with [[Name]] and [[Env]] internal slots. When an ArgGetter function f that expects no arguments is called it performs the following steps:

  1. Let name be the value of f's [[Name]] internal slot.
  2. Let env be the value of f's [[Env]] internal slot.
  3. Return env.GetBindingValue(name, false).
Note

ArgGetter functions are never directly accessible to ECMAScript code.

9.4.4.8.2MakeArgSetter ( name, env)#

The abstract operation MakeArgSetter called with String name and Environment Record env creates a built-in function object that when executed sets the value bound for name in env. It performs the following steps:

  1. Let realm be the current Realm Record.
  2. Let steps be the steps of an ArgSetter function as specified below.
  3. Let setter be CreateBuiltinFunction(realm, steps, %FunctionPrototype%, « [[Name]], [[Env]] »).
  4. Set setter's [[Name]] internal slot to name.
  5. Set setter's [[Env]] internal slot to env.
  6. Return setter.

An ArgSetter function is an anonymous built-in function with [[Name]] and [[Env]] internal slots. When an ArgSetter function f is called with argument value it performs the following steps:

  1. Let name be the value of f's [[Name]] internal slot.
  2. Let env be the value of f's [[Env]] internal slot.
  3. Return env.SetMutableBinding(name, value, false).
Note

ArgSetter functions are never directly accessible to ECMAScript code.

9.4.5整数索引非普通对象(Integer Indexed Exotic Objects)#

整数索引对象是一个非普通对象,它执行整数索引属性键的特殊处理。

整数索引非普通对象具有与普通对象相同的内部插槽,另外还有[[BeenArrayBuffer]],[[ArrayLength]],[[ByteOffset]]和[[TypedArrayName]]内部插槽。

整数索引的非普通对象为以下内部方法提供了替代定义。 所有其他整数索引的非普通对象的基本内部方法未在下面定义如9.1所述。

9.4.5.1[[GetOwnProperty]] ( P )#

When the [[GetOwnProperty]] internal method of an Integer Indexed exotic object O is called with property key P, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. Assert: O is an Object that has a [[ViewedArrayBuffer]] internal slot.
  3. If Type(P) is String, then
    1. Let numericIndex be ! CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, then
      1. Let value be ? IntegerIndexedElementGet(O, numericIndex).
      2. If value is undefined, return undefined.
      3. Return a PropertyDescriptor{[[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false}.
  4. Return OrdinaryGetOwnProperty(O, P).

9.4.5.2[[HasProperty]](P)#

When the [[HasProperty]] internal method of an Integer Indexed exotic object O is called with property key P, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. Assert: O is an Object that has a [[ViewedArrayBuffer]] internal slot.
  3. If Type(P) is String, then
    1. Let numericIndex be ! CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, then
      1. Let buffer be the value of O's [[ViewedArrayBuffer]] internal slot.
      2. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
      3. If IsInteger(numericIndex) is false, return false.
      4. If numericIndex = -0, return false.
      5. If numericIndex < 0, return false.
      6. If numericIndex ≥ the value of O's [[ArrayLength]] internal slot, return false.
      7. Return true.
  4. Return ? OrdinaryHasProperty(O, P).

9.4.5.3[[DefineOwnProperty]] ( P, Desc)#

When the [[DefineOwnProperty]] internal method of an Integer Indexed exotic object O is called with property key P, and Property Descriptor Desc, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. Assert: O is an Object that has a [[ViewedArrayBuffer]] internal slot.
  3. If Type(P) is String, then
    1. Let numericIndex be ! CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, then
      1. If IsInteger(numericIndex) is false, return false.
      2. Let intIndex be numericIndex.
      3. If intIndex = -0, return false.
      4. If intIndex < 0, return false.
      5. Let length be the value of O's [[ArrayLength]] internal slot.
      6. If intIndexlength, return false.
      7. If IsAccessorDescriptor(Desc) is true, return false.
      8. If Desc has a [[Configurable]] field and if Desc.[[Configurable]] is true, return false.
      9. If Desc has an [[Enumerable]] field and if Desc.[[Enumerable]] is false, return false.
      10. If Desc has a [[Writable]] field and if Desc.[[Writable]] is false, return false.
      11. If Desc has a [[Value]] field, then
        1. Let value be Desc.[[Value]].
        2. Return ? IntegerIndexedElementSet(O, intIndex, value).
      12. Return true.
  4. Return OrdinaryDefineOwnProperty(O, P, Desc).

9.4.5.4[[Get]] (P, Receiver)#

When the [[Get]] internal method of an Integer Indexed exotic object O is called with property key P and ECMAScript language value Receiver, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. If Type(P) is String, then
    1. Let numericIndex be ! CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, then
      1. Return ? IntegerIndexedElementGet(O, numericIndex).
  3. Return ? OrdinaryGet(O, P, Receiver).

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

When the [[Set]] internal method of an Integer Indexed exotic object O is called with property key P, value V, and ECMAScript language value Receiver, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. If Type(P) is String, then
    1. Let numericIndex be ! CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, then
      1. Return ? IntegerIndexedElementSet(O, numericIndex, V).
  3. Return ? OrdinarySet(O, P, V, Receiver).

9.4.5.6[[OwnPropertyKeys]] ()#

When the [[OwnPropertyKeys]] internal method of an Integer Indexed exotic object O is called, the following steps are taken:

  1. Let keys be a new empty List.
  2. Assert: O is an Object that has [[ViewedArrayBuffer]], [[ArrayLength]], [[ByteOffset]], and [[TypedArrayName]] internal slots.
  3. Let len be the value of O's [[ArrayLength]] internal slot.
  4. For each integer i starting with 0 such that i < len, in ascending order,
    1. Add ! ToString(i) as the last element of keys.
  5. For each own property key P of O such that Type(P) is String and P is not an integer index, in ascending chronological order of property creation
    1. Add P as the last element of keys.
  6. For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation
    1. Add P as the last element of keys.
  7. Return keys.

9.4.5.7IntegerIndexedObjectCreate (prototype, internalSlotsList)#

The abstract operation IntegerIndexedObjectCreate with arguments prototype and internalSlotsList is used to specify the creation of new Integer Indexed exotic objects. The argument internalSlotsList is a List of the names of additional internal slots that must be defined as part of the object. IntegerIndexedObjectCreate performs the following steps:

  1. Assert: internalSlotsList contains the names [[ViewedArrayBuffer]], [[ArrayLength]], [[ByteOffset]], and [[TypedArrayName]].
  2. Let A be a newly created object with an internal slot for each name in internalSlotsList.
  3. Set A's essential internal methods to the default ordinary object definitions specified in 9.1.
  4. Set the [[GetOwnProperty]] internal method of A as specified in 9.4.5.1.
  5. Set the [[HasProperty]] internal method of A as specified in 9.4.5.2.
  6. Set the [[DefineOwnProperty]] internal method of A as specified in 9.4.5.3.
  7. Set the [[Get]] internal method of A as specified in 9.4.5.4.
  8. Set the [[Set]] internal method of A as specified in 9.4.5.5.
  9. Set the [[OwnPropertyKeys]] internal method of A as specified in 9.4.5.6.
  10. Set the [[Prototype]] internal slot of A to prototype.
  11. Set the [[Extensible]] internal slot of A to true.
  12. Return A.

9.4.5.8IntegerIndexedElementGet ( O, index )#

The abstract operation IntegerIndexedElementGet with arguments O and index performs the following steps:

  1. Assert: Type(index) is Number.
  2. Assert: O is an Object that has [[ViewedArrayBuffer]], [[ArrayLength]], [[ByteOffset]], and [[TypedArrayName]] internal slots.
  3. Let buffer be the value of O's [[ViewedArrayBuffer]] internal slot.
  4. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  5. If IsInteger(index) is false, return undefined.
  6. If index = -0, return undefined.
  7. Let length be the value of O's [[ArrayLength]] internal slot.
  8. If index < 0 or indexlength, return undefined.
  9. Let offset be the value of O's [[ByteOffset]] internal slot.
  10. Let arrayTypeName be the String value of O's [[TypedArrayName]] internal slot.
  11. Let elementSize be the Number value of the Element Size value specified in Table 50 for arrayTypeName.
  12. Let indexedPosition be (index × elementSize) + offset.
  13. Let elementType be the String value of the Element Type value in Table 50 for arrayTypeName.
  14. Return GetValueFromBuffer(buffer, indexedPosition, elementType).

9.4.5.9IntegerIndexedElementSet ( O, index, value )#

The abstract operation IntegerIndexedElementSet with arguments O, index, and value performs the following steps:

  1. Assert: Type(index) is Number.
  2. Assert: O is an Object that has [[ViewedArrayBuffer]], [[ArrayLength]], [[ByteOffset]], and [[TypedArrayName]] internal slots.
  3. Let numValue be ? ToNumber(value).
  4. Let buffer be the value of O's [[ViewedArrayBuffer]] internal slot.
  5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  6. If IsInteger(index) is false, return false.
  7. If index = -0, return false.
  8. Let length be the value of O's [[ArrayLength]] internal slot.
  9. If index < 0 or indexlength, return false.
  10. Let offset be the value of O's [[ByteOffset]] internal slot.
  11. Let arrayTypeName be the String value of O's [[TypedArrayName]] internal slot.
  12. Let elementSize be the Number value of the Element Size value specified in Table 50 for arrayTypeName.
  13. Let indexedPosition be (index × elementSize) + offset.
  14. Let elementType be the String value of the Element Type value in Table 50 for arrayTypeName.
  15. Perform SetValueInBuffer(buffer, indexedPosition, elementType, numValue).
  16. Return true.

9.4.6模块命名空间非普通对象(Module Namespace Exotic Objects)#

模块命名空间对象是一个非普通对象,暴露了从ECMAScript模块导出的绑定(见15.2.3)。 模块命名空间非普通对象的String键控自己的属性和Module导出的绑定名称之间有一一对应的关系。 导出的绑定包括使用export * export项间接导出的任何绑定。 每个String值自己的属性键是相应导出的绑定名称的StringValue。 这些是模块命名空间非普通对象的唯一的String键控属性。 每个这样的属性都有属性{[Writable]]:true,[[Enumerable]]:true,[[Configurable]]:false}。 模块命名空间对象不可扩展。

模块命名空间对象具有表29中定义的内部插槽。

Table 29: Internal Slots of Module Namespace Exotic Objects
Internal Slot Type Description
[[Module]] Module Record The Module Record whose exports this namespace exposes.
[[Exports]] List of String 一个列表,其中包含作为该对象的属性公开的导出名称的String值。列表被排序好像使用SortCompare作为comparefn使用Array.prototype.sort对这些String值的数组进行排序。

模块命名空间非正常对象为所有内部方法提供了替代定义。

9.4.6.1[[GetPrototypeOf]] ( )#

When the [[GetPrototypeOf]] internal method of a module namespace exotic object O is called, the following steps are taken:

  1. Return null.

9.4.6.2[[SetPrototypeOf]] (V)#

When the [[SetPrototypeOf]] internal method of a module namespace exotic object O is called with argument V, the following steps are taken:

  1. Assert: Either Type(V) is Object or Type(V) is Null.
  2. Return false.

9.4.6.3[[IsExtensible]] ( )#

When the [[IsExtensible]] internal method of a module namespace exotic object O is called, the following steps are taken:

  1. Return false.

9.4.6.4[[PreventExtensions]] ( )#

When the [[PreventExtensions]] internal method of a module namespace exotic object O is called, the following steps are taken:

  1. Return true.

9.4.6.5[[GetOwnProperty]] (P)#

When the [[GetOwnProperty]] internal method of a module namespace exotic object O is called with property key P, the following steps are taken:

  1. If Type(P) is Symbol, return OrdinaryGetOwnProperty(O, P).
  2. Let exports be the value of O's [[Exports]] internal slot.
  3. If P is not an element of exports, return undefined.
  4. Let value be ? O.[[Get]](P, O).
  5. Return PropertyDescriptor{[[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }.

9.4.6.6[[DefineOwnProperty]] (P, Desc)#

When the [[DefineOwnProperty]] internal method of a module namespace exotic object O is called with property key P and Property Descriptor Desc, the following steps are taken:

  1. Return false.

9.4.6.7[[HasProperty]] (P)#

When the [[HasProperty]] internal method of a module namespace exotic object O is called with property key P, the following steps are taken:

  1. If Type(P) is Symbol, return OrdinaryHasProperty(O, P).
  2. Let exports be the value of O's [[Exports]] internal slot.
  3. If P is an element of exports, return true.
  4. Return false.

9.4.6.8[[Get]] (P, Receiver)#

When the [[Get]] internal method of a module namespace exotic object O is called with property key P and ECMAScript language value Receiver, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. If Type(P) is Symbol, then
    1. Return ? OrdinaryGet(O, P, Receiver).
  3. Let exports be the value of O's [[Exports]] internal slot.
  4. If P is not an element of exports, return undefined.
  5. Let m be the value of O's [[Module]] internal slot.
  6. Let binding be ? m.ResolveExport(P, « », « »).
  7. Assert: binding is neither null nor "ambiguous".
  8. Let targetModule be binding.[[Module]].
  9. Assert: targetModule is not undefined.
  10. Let targetEnv be targetModule.[[Environment]].
  11. If targetEnv is undefined, throw a ReferenceError exception.
  12. Let targetEnvRec be targetEnv's EnvironmentRecord.
  13. Return ? targetEnvRec.GetBindingValue(binding.[[BindingName]], true).
Note

ResolveExport是副作用的。实现可能会选择为每个模块命名空间非普通对象的[[Exports]]预先计算或缓存ResolveExport结果。

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

When the [[Set]] internal method of a module namespace exotic object O is called with property key P, value V, and ECMAScript language value Receiver, the following steps are taken:

  1. Return false.

9.4.6.10[[Delete]] (P)#

When the [[Delete]] internal method of a module namespace exotic object O is called with property key P, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. Let exports be the value of O's [[Exports]] internal slot.
  3. If P is an element of exports, return false.
  4. Return true.

9.4.6.11[[OwnPropertyKeys]] ( )#

抽象操作ModuleNamespaceCreate与arguments模块,而export用于指定创建新的模块命名空间非普通对象。 它执行以下步骤:

  1. Let exports be a copy of the value of O's [[Exports]] internal slot.
  2. Let symbolKeys be ! OrdinaryOwnPropertyKeys(O).
  3. Append all the entries of symbolKeys to the end of exports.
  4. Return exports.

9.4.6.12ModuleNamespaceCreate (module, exports)#

抽象操作ModuleNamespaceCreate使用参数 module,export用于指定创建新的模块命名空间非普通对象。 它执行以下步骤:

  1. Assert: module is a Module Record.
  2. Assert: module.[[Namespace]] is undefined.
  3. Assert: exports is a List of String values.
  4. Let M be a newly created object.
  5. Set M's essential internal methods to the definitions specified in 9.4.6.
  6. Set M's [[Module]] internal slot to module.
  7. Set M's [[Exports]] internal slot to exports.
  8. Create own properties of M corresponding to the definitions in 26.3.
  9. Set module.[[Namespace]] to M.
  10. Return M.

9.4.7不变原型非普通对象(Immutable Prototype Exotic Objects)#

一个不可变的原型非普通对象是一个非普通对象,它具有不可变的[[Prototype]]内部插槽。

9.4.7.1[[SetPrototypeOf]] (V)#

immutable prototype exotic object 的[[SetPrototypeOf]]内部方法用参数 V 调用,执行以下步骤:

  1. Assert: Either Type(V) is Object or Type(V) is Null.
  2. Let current be the value of the [[Prototype]] internal slot of O.
  3. If SameValue(V, current) is true, return true.
  4. Return false.

9.5代理对象内部方法和内部插槽(Proxy Object Internal Methods and Internal Slots)#

代理对象是一个非普通对象,其基本内部方法部分实现使用ECMAScript代码。 每个代理对象都有一个名为[[ProxyHandler]]的内部插槽。 [[ProxyHandler]]的值是一个对象,称为代理的处理程序对象,或为空。 可以使用处理程序对象的方法(参见表30)来增加代理对象的一个或多个内部方法的实现。 每个代理对象还有一个名为[[ProxyTarget]]的内部插槽,其值为对象或空值。 该对象称为代理的目标对象。

Table 30: Proxy Handler Methods
Internal Method Handler Method
[[GetPrototypeOf]] getPrototypeOf
[[SetPrototypeOf]] setPrototypeOf
[[IsExtensible]] isExtensible
[[PreventExtensions]] preventExtensions
[[GetOwnProperty]] getOwnPropertyDescriptor
[[HasProperty]] has
[[Get]] get
[[Set]] set
[[Delete]] deleteProperty
[[DefineOwnProperty]] defineProperty
[[OwnPropertyKeys]] ownKeys
[[Call]] apply
[[Construct]] construct

当调用处理程序方法来提供代理对象内部方法的实现时,处理程序方法作为参数传递代理的目标对象。 代理的处理程序对象不一定具有对应于每个必要内部方法的方法。 如果处理程序对象没有与内部陷阱对应的方法,则在代理上调用内部方法将导致在代理目标对象上调用相应的内部方法。

代理对象的[[ProxyHandler]]和[[ProxyTarget]]内部插槽始终在创建对象时初始化,通常可能不会被修改。 某些代理对象的创建方式允许随后被撤销。 当代理被撤销时,其[[ProxyHandler]]和[[ProxyTarget]]内部插槽设置为null,导致该代理对象上的内部方法的后续调用引发TypeError异常。

因为代理对象允许通过任意ECMAScript代码来实现内部方法,所以可以定义一个代理对象,其处理方法违反了6.1.7.3中定义的不变量。 6.1.7.3中定义的一些内部方法不变量是必需的完整性不变量。 这些不变量由本节中指定的代理对象内部方法显式执行。 在存在所有可能的不变违规的情况下,ECMAScript实现必须是稳健的。

在以下算法描述中,假定O是ECMAScript代理对象,P是属性键值,V是任何ECMAScript语言值,Desc是属性描述符记录。

9.5.1[[GetPrototypeOf]] ( )#

当调用Proxy非普通对象O的[[GetPrototypeOf]]内部方法时,将执行以下步骤:

  1. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  2. If handler is null, throw a TypeError exception.
  3. Assert: Type(handler) is Object.
  4. Let target be the value of the [[ProxyTarget]] internal slot of O.
  5. Let trap be ? GetMethod(handler, "getPrototypeOf").
  6. If trap is undefined, then
    1. Return ? target.[[GetPrototypeOf]]().
  7. Let handlerProto be ? Call(trap, handler, « target »).
  8. If Type(handlerProto) is neither Object nor Null, throw a TypeError exception.
  9. Let extensibleTarget be ? IsExtensible(target).
  10. If extensibleTarget is true, return handlerProto.
  11. Let targetProto be ? target.[[GetPrototypeOf]]().
  12. If SameValue(handlerProto, targetProto) is false, throw a TypeError exception.
  13. Return handlerProto.
Note

代理对象的[[GetPrototypeOf]]强制执行以下不变量:

  • [[GetPrototypeOf]]的结果必须是Object或null。
  • 如果目标对象不可扩展,则应用于代理对象的[[GetPrototypeOf]]必须返回与应用于代理对象的目标对象的[[GetPrototypeOf]]相同的值。

9.5.2[[SetPrototypeOf]] (V)#

When the [[SetPrototypeOf]] internal method of a Proxy exotic object O is called with argument V, the following steps are taken:

  1. Assert: Either Type(V) is Object or Type(V) is Null.
  2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  3. If handler is null, throw a TypeError exception.
  4. Assert: Type(handler) is Object.
  5. Let target be the value of the [[ProxyTarget]] internal slot of O.
  6. Let trap be ? GetMethod(handler, "setPrototypeOf").
  7. If trap is undefined, then
    1. Return ? target.[[SetPrototypeOf]](V).
  8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)).
  9. If booleanTrapResult is false, return false.
  10. Let extensibleTarget be ? IsExtensible(target).
  11. If extensibleTarget is true, return true.
  12. Let targetProto be ? target.[[GetPrototypeOf]]().
  13. If SameValue(V, targetProto) is false, throw a TypeError exception.
  14. Return true.
Note

[[SetPrototypeOf]] for proxy objects enforces the following invariant:

  • The result of [[SetPrototypeOf]] is a Boolean value.
  • If the target object is not extensible, the argument value must be the same as the result of [[GetPrototypeOf]] applied to target object.

9.5.3[[IsExtensible]] ( )#

When the [[IsExtensible]] internal method of a Proxy exotic object O is called, the following steps are taken:

  1. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  2. If handler is null, throw a TypeError exception.
  3. Assert: Type(handler) is Object.
  4. Let target be the value of the [[ProxyTarget]] internal slot of O.
  5. Let trap be ? GetMethod(handler, "isExtensible").
  6. If trap is undefined, then
    1. Return ? target.[[IsExtensible]]().
  7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target »)).
  8. Let targetResult be ? target.[[IsExtensible]]().
  9. If SameValue(booleanTrapResult, targetResult) is false, throw a TypeError exception.
  10. Return booleanTrapResult.
Note

[[IsExtensible]] for proxy objects enforces the following invariant:

  • The result of [[IsExtensible]] is a Boolean value.
  • [[IsExtensible]] applied to the proxy object must return the same value as [[IsExtensible]] applied to the proxy object's target object with the same argument.

9.5.4[[PreventExtensions]] ( )#

When the [[PreventExtensions]] internal method of a Proxy exotic object O is called, the following steps are taken:

  1. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  2. If handler is null, throw a TypeError exception.
  3. Assert: Type(handler) is Object.
  4. Let target be the value of the [[ProxyTarget]] internal slot of O.
  5. Let trap be ? GetMethod(handler, "preventExtensions").
  6. If trap is undefined, then
    1. Return ? target.[[PreventExtensions]]().
  7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target »)).
  8. If booleanTrapResult is true, then
    1. Let targetIsExtensible be ? target.[[IsExtensible]]().
    2. If targetIsExtensible is true, throw a TypeError exception.
  9. Return booleanTrapResult.
Note

[[PreventExtensions]] for proxy objects enforces the following invariant:

  • The result of [[PreventExtensions]] is a Boolean value.
  • [[PreventExtensions]] applied to the proxy object only returns true if [[IsExtensible]] applied to the proxy object's target object is false.

9.5.5[[GetOwnProperty]] (P)#

When the [[GetOwnProperty]] internal method of a Proxy exotic object O is called with property key P, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  3. If handler is null, throw a TypeError exception.
  4. Assert: Type(handler) is Object.
  5. Let target be the value of the [[ProxyTarget]] internal slot of O.
  6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor").
  7. If trap is undefined, then
    1. Return ? target.[[GetOwnProperty]](P).
  8. Let trapResultObj be ? Call(trap, handler, « target, P »).
  9. If Type(trapResultObj) is neither Object nor Undefined, throw a TypeError exception.
  10. Let targetDesc be ? target.[[GetOwnProperty]](P).
  11. If trapResultObj is undefined, then
    1. If targetDesc is undefined, return undefined.
    2. If targetDesc.[[Configurable]] is false, throw a TypeError exception.
    3. Let extensibleTarget be ? IsExtensible(target).
    4. Assert: Type(extensibleTarget) is Boolean.
    5. If extensibleTarget is false, throw a TypeError exception.
    6. Return undefined.
  12. Let extensibleTarget be ? IsExtensible(target).
  13. Let resultDesc be ? ToPropertyDescriptor(trapResultObj).
  14. Call CompletePropertyDescriptor(resultDesc).
  15. Let valid be IsCompatiblePropertyDescriptor(extensibleTarget, resultDesc, targetDesc).
  16. If valid is false, throw a TypeError exception.
  17. If resultDesc.[[Configurable]] is false, then
    1. If targetDesc is undefined or targetDesc.[[Configurable]] is true, then
      1. Throw a TypeError exception.
  18. Return resultDesc.
Note

[[GetOwnProperty]] for proxy objects enforces the following invariants:

  • The result of [[GetOwnProperty]] must be either an Object or undefined.
  • A property cannot be reported as non-existent, if it exists as a non-configurable own property of the target object.
  • A property cannot be reported as non-existent, if it exists as an own property of the target object and the target object is not extensible.
  • A property cannot be reported as existent, if it does not exists as an own property of the target object and the target object is not extensible.
  • A property cannot be reported as non-configurable, if it does not exists as an own property of the target object or if it exists as a configurable own property of the target object.

9.5.6[[DefineOwnProperty]] (P, Desc)#

When the [[DefineOwnProperty]] internal method of a Proxy exotic object O is called with property key P and Property Descriptor Desc, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  3. If handler is null, throw a TypeError exception.
  4. Assert: Type(handler) is Object.
  5. Let target be the value of the [[ProxyTarget]] internal slot of O.
  6. Let trap be ? GetMethod(handler, "defineProperty").
  7. If trap is undefined, then
    1. Return ? target.[[DefineOwnProperty]](P, Desc).
  8. Let descObj be FromPropertyDescriptor(Desc).
  9. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P, descObj »)).
  10. If booleanTrapResult is false, return false.
  11. Let targetDesc be ? target.[[GetOwnProperty]](P).
  12. Let extensibleTarget be ? IsExtensible(target).
  13. If Desc has a [[Configurable]] field and if Desc.[[Configurable]] is false, then
    1. Let settingConfigFalse be true.
  14. Else let settingConfigFalse be false.
  15. If targetDesc is undefined, then
    1. If extensibleTarget is false, throw a TypeError exception.
    2. If settingConfigFalse is true, throw a TypeError exception.
  16. Else targetDesc is not undefined,
    1. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc, targetDesc) is false, throw a TypeError exception.
    2. If settingConfigFalse is true and targetDesc.[[Configurable]] is true, throw a TypeError exception.
  17. Return true.
Note

[[DefineOwnProperty]] for proxy objects enforces the following invariants:

  • The result of [[DefineOwnProperty]] is a Boolean value.
  • A property cannot be added, if the target object is not extensible.
  • A property cannot be non-configurable, unless there exists a corresponding non-configurable own property of the target object.
  • If a property has a corresponding target object property then applying the Property Descriptor of the property to the target object using [[DefineOwnProperty]] will not throw an exception.

9.5.7[[HasProperty]] (P)#

When the [[HasProperty]] internal method of a Proxy exotic object O is called with property key P, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  3. If handler is null, throw a TypeError exception.
  4. Assert: Type(handler) is Object.
  5. Let target be the value of the [[ProxyTarget]] internal slot of O.
  6. Let trap be ? GetMethod(handler, "has").
  7. If trap is undefined, then
    1. Return ? target.[[HasProperty]](P).
  8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P »)).
  9. If booleanTrapResult is false, then
    1. Let targetDesc be ? target.[[GetOwnProperty]](P).
    2. If targetDesc is not undefined, then
      1. If targetDesc.[[Configurable]] is false, throw a TypeError exception.
      2. Let extensibleTarget be ? IsExtensible(target).
      3. If extensibleTarget is false, throw a TypeError exception.
  10. Return booleanTrapResult.
Note

[[HasProperty]] for proxy objects enforces the following invariants:

  • The result of [[HasProperty]] is a Boolean value.
  • A property cannot be reported as non-existent, if it exists as a non-configurable own property of the target object.
  • A property cannot be reported as non-existent, if it exists as an own property of the target object and the target object is not extensible.

9.5.8[[Get]] (P, Receiver)#

When the [[Get]] internal method of a Proxy exotic object O is called with property key P and ECMAScript language value Receiver, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  3. If handler is null, throw a TypeError exception.
  4. Assert: Type(handler) is Object.
  5. Let target be the value of the [[ProxyTarget]] internal slot of O.
  6. Let trap be ? GetMethod(handler, "get").
  7. If trap is undefined, then
    1. Return ? target.[[Get]](P, Receiver).
  8. Let trapResult be ? Call(trap, handler, « target, P, Receiver »).
  9. Let targetDesc be ? target.[[GetOwnProperty]](P).
  10. If targetDesc is not undefined, then
    1. If IsDataDescriptor(targetDesc) is true and targetDesc.[[Configurable]] is false and targetDesc.[[Writable]] is false, then
      1. If SameValue(trapResult, targetDesc.[[Value]]) is false, throw a TypeError exception.
    2. If IsAccessorDescriptor(targetDesc) is true and targetDesc.[[Configurable]] is false and targetDesc.[[Get]] is undefined, then
      1. If trapResult is not undefined, throw a TypeError exception.
  11. Return trapResult.
Note

[[Get]] for proxy objects enforces the following invariants:

  • The value reported for a property must be the same as the value of the corresponding target object property if the target object property is a non-writable, non-configurable own data property.
  • The value reported for a property must be undefined if the corresponding target object property is a non-configurable own accessor property that has undefined as its [[Get]] attribute.

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

When the [[Set]] internal method of a Proxy exotic object O is called with property key P, value V, and ECMAScript language value Receiver, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  3. If handler is null, throw a TypeError exception.
  4. Assert: Type(handler) is Object.
  5. Let target be the value of the [[ProxyTarget]] internal slot of O.
  6. Let trap be ? GetMethod(handler, "set").
  7. If trap is undefined, then
    1. Return ? target.[[Set]](P, V, Receiver).
  8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)).
  9. If booleanTrapResult is false, return false.
  10. Let targetDesc be ? target.[[GetOwnProperty]](P).
  11. If targetDesc is not undefined, then
    1. If IsDataDescriptor(targetDesc) is true and targetDesc.[[Configurable]] is false and targetDesc.[[Writable]] is false, then
      1. If SameValue(V, targetDesc.[[Value]]) is false, throw a TypeError exception.
    2. If IsAccessorDescriptor(targetDesc) is true and targetDesc.[[Configurable]] is false, then
      1. If targetDesc.[[Set]] is undefined, throw a TypeError exception.
  12. Return true.
Note

[[Set]] for proxy objects enforces the following invariants:

  • The result of [[Set]] is a Boolean value.
  • Cannot change the value of a property to be different from the value of the corresponding target object property if the corresponding target object property is a non-writable, non-configurable own data property.
  • Cannot set the value of a property if the corresponding target object property is a non-configurable own accessor property that has undefined as its [[Set]] attribute.

9.5.10[[Delete]] (P)#

When the [[Delete]] internal method of a Proxy exotic object O is called with property key P, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  3. If handler is null, throw a TypeError exception.
  4. Assert: Type(handler) is Object.
  5. Let target be the value of the [[ProxyTarget]] internal slot of O.
  6. Let trap be ? GetMethod(handler, "deleteProperty").
  7. If trap is undefined, then
    1. Return ? target.[[Delete]](P).
  8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P »)).
  9. If booleanTrapResult is false, return false.
  10. Let targetDesc be ? target.[[GetOwnProperty]](P).
  11. If targetDesc is undefined, return true.
  12. If targetDesc.[[Configurable]] is false, throw a TypeError exception.
  13. Return true.
Note

[[Delete]] for proxy objects enforces the following invariant:

  • The result of [[Delete]] is a Boolean value.
  • A property cannot be reported as deleted, if it exists as a non-configurable own property of the target object.

9.5.11[[OwnPropertyKeys]] ( )#

When the [[OwnPropertyKeys]] internal method of a Proxy exotic object O is called, the following steps are taken:

  1. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  2. If handler is null, throw a TypeError exception.
  3. Assert: Type(handler) is Object.
  4. Let target be the value of the [[ProxyTarget]] internal slot of O.
  5. Let trap be ? GetMethod(handler, "ownKeys").
  6. If trap is undefined, then
    1. Return ? target.[[OwnPropertyKeys]]().
  7. Let trapResultArray be ? Call(trap, handler, « target »).
  8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »).
  9. Let extensibleTarget be ? IsExtensible(target).
  10. Let targetKeys be ? target.[[OwnPropertyKeys]]().
  11. Assert: targetKeys is a List containing only String and Symbol values.
  12. Let targetConfigurableKeys be a new empty List.
  13. Let targetNonconfigurableKeys be a new empty List.
  14. Repeat, for each element key of targetKeys,
    1. Let desc be ? target.[[GetOwnProperty]](key).
    2. If desc is not undefined and desc.[[Configurable]] is false, then
      1. Append key as an element of targetNonconfigurableKeys.
    3. Else,
      1. Append key as an element of targetConfigurableKeys.
  15. If extensibleTarget is true and targetNonconfigurableKeys is empty, then
    1. Return trapResult.
  16. Let uncheckedResultKeys be a new List which is a copy of trapResult.
  17. Repeat, for each key that is an element of targetNonconfigurableKeys,
    1. If key is not an element of uncheckedResultKeys, throw a TypeError exception.
    2. Remove key from uncheckedResultKeys.
  18. If extensibleTarget is true, return trapResult.
  19. Repeat, for each key that is an element of targetConfigurableKeys,
    1. If key is not an element of uncheckedResultKeys, throw a TypeError exception.
    2. Remove key from uncheckedResultKeys.
  20. If uncheckedResultKeys is not empty, throw a TypeError exception.
  21. Return trapResult.
Note

[[OwnPropertyKeys]] for proxy objects enforces the following invariants:

  • The result of [[OwnPropertyKeys]] is a List.
  • The Type of each result List element is either String or Symbol.
  • The result List must contain the keys of all non-configurable own properties of the target object.
  • If the target object is not extensible, then the result List must contain all the keys of the own properties of the target object and no other values.

9.5.12[[Call]] (thisArgument, argumentsList)#

The [[Call]] internal method of a Proxy exotic object O is called with parameters thisArgument and argumentsList, a List of ECMAScript language values. The following steps are taken:

  1. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  2. If handler is null, throw a TypeError exception.
  3. Assert: Type(handler) is Object.
  4. Let target be the value of the [[ProxyTarget]] internal slot of O.
  5. Let trap be ? GetMethod(handler, "apply").
  6. If trap is undefined, then
    1. Return ? Call(target, thisArgument, argumentsList).
  7. Let argArray be CreateArrayFromList(argumentsList).
  8. Return ? Call(trap, handler, « target, thisArgument, argArray »).
Note

A Proxy exotic object only has a [[Call]] internal method if the initial value of its [[ProxyTarget]] internal slot is an object that has a [[Call]] internal method.

9.5.13[[Construct]] ( argumentsList, newTarget)#

The [[Construct]] internal method of a Proxy exotic object O is called with parameters argumentsList which is a possibly empty List of ECMAScript language values and newTarget. The following steps are taken:

  1. Let handler be the value of the [[ProxyHandler]] internal slot of O.
  2. If handler is null, throw a TypeError exception.
  3. Assert: Type(handler) is Object.
  4. Let target be the value of the [[ProxyTarget]] internal slot of O.
  5. Let trap be ? GetMethod(handler, "construct").
  6. If trap is undefined, then
    1. Assert: target has a [[Construct]] internal method.
    2. Return ? Construct(target, argumentsList, newTarget).
  7. Let argArray be CreateArrayFromList(argumentsList).
  8. Let newObj be ? Call(trap, handler, « target, argArray, newTarget »).
  9. If Type(newObj) is not Object, throw a TypeError exception.
  10. Return newObj.
Note 1

A Proxy exotic object only has a [[Construct]] internal method if the initial value of its [[ProxyTarget]] internal slot is an object that has a [[Construct]] internal method.

Note 2

[[Construct]] for proxy objects enforces the following invariants:

  • The result of [[Construct]] must be an Object.

9.5.14ProxyCreate (target, handler)#

使用参数target和handler的抽象操作ProxyCreate用于指定创建新的Proxy非普通对象。 它执行以下步骤:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. If target is a Proxy exotic object and the value of the [[ProxyHandler]] internal slot of target is null, throw a TypeError exception.
  3. If Type(handler) is not Object, throw a TypeError exception.
  4. If handler is a Proxy exotic object and the value of the [[ProxyHandler]] internal slot of handler is null, throw a TypeError exception.
  5. Let P be a newly created object.
  6. Set P's essential internal methods (except for [[Call]] and [[Construct]]) to the definitions specified in 9.5.
  7. If IsCallable(target) is true, then
    1. Set the [[Call]] internal method of P as specified in 9.5.12.
    2. If target has a [[Construct]] internal method, then
      1. Set the [[Construct]] internal method of P as specified in 9.5.13.
  8. Set the [[ProxyTarget]] internal slot of P to target.
  9. Set the [[ProxyHandler]] internal slot of P to handler.
  10. Return P.

10ECMAScript语言:源代码(ECMAScript Language: Source Code)#

10.1源文本(Source Text)#

语法(Syntax)

SourceCharacter::any Unicode code point

ECMAScript代码使用Unicode,8.0.0或更高版本来表示。 ECMAScript源文本是一系列代码点。 来自U + 0000至U + 10FFFF的所有Unicode代码点值(包括代理代码点)可能发生在ECMAScript语法允许的源文本中。 用于存储和交换ECMAScript源文本的实际编码与本规范无关。 不管外部源文本编码如何,符合规范的ECMAScript实现将源文本处理为SourceCharacter值的等效序列,每个SourceCharacter都是Unicode代码点。 执行ECMAScript实现不需要执行源文本的任何规范化,或者表现为正在执行源文本的归一化。

组合字符序列的组件被视为单独的Unicode代码点,即使用户可能将整个序列视为单个字符。

Note

在字符串文字中,正则表达式文字,模板文字和标识符,任何Unicode代码点也可以使用显式表达代码点数值的Unicode转义序列来表示。 在注释中,作为注释的一部分,这样的转义序列被有效地忽略。

ECMAScript与Java编程语言在Unicode转义序列的行为上不同。在Java程序中,如果Unicode转义序列\ u000A例如发生在单行注释中,则将其解释为行终止符(Unicode代码点U + 000A为LINE FEED(LF)),因此下一个代码点不是评论的一部分。类似地,如果Unicode转义序列\ u000A出现在Java程序中的字符串文字中,则它同样被解释为一个行终止符,它不允许在字符串文字中 - 一个必须写入\ n而不是\ u000A来引起一个LINE FEED(LF)成为字符串文字的String值的一部分。在ECMAScript程序中,注释中发生的Unicode转义序列从不被解释,因此不能有助于注释的终止。类似地,在ECMAScript程序中的字符串文字中出现的Unicode转义序列总是有助于文字,并且不会被解释为行终止符或可能终止字符串文字的代码点。

10.1.1静态语义(Static Semantics): UTF16Encoding ( cp )#

The UTF16Encoding of a numeric code point value, cp, is determined as follows:

  1. Assert: 0 ≤ cp ≤ 0x10FFFF.
  2. If cp ≤ 65535, return cp.
  3. Let cu1 be floor((cp - 65536) / 1024) + 0xD800.
  4. Let cu2 be ((cp - 65536) modulo 1024) + 0xDC00.
  5. Return the code unit sequence consisting of cu1 followed by cu2.

10.1.2Static Semantics: UTF16Decode( lead, trail )#

Two code units, lead and trail, that form a UTF-16 surrogate pair are converted to a code point by performing the following steps:

  1. Assert: 0xD800 ≤ lead ≤ 0xDBFF and 0xDC00 ≤ trail ≤ 0xDFFF.
  2. Let cp be (lead - 0xD800) × 1024 + (trail - 0xDC00) + 0x10000.
  3. Return the code point cp.

10.2源代码类型(Types of Source Code)#

ECMAScript代码有四种类型:

Note

函数代码通常作为函数定义(14.1),箭头函数定义(14.2),方法定义(14.3)和Generator 定义(14.4)的主体提供。 函数代码也派生自Function构造函数(19.2.1.1)和GeneratorFunction构造函数(25.2.1.1)的参数。

10.2.1严格模式代码(Strict Mode Code)#

可以使用无限制或严格模式语法和语义来处理ECMAScript脚本语法单元。 在以下情况下,代码被解释为严格模式代码:

  • 全局代码是严格的模式代码,如果它以指令序言(Directive Prologue)开头,其中包含 使用严格指令(Use Strict Directive)
  • 模块代码总是严格的模式代码。
  • ClassDeclaration或ClassExpression的所有部分都是严格的模式代码。
  • Eval代码是严格模式代码,如果它包含包含使用严格指令的指令序言,或者调用eval是否包含在严格模式代码中的直接eval。
  • 如果在严格模式代码中包含关联的FunctionDeclaration,FunctionExpression,GeneratorDeclaration,GeneratorExpression,MethodDefinition或ArrowFunction,则函数代码是严格模式代码,或者如果产生函数[[ECMAScriptCode]]内部值的值的代码以指令序言开头 其中包含使用严格指令。
  • 作为内置函数和生成器构造函数的参数提供的函数代码是严格模式代码,如果最后一个参数是一个String,当处理时是一个以包含使用严格指令的指令序言开头的FunctionBody。

不严格模式代码的ECMAScript代码称为非严格代码。

10.2.2非ECMAScript函数(Non-ECMAScript Functions)#

ECMAScript实现可以支持外来函数对象的执行,其执行行为以一些实现定义的可执行代码形式表示,而不是通过ECMAScript代码。 从ECMAScript代码函数的角度看,函数对象是否是ECMAScript代码函数或非ECMAScript函数,从ECMAScript函数调用或调用的ECMAScript函数的角度来看是不可语义的。

11ECMAScript语言:词法语法(ECMAScript Language: Lexical Grammar)#

ECMAScript脚本或模块的源文本首先被转换为一系列输入元素,它们是词条(tokens),行终止符,注释或空格。 源文本从左到右扫描,重复地将最长可能的代码点序列作为下一个输入元素。

有几种情况,其中词法输入元素的识别对消耗输入元素的句法语法上下文敏感。 这需要词汇语法的多个目标符号。 InputElementRegExpOrTemplateTail目标用于允许使用RegularExpressionLiteral,TemplateMiddle或TemplateTail的语法语法环境。 InputElementRegExp目标符号用于允许使用RegularExpressionLiteral的所有语法语法环境,但不允许使用TemplateMiddle和TemplateTail。 InputElementTemplateTail目标用于允许使用TemplateMiddle或TemplateTail的所有句法语法上下文,但不允许使用RegularExpressionLiteral。 在所有其他上下文中,InputElementDiv用作词汇目标符号。

Note

使用多个词汇目标确保没有影响自动分号插入的词汇模糊。 例如,没有句法语法上下文,其中允许前导分区或分区分配和领先的RegularExpressionLiteral。 这不受分号插入的影响(见11.9); 在以下示例中:


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

11.1Unicode格式控制字符(Unicode Format-Control Characters)#

Unicode格式控制字符(即,Unicode字符数据库中的类别“Cf”中的字符,例如LEFT-TO-RIGHT MARK或RIGHT-TO-LEFT MARK)是用于控制一系列文本的格式的控制代码 在没有更高级别的协议(如标记语言)的情况下。

允许源文本中的格式控制字符有助于编辑和显示。 所有格式控制字符可以在注释中使用,也可以在字符串文字,模板文字和正则表达式文字中使用。

U+200C(ZERO WIDTH NON-JOINER)和U+200D(ZERO WIDTH JOINER)是用于在以特定语言形成单词或短语时进行必要区分的格式控制字符。 在ECMAScript源文本中,这些代码点也可以在第一个字符之后的IdentifierName中使用。

U+FEFF(ZERO WIDTH NO-BREAK SPACE)是一种主要用于文本开头的格式控制字符,用于将其标记为Unicode,并允许检测文本的编码和字节顺序。 为此目的的字符有时也可能出现在文本开头之后,例如连接文件的结果。 在ECMAScript源文本中,代码点被视为空白字符(见11.2)。

表31中总结了注释外的某些格式控制字符,字符串文字和正则表达式文字的特殊处理。

Table 31: Format-Control Code Point Usage
Code Point Name Abbreviation Usage
U+200C ZERO WIDTH NON-JOINER <ZWNJ> IdentifierPart
U+200D ZERO WIDTH JOINER <ZWJ> IdentifierPart
U+FEFF ZERO WIDTH NO-BREAK SPACE <ZWNBSP> WhiteSpace

11.2White Space#

空白代码点用于提高源文本的可读性,并将词条(token)(不可分割的词汇单位)彼此分开,但是不重要。 任何两个词条之间和输入开始或结束时都可能会出现空格代码点。 一个StringLiteral,RegularExpressionLiteral,Template或TemplateSubstitutionTail中可能会出现空格代码点,它们被认为是构成文字值一部分的重要代码点。 它们也可能发生在注释中,但不能出现在任何其他类型的词条中。

ECMAScript空白代码点列在表32中。
Code Point Name Abbreviation
U+0009 CHARACTER TABULATION <TAB>
U+000B LINE TABULATION <VT>
U+000C FORM FEED (FF) <FF>
U+0020 SPACE <SP>
U+00A0 NO-BREAK SPACE <NBSP>
U+FEFF ZERO WIDTH NO-BREAK SPACE <ZWNBSP>
Other category “Zs” Any other Unicode “Separator, space” code point <USP>

ECMAScript实现必须识别为“分隔符,空格”(Zs)类别中列出的WhiteSpace代码点。

Note

除了表32中列出的代码点之外,ECMAScript WhiteSpace有意排除了所有具有Unicode“White_Space”属性但不归类于“Zs”类的代码点。

语法(Syntax)

WhiteSpace::<TAB> <VT> <FF> <SP> <NBSP> <ZWNBSP> <USP>

11.3行终止符(Line Terminators)#

像空格代码点一样,行终止符代码点用于提高源文本的可读性,并将token(不可分割的词汇单位)彼此分开。 然而,与空格代码点不同,行终止符对句法语法的行为有一定的影响。 通常,行终止符可能发生在任何两个token之间,但是有几个地方被语法语法所禁止。 行终止符也影响自动分号插入的过程(11.9)。 除了StringLiteral,Template或TemplateSubstitutionTail之外,任何token中都不能出现行终止符。 行终止符只能作为LineContinuation的一部分发生在StringLiteral token内。

行终止符可以在MultiLineComment中发生,但不能在SingleLineComment中发生。

行终止符包含在正则表达式中由\s类匹配的一组空白代码点中。

ECMAScript行终止符代码点在表33中列出。

Table 33: Line Terminator Code Points
Code Point 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>

表33中只有Unicode代码点被视为行终止符。 其他新行或断行的Unicode代码点不被视为行终止符,如果符合表32中列出的要求,则将其视为空格。序列 通常用作行终止符。 为了报告行号,应将其视为单个SourceCharacter。

语法(Syntax)

LineTerminator::<LF> <CR> <LS> <PS> LineTerminatorSequence::<LF> <CR>[lookahead ≠ <LF>] <LS> <PS> <CR><LF>

11.4注释(Comments)#

注释可以是单行还是多行。 多行注释不能嵌套。

因为单行注释可以包含除行终止符r代码点之外的任何Unicode代码点,并且由于令牌总是尽可能长的一般规则,所以单行注释始终包含来自//标记的所有代码点 到行尾。 但是,该行末尾的LineTerminator不被认为是单行注释的一部分; 它被词汇语法单独识别,并成为句法语法的输入元素流的一部分。 这一点非常重要,因为它意味着单行注释的存在或不存在不会影响自动分号插入的过程(参见11.9)。

注释的行为像空白,并且被丢弃,除了,如果MultiLineComment包含一个行终止符代码点,则整个注释被认为是一个LineTerminator,用于句法语法的解析。

Syntax

Comment::MultiLineComment SingleLineComment MultiLineComment::/*MultiLineCommentCharsopt*/ MultiLineCommentChars::MultiLineNotAsteriskCharMultiLineCommentCharsopt *PostAsteriskCommentCharsopt PostAsteriskCommentChars::MultiLineNotForwardSlashOrAsteriskCharMultiLineCommentCharsopt *PostAsteriskCommentCharsopt MultiLineNotAsteriskChar::SourceCharacterbut not * MultiLineNotForwardSlashOrAsteriskChar::SourceCharacterbut not one of / or * SingleLineComment:://SingleLineCommentCharsopt SingleLineCommentChars::SingleLineCommentCharSingleLineCommentCharsopt SingleLineCommentChar::SourceCharacterbut not LineTerminator

11.5Tokens#

Syntax

CommonToken::IdentifierName Punctuator NumericLiteral StringLiteral Template Note

DivPunctuator,RegularExpressionLiteral,RightBracePunctuator和TemplateSubstitutionTail生成导出了未包含在CommonToken生产中的附加词条。

11.6名称和关键词(Names and Keywords)#

IdentifierName ReservedWord是根据Unicode标准附件31中标识符和模式语法给出的默认标识符语法进行解释的token,并进行了一些小的修改。ReservedWordIdentifierName的枚举子集。 语法语法将Identifier定义为不是ReservedWord的IdentifierName 。 Unicode标识符语法基于Unicode标准指定的字符属性。 Unicode标准版本8.0.0中的指定类别中的Unicode代码点必须按照所有符合ECMAScript实现的那些类别进行处理。 ECMAScript实现可以识别在Unicode标准的后续版本中定义的标识符代码点。

Note 1

该标准规定了特定的代码点添加:标识符名称中的任何地方允许使用U+ 0024(DOLLAR SIGN)和U+005F(LOW LINE),代码点U+200C(ZERO WIDTH NON-JOINER)和U+200D(ZERO WIDTH JOINER)允许在IdentifierName的第一个代码点之后的任何地方。

在IdentifierName中允许使用Unicode转义序列,它们向IdentifierName贡献一个Unicode代码点。 代码点由Unicode转义序列的16进制表示(见11.8.4)。 在Unicode转义序列之前的\和u和{}代码单元,如果它们出现,不贡献代码点到IdentifierName。 Unicode转义序列不能用于将代码点放入否则为非法的IdentifierName。 换句话说,如果一个\UnicodeEscapeSequence序列被SourceCharacter替换,那么该结果仍然是一个有效的IdentifierName,它具有与原始IdentifierName完全相同的SourceCharacter元素序列。 本规范中IdentifierName的所有解释均基于其实际代码点,而不管转义序列是否用于提供任何特定的代码点。

符合Unicode标准的两个标识符名称不相等,除非在替换每个UnicodeEscapeSequence之后,它们由完全相同的代码点序列表示。

Syntax

IdentifierName::IdentifierStart IdentifierNameIdentifierPart IdentifierStart::UnicodeIDStart $ _ \UnicodeEscapeSequence IdentifierPart::UnicodeIDContinue $ _ \UnicodeEscapeSequence <ZWNJ> <ZWJ> UnicodeIDStart::any Unicode code point with the Unicode property “ID_Start” UnicodeIDContinue::any Unicode code point with the Unicode property “ID_Continue”

非终止UnicodeEscapeSequence的定义在11.8.4中给出。

Note 2

具有Unicode属性“ID_Start”和“ID_Continue”的代码点集合分别包含具有Unicode属性“Other_ID_Start”和“Other_ID_Continue”的代码点。

11.6.1Identifier Names#

11.6.1.1静态语义:早期错误(Static Semantics: Early Errors)#

IdentifierStart::\UnicodeEscapeSequence IdentifierPart::\UnicodeEscapeSequence

11.6.1.2Static Semantics: StringValue#

IdentifierName::IdentifierStart IdentifierNameIdentifierPart
  1. 返回由与IdentifierName对应的代码单元序列组成的String值。 在确定序列时,首先用UnicodeEscapeSequence表示的代码点替换\ UnicodeEscapeSequence的任何出现,然后通过UTF16Encoding每个代码点将整个IdentifierName的代码点转换为代码单元。

11.6.2Reserved Words#

保留字(reserved word)是不能用作标识符(Identifier)的IdentifierName。

Syntax

ReservedWord::Keyword FutureReservedWord NullLiteral BooleanLiteral Note

ReservedWord定义被指定为特定SourceCharacter元素的文字序列。 ReservedWord中的代码点不能由\ UnicodeEscapeSequence表示。

11.6.2.1关键词(Keywords)#

以下tokens是ECMAScript关键字,不能用作ECMAScript程序中的标识符(Identifiers)。

Syntax

Keyword::one ofbreakdointypeofcaseelseinstanceofvarcatchexportnewvoidclassextendsreturnwhileconstfinallysuperwithcontinueforswitchyielddebuggerfunctionthisdefaultifthrowdeleteimporttry Note

在某些情况下,yield被赋予了标识符的语义。 见12.1.1。 在严格模式代码中,let和static通过静态语义限制(见12.1.1,13.3.1.1,13.7.5.1和14.5.1)而不是词法语法被视为保留关键字。

11.6.2.2未来保留字(Future Reserved Words)#

以下tokens保留作为未来语言扩展中的关键字

Syntax

FutureReservedWord::enum await

await只有当Module成为句法语法的目标符号时,才被视为FutureReservedWord。

Note

在严格模式代码中使用以下tokens也是保留的。 该使用受到使用静态语义限制(参见12.1.1)而不是词法语法的限制:

implements package protected
interface private public

11.7标点符号(Punctuators)#

Syntax

Punctuator::one of{()[]....;,<><=>===!====!==+-*%++--<<>>>>>&|^!~&&||?:=+=-=*=%=<<=>>=>>>=&=|=^==>****= DivPunctuator(分区符号)::/ /= RightBracePunctuator(右支撑标点符号)::}

11.8字面(Literals)#

11.8.1Null Literals#

Syntax

NullLiteral::null

11.8.2Boolean Literals#

Syntax

BooleanLiteral::true false

11.8.3Numeric Literals#

Syntax

NumericLiteral::DecimalLiteral BinaryIntegerLiteral OctalIntegerLiteral HexIntegerLiteral DecimalLiteral::DecimalIntegerLiteral.DecimalDigitsoptExponentPartopt .DecimalDigitsExponentPartopt DecimalIntegerLiteralExponentPartopt DecimalIntegerLiteral::0 NonZeroDigitDecimalDigitsopt DecimalDigits::DecimalDigit DecimalDigitsDecimalDigit DecimalDigit::one of0123456789 NonZeroDigit::one of123456789 ExponentPart::ExponentIndicatorSignedInteger ExponentIndicator::one ofeE SignedInteger::DecimalDigits +DecimalDigits -DecimalDigits BinaryIntegerLiteral::0bBinaryDigits 0BBinaryDigits BinaryDigits::BinaryDigit BinaryDigitsBinaryDigit BinaryDigit::one of01 OctalIntegerLiteral::0oOctalDigits 0OOctalDigits OctalDigits::OctalDigit OctalDigitsOctalDigit OctalDigit::one of01234567 HexIntegerLiteral::0xHexDigits 0XHexDigits HexDigits::HexDigit HexDigitsHexDigit HexDigit::one of0123456789abcdefABCDEF

紧跟在NumericLiteral之后的SourceCharacter不能是IdentifierStart或DecimalDigit。

Note

例如:3in是一个error,而不是两个输入元素3和in。/p>

在处理严格模式代码时,一致的实现不能如B.1.1所述扩展NumericLiteral的语法以包含LegacyOctalIntegerLiteral,也不能扩展DecimalIntegerLiteral的语法以包含NonOctalDecimalIntegerLiteral。

11.8.3.1Static Semantics(静态语义): MV#

数字字面代表数字类型的值。 该值通过两个步骤确定:首先,从文字导出数学值(MV); 第二,这个数学值如下所述舍入。

一旦确定了数字文字的确切的MV,它将被四舍五入为数字类型的值。 如果MV为0,则舍入值为+0; 否则,舍入值必须是MV的Number值(如6.1.6中所述),除非文字为DecimalLiteral,并且文字具有20个有效数字,在这种情况下,Number值可能是Number值 对于通过用20位替换20位后的每个有效数字的MV,或者通过用20位替换20位之后的每个有效数字,然后在20位递增文字而产生的字面值的MV的Number值。 如果一个数字不是一个ExponentPart的一部分

  • it is not 0; or
  • 它的左边有一个非零的数字,在指数部分右边是一个非零的数字。

11.8.4String Literals#

Note 1

字符串字面值为零或更多的Unicode代码点,以单引号或双引号括起来。 Unicode代码点也可以由转义序列表示。 U+005C(REVERSE SOLIDUS),U+000D(CARRIAGE RETURN),U+ 2028(LINE SEPARATOR),U+2029(PARAGRAPH SEPARATOR)和U+000A(LINE FEED)的结束代码点除外,所有代码点可以以字符串文字形式出现。 任何代码点可以以转义序列的形式出现。 字符串字面值执行为ECMAScript字符串值。 当生成这些String值时,Unicode代码点是按照10.1.1中定义的UTF-16编码。 属于基本多语言平面的代码点被编码为字符串的单个代码单元元素。 所有其他代码点被编码为字符串的两个代码单元元素。

Syntax

StringLiteral::"DoubleStringCharactersopt" 'SingleStringCharactersopt' DoubleStringCharacters::DoubleStringCharacterDoubleStringCharactersopt SingleStringCharacters::SingleStringCharacterSingleStringCharactersopt DoubleStringCharacter::SourceCharacterbut not one of " or \ or LineTerminator \EscapeSequence LineContinuation SingleStringCharacter::SourceCharacterbut not one of ' or \ or LineTerminator \EscapeSequence LineContinuation LineContinuation::\LineTerminatorSequence EscapeSequence::CharacterEscapeSequence 0[lookahead ∉ DecimalDigit] HexEscapeSequence UnicodeEscapeSequence

在处理严格模式代码时,一致的实现不能将EscapeSequence的语法扩展为包括B.1.2中所述的传统八进制转义序列。

CharacterEscapeSequence::SingleEscapeCharacter NonEscapeCharacter SingleEscapeCharacter::one of'"\bfnrtv NonEscapeCharacter::SourceCharacterbut not one of EscapeCharacter or LineTerminator EscapeCharacter::SingleEscapeCharacter DecimalDigit x u HexEscapeSequence::xHexDigitHexDigit UnicodeEscapeSequence::uHex4Digits u{HexDigits} Hex4Digits::HexDigitHexDigitHexDigitHexDigit

非终端HexDigit的定义在11.8.3中给出。 SourceCharacter在10.1中定义。

Note 2

行终止符代码点不能出现在字符串文字中,除了作为生成空代码点序列的LineContinuation的一部分。 导致行终止符代码指向字符串文字的String值的一部分的正确方法是使用转义序列,例如\n或\u000A。

11.8.4.1Static Semantics: Early Errors#

UnicodeEscapeSequence::u{HexDigits}
  • It is a Syntax Error if the MV of HexDigits > 1114111.

11.8.4.2Static Semantics: StringValue#

StringLiteral::"DoubleStringCharactersopt" 'SingleStringCharactersopt'
  1. Return the String value whose elements are the SV of this StringLiteral.

11.8.4.3Static Semantics: SV#

字符串字面值代表String类型的值。 文字的字符串值(SV)根据由字符串文字的各个部分贡献的代码单位值进行描述。 作为此过程的一部分,字符串文字中的一些Unicode代码点被解释为具有数学值(MV),如下所述或11.8.3中所述。

Table 34:字符串单字符转义序列(String Single Character Escape Sequences)
Escape Sequence Code Unit Value 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 \

11.8.5正则表达式文字(Regular Expression Literals)#

Note 1

正则表达式文字是每次执行文字时转换为RegExp对象(参见21.2)的输入元素。 程序中的两个正则表达式文字作为正则表达式对象执行时,即使两个文字的内容相同,也不会彼此比较为===。 RegExp对象也可以在运行时由新的RegExp创建,或者作为函数调用RegExp构造函数(见21.2.3)。

下面的产品描述正则表达式文字的语法,并由输入元素扫描器用于查找正则表达式文字的结尾。 随后使用更严格的ECMAScript正则表达式语法(21.2.1)再次解析包含RegularExpressionBody和RegularExpressionFlags的源文本。

实现可以扩展21.2.1中定义的ECMAScript正则表达式语法,但不能扩展下面定义的RegularExpressionBody和RegularExpressionFlags生成,也不能扩展这些生成使用的生成。

Syntax

RegularExpressionLiteral::/RegularExpressionBody/RegularExpressionFlags RegularExpressionBody::RegularExpressionFirstCharRegularExpressionChars RegularExpressionChars::[empty] RegularExpressionCharsRegularExpressionChar RegularExpressionFirstChar::RegularExpressionNonTerminatorbut not one of * or \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionChar::RegularExpressionNonTerminatorbut not one of \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionBackslashSequence::\RegularExpressionNonTerminator RegularExpressionNonTerminator::SourceCharacterbut not LineTerminator RegularExpressionClass::[RegularExpressionClassChars] RegularExpressionClassChars::[empty] RegularExpressionClassCharsRegularExpressionClassChar RegularExpressionClassChar::RegularExpressionNonTerminatorbut not one of ] or \ RegularExpressionBackslashSequence RegularExpressionFlags::[empty] RegularExpressionFlagsIdentifierPart Note 2

正则表达式文字不能为空; 代码单元序列//开始一个单行注释,而不是表示一个空的正则表达式文字。 要指定一个空的正则表达式,请使用:/(?:)/。

11.8.5.1Static Semantics: Early Errors#

RegularExpressionFlags::RegularExpressionFlagsIdentifierPart
  • It is a Syntax Error if IdentifierPart contains a Unicode escape sequence.

11.8.5.2Static Semantics: BodyText#

RegularExpressionLiteral::/RegularExpressionBody/RegularExpressionFlags
  1. Return the source text that was recognized as RegularExpressionBody.

11.8.5.3Static Semantics: FlagText#

RegularExpressionLiteral::/RegularExpressionBody/RegularExpressionFlags
  1. Return the source text that was recognized as RegularExpressionFlags.

11.8.6模板文字词汇组件(Template Literal Lexical Components)#

Syntax

Template::NoSubstitutionTemplate TemplateHead NoSubstitutionTemplate::`TemplateCharactersopt` TemplateHead::`TemplateCharactersopt${ TemplateSubstitutionTail::TemplateMiddle TemplateTail TemplateMiddle::}TemplateCharactersopt${ TemplateTail::}TemplateCharactersopt` TemplateCharacters::TemplateCharacterTemplateCharactersopt TemplateCharacter::$[lookahead ≠ {] \EscapeSequence LineContinuation LineTerminatorSequence SourceCharacterbut not one of ` or \ or $ or LineTerminator

解析TemplateCharacter时,一致的实现不能使用B.1.2中描述的EscapeSequence的扩展定义。

Note

TemplateSubstitutionTail由InputElementTemplateTail替代的词汇目标使用。

11.8.6.1Static Semantics: TV and TRV#

模板文字组件被解释为Unicode代码点的序列。 根据由模板文字组件的各个部分贡献的代码单元值(SV,11.8.4)来描述文字分量的模板值(TV)。 作为此过程的一部分,模板组件中的一些Unicode代码点被解释为具有数学值(MV,11.8.3)。 在确定模板值时,转义序列将由转义序列所代表的Unicode码点的UTF-16码单元替换。 模板原始值(TRV)与模板值类似,区别在于TRV中的转义序列是从字面上解释的。

Note

TV不包括LineContinuation的代码单位,而TRV包括它们。 对于TV和TRV, LineTerminatorSequences均标准化为 。 需要一个明确的EscapeSequence来包括一个 序列。

11.9自动分号插入(Automatic Semicolon Insertion)#

大多数ECMAScript语句和声明必须以分号终止。 这样的分号可能始终显示在源文本中。 然而,为了方便起见,在某些情况下可以从源文本中省略这样的分号。 这些情况的描述是在这些情况下,分号被自动插入到源代码tokens流中。

11.9.1自动分号插入规则(Rules of Automatic Semicolon Insertion)#

在以下规则中,“token”是指使用第11节所述的当前词汇目标符号确定的实际识别的词汇token。

分号插入有三条基本规则:

  1. 当作为脚本或模块从左到右解析时,遇到token(称为违规token),不允许任何语法生成,则分号在被冒犯的token之前被自动插入,如果有一个或多个 符合以下条件:

    • 至少一个LineTerminator将违规token与先前的token分开。
    • 违规token是}
    • 之前的令牌是),然后插入的分号将被解析为do-while语句的终止分号(13.7.2)。
  2. 当脚本或模块从左到右解析时,会遇到token输入流的结尾,并且解析器无法将输入token流解析为单个完整的ECMAScript脚本或模块,则分号将自动插入 在输入流的末尾。
  3. 当脚本或模块从左到右解析时,会遇到一些生成语法允许的token,但是生产是受限生产,token将是终端或非终端的第一个token 限制生产中的“[No LineTerminator Here]”的注释(因此这样的token被称为限制token),并且受限标记与至少一个LineTerminator与先前token分开,则分号自动插入到 限制token

但是,对于上述规则,还有一个额外的重写条件:如果分号将被解析为空语句,或者该分号将成为for语句头部的两个分号之一,则分号不会自动插入(请参阅13.7.4)。

Note

以下是语法中唯一受限制的产生式:

UpdateExpression[Yield]:LeftHandSideExpression[?Yield][no LineTerminator here]++ LeftHandSideExpression[?Yield][no LineTerminator here]-- ContinueStatement[Yield]:continue; continue[no LineTerminator here]LabelIdentifier[?Yield]; BreakStatement[Yield]:break; break[no LineTerminator here]LabelIdentifier[?Yield]; ReturnStatement[Yield]:return; return[no LineTerminator here]Expression[In, ?Yield]; ThrowStatement[Yield]:throw[no LineTerminator here]Expression[In, ?Yield]; ArrowFunction[In, Yield]:ArrowParameters[?Yield][no LineTerminator here]=>ConciseBody[?In] YieldExpression[In]:yield[no LineTerminator here]*AssignmentExpression[?In, Yield] yield[no LineTerminator here]AssignmentExpression[?In, Yield]

这些受限制产生式的实际效果如下:

  • 当遇到一个++或 -- token时,解析器将其视为后缀操作符,并且至少有一个LineTerminator发生在前面的token和++或 --标记之间,则分号将自动插入到++或 -- token之前
  • 当遇到continue,break,return,throw或yield 词条时,在下一个词条(token)之前遇到一个LineTerminator,则在continue,break,return,throw或yield令牌之后会自动插入分号。

对ECMAScript程序员的实际建议是:

  • 后缀++或 -- 运算符应该出现在与其操作数相同的行上。
  • return或throw语句中的表达式或yield表达式中的AssignmentExpression应该在与return,throw或yield词条相同的行上开始。
  • break或continue语句中的LabelIdentifier应与break或continue标记位于同一行。

11.9.2自动分号插入示例#

The source

{ 1 2 } 3

即使使用自动分号插入规则,ECMAScript语法中也不是有效的句子。 相反,来源


{ 1
2 } 3
      

也不是有效的ECMAScript句子,但是通过自动分号插入到以下变量中:


{ 1
;2 ;} 3;
      

这是一个有效的ECMAScript句子。

The source


for (a; b
)
      

不是一个有效的ECMAScript句子,并且不会被自动分号插入更改,因为for语句的标题需要分号。 自动分号插入不会在for语句的标题中插入两个分号中的一个。

The source


return
a + b
      

通过自动分号插入转换为以下内容:


return;
a + b;
      
Note 1

表达式a + b不被视为返回语句返回的值,因为LineTerminator将其从token return中分离出来。

The source


a = b
++c
      

通过自动分号插入转换为以下内容:


a = b;
++c;
      
Note 2

token ++不被视为应用于变量b的后缀运算符,因为LineTerminator发生在b和++之间。

The source


if (a > b)
else c = d
      

不是一个有效的ECMAScript句子,并且不会在else标记之前自动分号插入更改,即使在该点不会生成语法,因为自动插入的分号将被解析为空语句。

The source


a = b + c
(d + e).print()
      

不会通过自动分号插入进行转换,因为开始第二行的括号表达式可以解释为函数调用的参数列表:

a = b + c(d + e).print()

在赋值语句必须以左括号开头的情况下,程序员在前一个语句的末尾提供一个明确的分号,而不是依靠自动分号插入是一个好主意。

12ECMAScript语言:表达式(ECMAScript Language: Expressions)#

12.1标识(Identifiers)#

语法(Syntax)

IdentifierReference[Yield]:Identifier [~Yield]yield BindingIdentifier[Yield]:Identifier [~Yield]yield LabelIdentifier[Yield]:Identifier [~Yield]yield Identifier:IdentifierNamebut not ReservedWord(标识符名称,但不保留字)

12.1.1静态语义:早期错误(Static Semantics: Early Errors)#

BindingIdentifier:Identifier
  • 如果与此生产匹配的代码包含在严格模式代码中,并且标识符的StringValue为“arguments”或“eval”,则会出现语法错误。
IdentifierReference:yield BindingIdentifier:yield LabelIdentifier:yield
  • 如果与此生产匹配的代码包含在严格模式代码中,则是语法错误。
IdentifierReference[Yield]:Identifier BindingIdentifier[Yield]:Identifier LabelIdentifier[Yield]:Identifier
  • 如果此生产具有[Yield]参数,并且Identifier的StringValue为“yield”,则会出现语法错误。
Identifier:IdentifierNamebut not ReservedWord
  • 如果此短语包含在严格模式代码中,并且IdentifierName的StringValue为"implements", "interface", "let", "package", "private", "protected", "public", "static", or "yield".
  • 如果IdentifierName的StringValue与任何ReservedWord的StringValue相同(除了yield),则该语法错误除了产出。
Note

IdentifierName的StringValue标准化IdentifierName中的任何Unicode转义序列,因此这种转义不能用于写入其代码点序列与ReservedWord相同的标识符。

12.1.2Static Semantics(静态语义): BoundNames#

BindingIdentifier:Identifier
  1. Return a new List containing the StringValue of Identifier.
BindingIdentifier:yield
  1. Return a new List containing "yield".

12.1.3Static Semantics: IsValidSimpleAssignmentTarget#

IdentifierReference:Identifier
  1. If this IdentifierReference is contained in strict mode code and StringValue of Identifier is "eval" or "arguments", return false.
  2. Return true.
IdentifierReference:yield
  1. Return true.

12.1.4Static Semantics: StringValue#

IdentifierReference:yield BindingIdentifier:yield LabelIdentifier:yield
  1. Return "yield".
Identifier:IdentifierNamebut not ReservedWord
  1. Return the StringValue of IdentifierName.

12.1.5Runtime Semantics: BindingInitialization#

With arguments value and environment.

Note

undefined传递给环境以指示应使用PutValue操作来分配初始化值。 对于一些非严格函数的var语句和形式参数列表(见9.2.12)就是这种情况。 在这些情况下,在对其初始化程序进行执行之前,会悬挂一个词汇绑定并进行初始化。

BindingIdentifier:Identifier
  1. Let name be StringValue of Identifier.
  2. Return ? InitializeBoundName(name, value, environment).
BindingIdentifier:yield
  1. Return ? InitializeBoundName("yield", value, environment).

12.1.5.1Runtime Semantics(运行时语义): InitializeBoundName(name, value, environment)#

  1. Assert: Type(name) is String.
  2. If environment is not undefined, then
    1. Let env be the EnvironmentRecord component of environment.
    2. Perform env.InitializeBinding(name, value).
    3. Return NormalCompletion(undefined).
  3. Else,
    1. Let lhs be ResolveBinding(name).
    2. Return ? PutValue(lhs, value).

12.1.6Runtime Semantics: Evaluation#

IdentifierReference:Identifier
  1. Return ? ResolveBinding(StringValue of Identifier).
IdentifierReference:yield
  1. Return ? ResolveBinding("yield").
Note 1

执行IdentifierReference的结果始终是Reference类型的值。

Note 2

在非严格的代码中,关键字yield可以用作标识符。 执行IdentifierReference生产解决了yield的绑定,就像它是一个Identifier一样。 早期错误限制确保只有非严格代码才能进行此类执行。 关于绑定创建上下文中yield的处理,请参见13.3.1。

12.2主要表达式(Primary Expression)#

Syntax

PrimaryExpression[Yield]:this IdentifierReference[?Yield] Literal ArrayLiteral[?Yield] ObjectLiteral[?Yield] FunctionExpression ClassExpression[?Yield] GeneratorExpression RegularExpressionLiteral TemplateLiteral[?Yield] CoverParenthesizedExpressionAndArrowParameterList[?Yield] CoverParenthesizedExpressionAndArrowParameterList[Yield]:(Expression[In, ?Yield]) () (...BindingIdentifier[?Yield]) (...BindingPattern[?Yield]) (Expression[In, ?Yield],...BindingIdentifier[?Yield]) (Expression[In, ?Yield],...BindingPattern[?Yield])

补充语法

When processing the production
PrimaryExpression[Yield]:CoverParenthesizedExpressionAndArrowParameterList[?Yield]
the interpretation of CoverParenthesizedExpressionAndArrowParameterList is refined using the following grammar:

ParenthesizedExpression[Yield]:(Expression[In, ?Yield])

12.2.1语义(Semantics)#

12.2.1.1Static Semantics: CoveredParenthesizedExpression(括号表达式)#

CoverParenthesizedExpressionAndArrowParameterList[Yield]:(Expression[In, ?Yield])
  1. 根据CoverParenthesizedExpressionAndArrowParameterList匹配时是否存在[Yield]语法参数,返回使用RoundParenthesizedExpressionAndArrowParameterList [Yield]解析词汇符号流的结果,使用“ParenthesizedExpression或 ParenthesizedExpression[Yield] 作为目标符号。

12.2.1.2Static Semantics: HasName#

PrimaryExpression:CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. If IsFunctionDefinition of expr is false, return false.
  3. Return HasName of expr.

12.2.1.3Static Semantics: IsFunctionDefinition#

PrimaryExpression:this IdentifierReference Literal ArrayLiteral ObjectLiteral RegularExpressionLiteral TemplateLiteral
  1. Return false.
PrimaryExpression:CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return IsFunctionDefinition of expr.

12.2.1.4Static Semantics: IsIdentifierRef#

PrimaryExpression:IdentifierReference
  1. Return true.
PrimaryExpression:this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression RegularExpressionLiteral TemplateLiteral CoverParenthesizedExpressionAndArrowParameterList
  1. Return false.

12.2.1.5Static Semantics: IsValidSimpleAssignmentTarget#

PrimaryExpression:this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression RegularExpressionLiteral TemplateLiteral
  1. Return false.
PrimaryExpression:CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return IsValidSimpleAssignmentTarget of expr.

12.2.2(this关键字)The this Keyword#

12.2.2.1Runtime Semantics: Evaluation#

PrimaryExpression:this
  1. Return ? ResolveThisBinding( ).

12.2.3Identifier Reference#

See 12.1 for IdentifierReference.

12.2.4字面(Literals)#

Syntax

Literal:NullLiteral BooleanLiteral NumericLiteral StringLiteral

12.2.4.1Runtime Semantics: Evaluation#

Literal:NullLiteral
  1. Return null.
Literal:BooleanLiteral
  1. Return false if BooleanLiteral is the token false.
  2. Return true if BooleanLiteral is the token true.
Literal:NumericLiteral
  1. Return the number whose value is MV of NumericLiteral as defined in 11.8.3.
Literal:StringLiteral
  1. Return the StringValue of StringLiteral as defined in 11.8.4.2.

12.2.5Array Initializer#

Note

ArrayLiteral是一个表达式,描述使用零个或多个表达式的Array对象的初始化,每个表达式都表示一个数组元素,用方括号括起来。 元素不需要是字面量; 每次对数组初始化器运行时,都会进行运行。

数组元素可以在元素列表的开始,中间或末尾被删除。 无论何时元素列表中的逗号前面都没有一个AssignmentExpression(即,在开头或另一个逗号后面的逗号),缺少的数组元素将有助于Array的长度,并增加后续元素的索引。 精确的数组元素未定义。 如果一个元素在数组末尾被消除,该元素不会对Array的长度有贡献。

Syntax

ArrayLiteral[Yield]:[Elisionopt] [ElementList[?Yield]] [ElementList[?Yield],Elisionopt] ElementList[Yield]:ElisionoptAssignmentExpression[In, ?Yield] ElisionoptSpreadElement[?Yield] ElementList[?Yield],ElisionoptAssignmentExpression[In, ?Yield] ElementList[?Yield],ElisionoptSpreadElement[?Yield] Elision:, Elision, SpreadElement[Yield]:...AssignmentExpression[In, ?Yield]

12.2.5.1Static Semantics: ElisionWidth(精度宽度)#

Elision:,
  1. Return the numeric value 1.
Elision:Elision,
  1. Let preceding be the ElisionWidth of Elision.
  2. Return preceding+1.

12.2.5.2Runtime Semantics: ArrayAccumulation(数组积累)#

With parameters array and nextIndex.

ElementList:ElisionoptAssignmentExpression
  1. Let padding be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
  2. Let initResult be the result of evaluating AssignmentExpression.
  3. Let initValue be ? GetValue(initResult).
  4. Let created be CreateDataProperty(array, ToString(ToUint32(nextIndex+padding)), initValue).
  5. Assert: created is true.
  6. Return nextIndex+padding+1.
ElementList:ElisionoptSpreadElement
  1. Let padding be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
  2. Return the result of performing ArrayAccumulation for SpreadElement with arguments array and nextIndex+padding.
ElementList:ElementList,ElisionoptAssignmentExpression
  1. Let postIndex be the result of performing ArrayAccumulation for ElementList with arguments array and nextIndex.
  2. ReturnIfAbrupt(postIndex).
  3. Let padding be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
  4. Let initResult be the result of evaluating AssignmentExpression.
  5. Let initValue be ? GetValue(initResult).
  6. Let created be CreateDataProperty(array, ToString(ToUint32(postIndex+padding)), initValue).
  7. Assert: created is true.
  8. Return postIndex+padding+1.
ElementList:ElementList,ElisionoptSpreadElement
  1. Let postIndex be the result of performing ArrayAccumulation for ElementList with arguments array and nextIndex.
  2. ReturnIfAbrupt(postIndex).
  3. Let padding be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
  4. Return the result of performing ArrayAccumulation for SpreadElement with arguments array and postIndex+padding.
SpreadElement:...AssignmentExpression
  1. Let spreadRef be the result of evaluating AssignmentExpression.
  2. Let spreadObj be ? GetValue(spreadRef).
  3. Let iterator be ? GetIterator(spreadObj).
  4. Repeat
    1. Let next be ? IteratorStep(iterator).
    2. If next is false, return nextIndex.
    3. Let nextValue be ? IteratorValue(next).
    4. Let status be CreateDataProperty(array, ToString(ToUint32(nextIndex)), nextValue).
    5. Assert: status is true.
    6. Let nextIndex be nextIndex + 1.
Note

CreateDataProperty is used to ensure that own properties are defined for the array even if the standard built-in Array prototype object has been modified in a manner that would preclude the creation of new own properties using [[Set]].

12.2.5.3Runtime Semantics: Evaluation(执行)#

ArrayLiteral:[Elisionopt]
  1. Let array be ArrayCreate(0).
  2. Let pad be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
  3. Perform Set(array, "length", ToUint32(pad), false).
  4. NOTE: The above Set cannot fail because of the nature of the object returned by ArrayCreate.
  5. Return array.
ArrayLiteral:[ElementList]
  1. Let array be ArrayCreate(0).
  2. Let len be the result of performing ArrayAccumulation for ElementList with arguments array and 0.
  3. ReturnIfAbrupt(len).
  4. Perform Set(array, "length", ToUint32(len), false).
  5. NOTE: The above Set cannot fail because of the nature of the object returned by ArrayCreate.
  6. Return array.
ArrayLiteral:[ElementList,Elisionopt]
  1. Let array be ArrayCreate(0).
  2. Let len be the result of performing ArrayAccumulation for ElementList with arguments array and 0.
  3. ReturnIfAbrupt(len).
  4. Let padding be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
  5. Perform Set(array, "length", ToUint32(padding+len), false).
  6. NOTE: The above Set cannot fail because of the nature of the object returned by ArrayCreate.
  7. Return array.

12.2.6Object Initializer(对象初始化)#

Note 1

对象初始化是描述Object的初始化的表达式,以类似于文字的形式写入。 它是零或多对属性键和关联值的列表,括在大括号中。 值不需要是字面值; 每次对对象初始化程序进行执行时都会进行执行。

句法

ObjectLiteral(对象字面量)[Yield]:{} {PropertyDefinitionList[?Yield]} {PropertyDefinitionList[?Yield],} PropertyDefinitionList[Yield]:PropertyDefinition[?Yield] PropertyDefinitionList[?Yield],PropertyDefinition[?Yield] PropertyDefinition[Yield]:IdentifierReference[?Yield] CoverInitializedName[?Yield] PropertyName[?Yield]:AssignmentExpression[In, ?Yield] MethodDefinition[?Yield] PropertyName[Yield]:LiteralPropertyName ComputedPropertyName[?Yield] LiteralPropertyName:IdentifierName StringLiteral NumericLiteral ComputedPropertyName[Yield]:[AssignmentExpression[In, ?Yield]] CoverInitializedName[Yield]:IdentifierReference[?Yield]Initializer[In, ?Yield] Initializer[In, Yield]:=AssignmentExpression[?In, ?Yield] Note 2

MethodDefinition is defined in 14.3.

Note 3

在某些上下文中,ObjectLiteral被用作更受限制的辅助语法的覆盖语法。 CoverInitializedName表达式是完全覆盖这些二级语法所必需的。 但是,使用此表达式会导致在正常上下文中预期实际的ObjectLiteral的早期语法错误。

12.2.6.1Static Semantics: Early Errors(静态语义:早期错误)#

PropertyDefinition:MethodDefinition
  • 如果MethodDefinition的HasDirectSuper为true,则为语法错误。

除了描述一个实际的对象初始化器之外,ObjectLiteral的生成也被用作ObjectAssignmentPattern的封面语法。 并且可以被识别为CoverParenthesizedExpressionAndArrowParameterList的一部分。 当ObjectLiteral出现在需要ObjectAssignmentPattern的上下文中时,不会应用以下Early Error规则。 此外,在最初解析CoverParenthesizedExpressionAndArrowParameterList时不会应用它们。

PropertyDefinition:CoverInitializedName
  • 如果代码与此生产相匹配,则始终会引发语法错误。
Note

这种表达式存在,因此ObjectLiteral可以作为ObjectAssignmentPattern的封面语法。 它不会发生在实际的对象初始化程序中。

12.2.6.2Static Semantics: ComputedPropertyContains(静态语义:ComputedPropertyContains)#

With parameter symbol.

PropertyName:LiteralPropertyName
  1. Return false.
PropertyName:ComputedPropertyName
  1. Return the result of ComputedPropertyName Contains symbol.

12.2.6.3Static Semantics: Contains#

With parameter symbol.

PropertyDefinition:MethodDefinition
  1. If symbol is MethodDefinition, return true.
  2. Return the result of ComputedPropertyContains for MethodDefinition with argument symbol.
Note

依赖于子结构的静态语义规则通常不考虑函数定义

LiteralPropertyName:IdentifierName
  1. If symbol is a ReservedWord, return false.
  2. If symbol is an Identifier and StringValue of symbol is the same value as the StringValue of IdentifierName, return true.
  3. Return false.

12.2.6.4Static Semantics: HasComputedPropertyKey#

PropertyDefinitionList:PropertyDefinitionList,PropertyDefinition
  1. If HasComputedPropertyKey of PropertyDefinitionList is true, return true.
  2. Return HasComputedPropertyKey of PropertyDefinition.
PropertyDefinition:IdentifierReference
  1. Return false.
PropertyDefinition:PropertyName:AssignmentExpression
  1. Return IsComputedPropertyKey of PropertyName.

12.2.6.5Static Semantics: IsComputedPropertyKey#

PropertyName:LiteralPropertyName
  1. Return false.
PropertyName:ComputedPropertyName
  1. Return true.

12.2.6.6Static Semantics: PropName#

PropertyDefinition:IdentifierReference
  1. Return StringValue of IdentifierReference.
PropertyDefinition:PropertyName:AssignmentExpression
  1. Return PropName of PropertyName.
LiteralPropertyName:IdentifierName
  1. Return StringValue of IdentifierName.
LiteralPropertyName:StringLiteral
  1. Return a String value whose code units are the SV of the StringLiteral.
LiteralPropertyName:NumericLiteral
  1. Let nbr be the result of forming the value of the NumericLiteral.
  2. Return ! ToString(nbr).
ComputedPropertyName:[AssignmentExpression]
  1. Return empty.

12.2.6.7Static Semantics: PropertyNameList#

PropertyDefinitionList:PropertyDefinition
  1. If PropName of PropertyDefinition is empty, return a new empty List.
  2. Return a new List containing PropName of PropertyDefinition.
PropertyDefinitionList:PropertyDefinitionList,PropertyDefinition
  1. Let list be PropertyNameList of PropertyDefinitionList.
  2. If PropName of PropertyDefinition is empty, return list.
  3. Append PropName of PropertyDefinition to the end of list.
  4. Return list.

12.2.6.8Runtime Semantics(运行时语义): Evaluation(执行)#

ObjectLiteral:{}
  1. Return ObjectCreate(%ObjectPrototype%).
ObjectLiteral:{PropertyDefinitionList} {PropertyDefinitionList,}
  1. Let obj be ObjectCreate(%ObjectPrototype%).
  2. Let status be the result of performing PropertyDefinitionEvaluation of PropertyDefinitionList with arguments obj and true.
  3. ReturnIfAbrupt(status).
  4. Return obj.
LiteralPropertyName:IdentifierName
  1. Return StringValue of IdentifierName.
LiteralPropertyName:StringLiteral
  1. Return a String value whose code units are the SV of the StringLiteral.
LiteralPropertyName:NumericLiteral
  1. Let nbr be the result of forming the value of the NumericLiteral.
  2. Return ! ToString(nbr).
ComputedPropertyName:[AssignmentExpression]
  1. Let exprValue be the result of evaluating AssignmentExpression.
  2. Let propName be ? GetValue(exprValue).
  3. Return ? ToPropertyKey(propName).

12.2.6.9Runtime Semantics: PropertyDefinitionEvaluation(属性定义执行)#

With parameters object and enumerable.

PropertyDefinitionList:PropertyDefinitionList,PropertyDefinition
  1. Let status be the result of performing PropertyDefinitionEvaluation of PropertyDefinitionList with arguments object and enumerable.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing PropertyDefinitionEvaluation of PropertyDefinition with arguments object and enumerable.
PropertyDefinition:IdentifierReference
  1. Let propName be StringValue of IdentifierReference.
  2. Let exprValue be the result of evaluating IdentifierReference.
  3. Let propValue be ? GetValue(exprValue).
  4. Assert: enumerable is true.
  5. Return CreateDataPropertyOrThrow(object, propName, propValue).
PropertyDefinition:PropertyName:AssignmentExpression
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. Let exprValueRef be the result of evaluating AssignmentExpression.
  4. Let propValue be ? GetValue(exprValueRef).
  5. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
    1. Let hasNameProperty be ? HasOwnProperty(propValue, "name").
    2. If hasNameProperty is false, perform SetFunctionName(propValue, propKey).
  6. Assert: enumerable is true.
  7. Return CreateDataPropertyOrThrow(object, propKey, propValue).
Note

B.3.1给出了这种表达式的另一种语义。

12.2.7Function Defining Expressions#

See 14.1 for PrimaryExpression:FunctionExpression .

See 14.4 for PrimaryExpression:GeneratorExpression .

See 14.5 for PrimaryExpression:ClassExpression .

12.2.8Regular Expression Literals(正则表达式字面量)#

Syntax(语法)

See 11.8.5.

12.2.8.1静态语义:早期错误#

PrimaryExpression:RegularExpressionLiteral
  • 如果无法使用21.2.1中指定的ECMAScript RegExp语法的目标符号模式识别RegularExpressionLiteral的BodyText,则会出现语法错误。
  • 如果RegularExpressionLiteral的FlagText包含除“g”,“i”,“m”,“u”或“y”之外的任何代码点,或者如果它包含相同的代码点( code point)不止一次,则这是一个语法错误。

12.2.8.2运行时语义:执行#

PrimaryExpression:RegularExpressionLiteral
  1. pattern是由RegularExpressionLiteral的BodyText的每个代码点的UTF16编码组成的String值。
  2. 让flags是由RegularExpressionLiteral的FlagText的每个代码点的UTF16编码组成的String值。
  3. Return RegExpCreate(pattern, flags).

12.2.9Template Literals(模板字面量)#

语法

TemplateLiteral[Yield]:NoSubstitutionTemplate TemplateHeadExpression[In, ?Yield]TemplateSpans[?Yield] TemplateSpans[Yield]:TemplateTail TemplateMiddleList[?Yield]TemplateTail TemplateMiddleList[Yield]:TemplateMiddleExpression[In, ?Yield] TemplateMiddleList[?Yield]TemplateMiddleExpression[In, ?Yield]

12.2.9.1Static Semantics: TemplateStrings#

With parameter raw.

TemplateLiteral:NoSubstitutionTemplate
  1. If raw is false, then
    1. Let string be the TV of NoSubstitutionTemplate.
  2. Else,
    1. Let string be the TRV of NoSubstitutionTemplate.
  3. Return a List containing the single element, string.
TemplateLiteral:TemplateHeadExpressionTemplateSpans
  1. If raw is false, then
    1. Let head be the TV of TemplateHead.
  2. Else,
    1. Let head be the TRV of TemplateHead.
  3. Let tail be TemplateStrings of TemplateSpans with argument raw.
  4. Return a List containing head followed by the elements, in order, of tail.
TemplateSpans:TemplateTail
  1. If raw is false, then
    1. Let tail be the TV of TemplateTail.
  2. Else,
    1. Let tail be the TRV of TemplateTail.
  3. Return a List containing the single element, tail.
TemplateSpans:TemplateMiddleListTemplateTail
  1. Let middle be TemplateStrings of TemplateMiddleList with argument raw.
  2. If raw is false, then
    1. Let tail be the TV of TemplateTail.
  3. Else,
    1. Let tail be the TRV of TemplateTail.
  4. Return a List containing the elements, in order, of middle followed by tail.
TemplateMiddleList:TemplateMiddleExpression
  1. If raw is false, then
    1. Let string be the TV of TemplateMiddle.
  2. Else,
    1. Let string be the TRV of TemplateMiddle.
  3. Return a List containing the single element, string.
TemplateMiddleList:TemplateMiddleListTemplateMiddleExpression
  1. Let front be TemplateStrings of TemplateMiddleList with argument raw.
  2. If raw is false, then
    1. Let last be the TV of TemplateMiddle.
  3. Else,
    1. Let last be the TRV of TemplateMiddle.
  4. Append last as the last element of the List front.
  5. Return front.

12.2.9.2Runtime Semantics: ArgumentListEvaluation#

TemplateLiteral:NoSubstitutionTemplate
  1. Let templateLiteral be this TemplateLiteral.
  2. Let siteObj be GetTemplateObject(templateLiteral).
  3. Return a List containing the one element which is siteObj.
TemplateLiteral:TemplateHeadExpressionTemplateSpans
  1. Let templateLiteral be this TemplateLiteral.
  2. Let siteObj be GetTemplateObject(templateLiteral).
  3. Let firstSub be the result of evaluating Expression.
  4. ReturnIfAbrupt(firstSub).
  5. Let restSub be SubstitutionEvaluation of TemplateSpans.
  6. ReturnIfAbrupt(restSub).
  7. Assert: restSub is a List.
  8. Return a List whose first element is siteObj, whose second elements is firstSub, and whose subsequent elements are the elements of restSub, in order. restSub may contain no elements.

12.2.9.3Runtime Semantics: GetTemplateObject ( templateLiteral )#

The abstract operation GetTemplateObject is called with a grammar production, templateLiteral, as an argument. It performs the following steps:

  1. Let rawStrings be TemplateStrings of templateLiteral with argument true.
  2. Let realm be the current Realm Record.
  3. Let templateRegistry be realm.[[TemplateMap]].
  4. For each element e of templateRegistry, do
    1. If e.[[Strings]] and rawStrings contain the same values in the same order, then
      1. Return e.[[Array]].
  5. Let cookedStrings be TemplateStrings of templateLiteral with argument false.
  6. Let count be the number of elements in the List cookedStrings.
  7. Let template be ArrayCreate(count).
  8. Let rawObj be ArrayCreate(count).
  9. Let index be 0.
  10. Repeat while index < count
    1. Let prop be ! ToString(index).
    2. Let cookedValue be the String value cookedStrings[index].
    3. Call template.[[DefineOwnProperty]](prop, PropertyDescriptor{[[Value]]: cookedValue, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false}).
    4. Let rawValue be the String value rawStrings[index].
    5. Call rawObj.[[DefineOwnProperty]](prop, PropertyDescriptor{[[Value]]: rawValue, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false}).
    6. Let index be index+1.
  11. Perform SetIntegrityLevel(rawObj, "frozen").
  12. Call template.[[DefineOwnProperty]]("raw", PropertyDescriptor{[[Value]]: rawObj, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false}).
  13. Perform SetIntegrityLevel(template, "frozen").
  14. Append the Record{[[Strings]]: rawStrings, [[Array]]: template} to templateRegistry.
  15. Return template.
Note 1

The creation of a template object cannot result in an abrupt completion.

Note 2

Each TemplateLiteral in the program code of a realm is associated with a unique template object that is used in the evaluation of tagged Templates (12.2.9.5). The template objects are frozen and the same template object is used each time a specific tagged Template is evaluated. Whether template objects are created lazily upon first evaluation of the TemplateLiteral or eagerly prior to first evaluation is an implementation choice that is not observable to ECMAScript code.

Note 3

Future editions of this specification may define additional non-enumerable properties of template objects.

12.2.9.4Runtime Semantics: SubstitutionEvaluation#

TemplateSpans:TemplateTail
  1. Return a new empty List.
TemplateSpans:TemplateMiddleListTemplateTail
  1. Return the result of SubstitutionEvaluation of TemplateMiddleList.
TemplateMiddleList:TemplateMiddleExpression
  1. Let sub be the result of evaluating Expression.
  2. ReturnIfAbrupt(sub).
  3. Return a List containing only sub.
TemplateMiddleList:TemplateMiddleListTemplateMiddleExpression
  1. Let preceding be the result of SubstitutionEvaluation of TemplateMiddleList.
  2. ReturnIfAbrupt(preceding).
  3. Let next be the result of evaluating Expression.
  4. ReturnIfAbrupt(next).
  5. Append next as the last element of the List preceding.
  6. Return preceding.

12.2.9.5Runtime Semantics: Evaluation#

TemplateLiteral:NoSubstitutionTemplate
  1. Return the String value whose code units are the elements of the TV of NoSubstitutionTemplate as defined in 11.8.6.
TemplateLiteral:TemplateHeadExpressionTemplateSpans
  1. Let head be the TV of TemplateHead as defined in 11.8.6.
  2. Let sub be the result of evaluating Expression.
  3. ReturnIfAbrupt(sub).
  4. Let middle be ? ToString(sub).
  5. Let tail be the result of evaluating TemplateSpans.
  6. ReturnIfAbrupt(tail).
  7. Return the String value whose code units are the elements of head followed by the elements of middle followed by the elements of tail.
Note 1

The string conversion semantics applied to the Expression value are like String.prototype.concat rather than the + operator.

TemplateSpans:TemplateTail
  1. Let tail be the TV of TemplateTail as defined in 11.8.6.
  2. Return the string consisting of the code units of tail.
TemplateSpans:TemplateMiddleListTemplateTail
  1. Let head be the result of evaluating TemplateMiddleList.
  2. ReturnIfAbrupt(head).
  3. Let tail be the TV of TemplateTail as defined in 11.8.6.
  4. Return the string whose code units are the elements of head followed by the elements of tail.
TemplateMiddleList:TemplateMiddleExpression
  1. Let head be the TV of TemplateMiddle as defined in 11.8.6.
  2. Let sub be the result of evaluating Expression.
  3. ReturnIfAbrupt(sub).
  4. Let middle be ? ToString(sub).
  5. Return the sequence of code units consisting of the code units of head followed by the elements of middle.
Note 2

The string conversion semantics applied to the Expression value are like String.prototype.concat rather than the + operator.

TemplateMiddleList:TemplateMiddleListTemplateMiddleExpression
  1. Let rest be the result of evaluating TemplateMiddleList.
  2. ReturnIfAbrupt(rest).
  3. Let middle be the TV of TemplateMiddle as defined in 11.8.6.
  4. Let sub be the result of evaluating Expression.
  5. ReturnIfAbrupt(sub).
  6. Let last be ? ToString(sub).
  7. Return the sequence of code units consisting of the elements of rest followed by the code units of middle followed by the elements of last.
Note 3

The string conversion semantics applied to the Expression value are like String.prototype.concat rather than the + operator.

12.2.10The Grouping Operator(分组运算)#

12.2.10.1Static Semantics: Early Errors#

PrimaryExpression:CoverParenthesizedExpressionAndArrowParameterList(覆盖括号表达式和箭头参数列表)
  • 如果由CoverParenthesizedExpressionAndArrowParameterList匹配的词法令牌序列在没有使用“括号符”作为令牌时,不能被解析,则是一个语法错误
  • ParenthesizedExpression及其衍生作品的所有早期错误规则也适用于CoverParenthesizedExpressionAndArrowParameterList的CoveredParenthesizedExpression。

12.2.10.2Static Semantics: IsFunctionDefinition#

ParenthesizedExpression:(Expression)
  1. Return IsFunctionDefinition of Expression.

12.2.10.3Static Semantics: IsValidSimpleAssignmentTarget#

ParenthesizedExpression:(Expression)
  1. Return IsValidSimpleAssignmentTarget of Expression.

12.2.10.4Runtime Semantics: Evaluation#

PrimaryExpression:CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return the result of evaluating expr.
ParenthesizedExpression:(Expression)
  1. Return the result of evaluating Expression. This may be of type Reference.
Note

该算法不对GetValue应用于执行Expression的结果。 这样做的主要动机是使delete和typeof可以应用于括号表达式。

12.3Left-Hand-Side Expressions(左表达式)#

Syntax

MemberExpression[Yield]:PrimaryExpression[?Yield] MemberExpression[?Yield][Expression[In, ?Yield]] MemberExpression[?Yield].IdentifierName MemberExpression[?Yield]TemplateLiteral[?Yield] SuperProperty[?Yield] MetaProperty newMemberExpression[?Yield]Arguments[?Yield] SuperProperty[Yield]:super[Expression[In, ?Yield]] super.IdentifierName MetaProperty:NewTarget NewTarget:new.target NewExpression[Yield]:MemberExpression[?Yield] newNewExpression[?Yield] CallExpression[Yield]:MemberExpression[?Yield]Arguments[?Yield] SuperCall[?Yield] CallExpression[?Yield]Arguments[?Yield] CallExpression[?Yield][Expression[In, ?Yield]] CallExpression[?Yield].IdentifierName CallExpression[?Yield]TemplateLiteral[?Yield] SuperCall[Yield]:superArguments[?Yield] Arguments[Yield]:() (ArgumentList[?Yield]) ArgumentList[Yield]:AssignmentExpression[In, ?Yield] ...AssignmentExpression[In, ?Yield] ArgumentList[?Yield],AssignmentExpression[In, ?Yield] ArgumentList[?Yield],...AssignmentExpression[In, ?Yield] LeftHandSideExpression[Yield]:NewExpression[?Yield] CallExpression[?Yield]

12.3.1Static Semantics#

12.3.1.1Static Semantics: Contains#

With parameter symbol.

MemberExpression:MemberExpression.IdentifierName
  1. If MemberExpression Contains symbol is true, return true.
  2. If symbol is a ReservedWord, return false.
  3. If symbol is an Identifier and StringValue of symbol is the same value as the StringValue of IdentifierName, return true.
  4. Return false.
SuperProperty:super.IdentifierName
  1. If symbol is the ReservedWord super, return true.
  2. If symbol is a ReservedWord, return false.
  3. If symbol is an Identifier and StringValue of symbol is the same value as the StringValue of IdentifierName, return true.
  4. Return false.
CallExpression:CallExpression.IdentifierName
  1. If CallExpression Contains symbol is true, return true.
  2. If symbol is a ReservedWord, return false.
  3. If symbol is an Identifier and StringValue of symbol is the same value as the StringValue of IdentifierName, return true.
  4. Return false.

12.3.1.2Static Semantics: IsFunctionDefinition#

MemberExpression:MemberExpression[Expression] MemberExpression.IdentifierName MemberExpressionTemplateLiteral SuperProperty MetaProperty newMemberExpressionArguments NewExpression:newNewExpression CallExpression:MemberExpressionArguments SuperCall CallExpressionArguments CallExpression[Expression] CallExpression.IdentifierName CallExpressionTemplateLiteral
  1. Return false.

12.3.1.3Static Semantics: IsDestructuring#

MemberExpression:PrimaryExpression
  1. If PrimaryExpression is either an ObjectLiteral or an ArrayLiteral, return true.(如果PrimaryExpression是ObjectLiteral或ArrayLiteral,则返回true)
  2. Return false.
MemberExpression:MemberExpression[Expression] MemberExpression.IdentifierName MemberExpressionTemplateLiteral SuperProperty MetaProperty newMemberExpressionArguments NewExpression:newNewExpression CallExpression:MemberExpressionArguments SuperCall CallExpressionArguments CallExpression[Expression] CallExpression.IdentifierName CallExpressionTemplateLiteral
  1. Return false.

12.3.1.4Static Semantics: IsIdentifierRef#

LeftHandSideExpression:CallExpression MemberExpression:MemberExpression[Expression] MemberExpression.IdentifierName MemberExpressionTemplateLiteral SuperProperty MetaProperty newMemberExpressionArguments NewExpression:newNewExpression
  1. Return false.

12.3.1.5Static Semantics: IsValidSimpleAssignmentTarget#

CallExpression:CallExpression[Expression] CallExpression.IdentifierName MemberExpression:MemberExpression[Expression] MemberExpression.IdentifierName SuperProperty
  1. Return true.
CallExpression:MemberExpressionArguments SuperCall CallExpressionArguments CallExpressionTemplateLiteral NewExpression:newNewExpression MemberExpression:MemberExpressionTemplateLiteral newMemberExpressionArguments NewTarget:new.target
  1. Return false.

12.3.2Property Accessors(属性访问者)#

Note

Properties are accessed by name, using either the dot notation:(通过名称访问属性,使用点符号)

or the bracket notation(或括号符号):

The dot notation is explained by the following syntactic conversion(点符号由以下句法转换来解释):

is identical in its behaviour to(在其行为上是相同的)

MemberExpression [ <identifier-name-string> ]

and similarly(同样地)

is identical in its behaviour to(在其行为上是相同的)

CallExpression [ <identifier-name-string> ]

其中是执行IdentifierName的StringValue的结果。

12.3.2.1Runtime Semantics: Evaluation#

MemberExpression:MemberExpression[Expression]
  1. Let baseReference be the result of evaluating MemberExpression.
  2. Let baseValue be ? GetValue(baseReference).
  3. Let propertyNameReference be the result of evaluating Expression.
  4. Let propertyNameValue be ? GetValue(propertyNameReference).
  5. Let bv be ? RequireObjectCoercible(baseValue).
  6. Let propertyKey be ? ToPropertyKey(propertyNameValue).
  7. If the code matched by the syntactic production that is being evaluated is strict mode code, let strict be true, else let strict be false.
  8. Return a value of type Reference whose base value is bv, whose referenced name is propertyKey, and whose strict reference flag is strict.
MemberExpression:MemberExpression.IdentifierName
  1. Let baseReference be the result of evaluating MemberExpression.
  2. Let baseValue be ? GetValue(baseReference).
  3. Let bv be ? RequireObjectCoercible(baseValue).
  4. Let propertyNameString be StringValue of IdentifierName.
  5. If the code matched by the syntactic production that is being evaluated is strict mode code, let strict be true, else let strict be false.
  6. Return a value of type Reference whose base value is bv, whose referenced name is propertyNameString, and whose strict reference flag is strict.
CallExpression:CallExpression[Expression]

Is evaluated in exactly the same manner as MemberExpression:MemberExpression[Expression] except that the contained CallExpression is evaluated in step 1.

CallExpression:CallExpression.IdentifierName

Is evaluated in exactly the same manner as MemberExpression:MemberExpression.IdentifierName except that the contained CallExpression is evaluated in step 1.

12.3.3The new Operator#

12.3.3.1Runtime Semantics: Evaluation(运行时语义:执行)#

NewExpression:newNewExpression
  1. Return ? EvaluateNew(NewExpression, empty).
MemberExpression:newMemberExpressionArguments
  1. Return ? EvaluateNew(MemberExpression, Arguments).

12.3.3.1.1Runtime Semantics: EvaluateNew(constructProduction, arguments)#

The abstract operation EvaluateNew with arguments constructProduction, and arguments performs the following steps:

  1. Assert: constructProduction is either a NewExpression or a MemberExpression.
  2. Assert: arguments is either empty or an Arguments production.
  3. Let ref be the result of evaluating constructProduction.
  4. Let constructor be ? GetValue(ref).
  5. If arguments is empty, let argList be a new empty List.
  6. Else,
    1. Let argList be ArgumentListEvaluation of arguments.
    2. ReturnIfAbrupt(argList).
  7. If IsConstructor(constructor) is false, throw a TypeError exception.
  8. Return ? Construct(constructor, argList).

12.3.4Function Calls(函数调用)#

12.3.4.1Runtime Semantics: Evaluation#

CallExpression:MemberExpressionArguments
  1. Let ref be the result of evaluating MemberExpression.
  2. Let func be ? GetValue(ref).
  3. If Type(ref) is Reference and IsPropertyReference(ref) is false and GetReferencedName(ref) is "eval", then
    1. If SameValue(func, %eval%) is true, then
      1. Let argList be ? ArgumentListEvaluation(Arguments).
      2. If argList has no elements, return undefined.
      3. Let evalText be the first element of argList.
      4. If the source code matching this CallExpression is strict code, let strictCaller be true. Otherwise let strictCaller be false.
      5. Let evalRealm be the current Realm Record.
      6. Return ? PerformEval(evalText, evalRealm, strictCaller, true).
  4. If Type(ref) is Reference, then
    1. If IsPropertyReference(ref) is true, then
      1. Let thisValue be GetThisValue(ref).
    2. Else, the base of ref is an Environment Record
      1. Let refEnv be GetBase(ref).
      2. Let thisValue be refEnv.WithBaseObject().
  5. Else Type(ref) is not Reference,
    1. Let thisValue be undefined.
  6. Let thisCall be this CallExpression.
  7. Let tailCall be IsInTailPosition(thisCall).
  8. Return ? EvaluateDirectCall(func, thisValue, Arguments, tailCall).

A CallExpression evaluation that executes step 3.a.vi is a direct eval.

CallExpression:CallExpressionArguments
  1. Let ref be the result of evaluating CallExpression.
  2. Let thisCall be this CallExpression.
  3. Let tailCall be IsInTailPosition(thisCall).
  4. Return ? EvaluateCall(ref, Arguments, tailCall).

12.3.4.2Runtime Semantics: EvaluateCall( ref, arguments, tailPosition )#

The abstract operation EvaluateCall takes as arguments a value ref, a syntactic grammar production arguments, and a Boolean argument tailPosition. It performs the following steps:

  1. Let func be ? GetValue(ref).
  2. If Type(ref) is Reference, then
    1. If IsPropertyReference(ref) is true, then
      1. Let thisValue be GetThisValue(ref).
    2. Else, the base of ref is an Environment Record
      1. Let refEnv be GetBase(ref).
      2. Let thisValue be refEnv.WithBaseObject().
  3. Else Type(ref) is not Reference,
    1. Let thisValue be undefined.
  4. Return ? EvaluateDirectCall(func, thisValue, arguments, tailPosition).

12.3.4.3Runtime Semantics: EvaluateDirectCall( func, thisValue, arguments, tailPosition )#

The abstract operation EvaluateDirectCall takes as arguments a value func, a value thisValue, a syntactic grammar production arguments, and a Boolean argument tailPosition. It performs the following steps:

  1. Let argList be ? ArgumentListEvaluation(arguments).
  2. If Type(func) is not Object, throw a TypeError exception.
  3. If IsCallable(func) is false, throw a TypeError exception.
  4. If tailPosition is true, perform PrepareForTailCall().
  5. Let result be Call(func, thisValue, argList).
  6. Assert: If tailPosition is true, the above call will not return here, but instead evaluation will continue as if the following return has already occurred.
  7. Assert: If result is not an abrupt completion, then Type(result) is an ECMAScript language type.
  8. Return result.

12.3.5The super Keyword(super关键字)#

12.3.5.1Runtime Semantics: Evaluation#

SuperProperty:super[Expression]
  1. Let propertyNameReference be the result of evaluating Expression.
  2. Let propertyNameValue be GetValue(propertyNameReference).
  3. Let propertyKey be ? ToPropertyKey(propertyNameValue).
  4. If the code matched by the syntactic production that is being evaluated is strict mode code, let strict be true, else let strict be false.
  5. Return ? MakeSuperPropertyReference(propertyKey, strict).
SuperProperty:super.IdentifierName
  1. Let propertyKey be StringValue of IdentifierName.
  2. If the code matched by the syntactic production that is being evaluated is strict mode code, let strict be true, else let strict be false.
  3. Return ? MakeSuperPropertyReference(propertyKey, strict).
SuperCall:superArguments
  1. Let newTarget be GetNewTarget().
  2. If newTarget is undefined, throw a ReferenceError exception.
  3. Let func be ? GetSuperConstructor().
  4. Let argList be ArgumentListEvaluation of Arguments.
  5. ReturnIfAbrupt(argList).
  6. Let result be ? Construct(func, argList, newTarget).
  7. Let thisER be GetThisEnvironment( ).
  8. Return ? thisER.BindThisValue(result).

12.3.5.2Runtime Semantics: GetSuperConstructor ( )#

The abstract operation GetSuperConstructor performs the following steps:

  1. Let envRec be GetThisEnvironment( ).
  2. Assert: envRec is a function Environment Record.
  3. Let activeFunction be envRec.[[FunctionObject]].
  4. Let superConstructor be ? activeFunction.[[GetPrototypeOf]]().
  5. If IsConstructor(superConstructor) is false, throw a TypeError exception.
  6. Return superConstructor.

12.3.5.3Runtime Semantics: MakeSuperPropertyReference(propertyKey, strict)#

The abstract operation MakeSuperPropertyReference with arguments propertyKey and strict performs the following steps:

  1. Let env be GetThisEnvironment( ).
  2. If env.HasSuperBinding() is false, throw a ReferenceError exception.
  3. Let actualThis be ? env.GetThisBinding().
  4. Let baseValue be ? env.GetSuperBase().
  5. Let bv be ? RequireObjectCoercible(baseValue).
  6. Return a value of type Reference that is a Super Reference whose base value is bv, whose referenced name is propertyKey, whose thisValue is actualThis, and whose strict reference flag is strict.

12.3.6Argument Lists(参数列表)#

Note

参数列表的执行产生一个值列表。

12.3.6.1Runtime Semantics: ArgumentListEvaluation#

Arguments:()
  1. Return a new empty List.
ArgumentList:AssignmentExpression
  1. Let ref be the result of evaluating AssignmentExpression.
  2. Let arg be ? GetValue(ref).
  3. Return a List whose sole item is arg.
ArgumentList:...AssignmentExpression
  1. Let list be a new empty List.
  2. Let spreadRef be the result of evaluating AssignmentExpression.
  3. Let spreadObj be ? GetValue(spreadRef).
  4. Let iterator be ? GetIterator(spreadObj).
  5. Repeat
    1. Let next be ? IteratorStep(iterator).
    2. If next is false, return list.
    3. Let nextArg be ? IteratorValue(next).
    4. Append nextArg as the last element of list.
ArgumentList:ArgumentList,AssignmentExpression
  1. Let precedingArgs be the result of evaluating ArgumentList.
  2. ReturnIfAbrupt(precedingArgs).
  3. Let ref be the result of evaluating AssignmentExpression.
  4. Let arg be ? GetValue(ref).
  5. Append arg to the end of precedingArgs.
  6. Return precedingArgs.
ArgumentList:ArgumentList,...AssignmentExpression
  1. Let precedingArgs be the result of evaluating ArgumentList.
  2. Let spreadRef be the result of evaluating AssignmentExpression.
  3. Let iterator be ? GetIterator(? GetValue(spreadRef)).
  4. Repeat
    1. Let next be ? IteratorStep(iterator).
    2. If next is false, return precedingArgs.
    3. Let nextArg be ? IteratorValue(next).
    4. Append nextArg as the last element of precedingArgs.

12.3.7Tagged Templates(标记模板)#

Note

标记的模板是一个函数调用,其中调用的参数来自TemplateLiteral (12.2.9)。 实际参数包括一个模板对象(12.2.9.3)以及通过执行嵌入在TemplateLiteral中的表达式产生的值。

12.3.7.1Runtime Semantics: Evaluation#

MemberExpression:MemberExpressionTemplateLiteral
  1. Let tagRef be the result of evaluating MemberExpression.
  2. Let thisCall be this MemberExpression.
  3. Let tailCall be IsInTailPosition(thisCall).
  4. Return ? EvaluateCall(tagRef, TemplateLiteral, tailCall).
CallExpression:CallExpressionTemplateLiteral
  1. Let tagRef be the result of evaluating CallExpression.
  2. Let thisCall be this CallExpression.
  3. Let tailCall be IsInTailPosition(thisCall).
  4. Return ? EvaluateCall(tagRef, TemplateLiteral, tailCall).

12.3.8Meta Properties(元属性)#

12.3.8.1Runtime Semantics: Evaluation#

NewTarget:new.target
  1. Return GetNewTarget().

12.4Update Expressions(更新表达式)#

Syntax

UpdateExpression[Yield]:LeftHandSideExpression[?Yield] LeftHandSideExpression[?Yield][no LineTerminator here]++ LeftHandSideExpression[?Yield][no LineTerminator here]-- ++UnaryExpression[?Yield] --UnaryExpression[?Yield]

12.4.1Static Semantics: Early Errors#

UpdateExpression:LeftHandSideExpression++ LeftHandSideExpression-- UpdateExpression:++UnaryExpression --UnaryExpression

12.4.2Static Semantics: IsFunctionDefinition#

UpdateExpression:LeftHandSideExpression++ LeftHandSideExpression-- ++UnaryExpression --UnaryExpression
  1. Return false.

12.4.3Static Semantics: IsValidSimpleAssignmentTarget#

UpdateExpression:LeftHandSideExpression++ LeftHandSideExpression-- ++UnaryExpression --UnaryExpression
  1. Return false.

12.4.4Postfix Increment Operator#

12.4.4.1Runtime Semantics: Evaluation#

UpdateExpression:LeftHandSideExpression++
  1. Let lhs be the result of evaluating LeftHandSideExpression.
  2. Let oldValue be ? ToNumber(? GetValue(lhs)).
  3. Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the + operator (see 12.8.5).
  4. Perform ? PutValue(lhs, newValue).
  5. Return oldValue.

12.4.5Postfix Decrement Operator(后缀增量运算符)#

12.4.5.1Runtime Semantics: Evaluation#

UpdateExpression:LeftHandSideExpression--
  1. Let lhs be the result of evaluating LeftHandSideExpression.
  2. Let oldValue be ? ToNumber(? GetValue(lhs)).
  3. Let newValue be the result of subtracting the value 1 from oldValue, using the same rules as for the - operator (see 12.8.5).
  4. Perform ? PutValue(lhs, newValue).
  5. Return oldValue.

12.4.6Prefix Increment Operator#

12.4.6.1Runtime Semantics: Evaluation#

UpdateExpression:++UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Let oldValue be ? ToNumber(? GetValue(expr)).
  3. Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the + operator (see 12.8.5).
  4. Perform ? PutValue(expr, newValue).
  5. Return newValue.

12.4.7Prefix Decrement Operator#

12.4.7.1Runtime Semantics: Evaluation#

UpdateExpression:--UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Let oldValue be ? ToNumber(? GetValue(expr)).
  3. Let newValue be the result of subtracting the value 1 from oldValue, using the same rules as for the - operator (see 12.8.5).
  4. Perform ? PutValue(expr, newValue).
  5. Return newValue.

12.5Unary Operators#

Syntax

UnaryExpression[Yield]:UpdateExpression[?Yield] deleteUnaryExpression[?Yield] voidUnaryExpression[?Yield] typeofUnaryExpression[?Yield] +UnaryExpression[?Yield] -UnaryExpression[?Yield] ~UnaryExpression[?Yield] !UnaryExpression[?Yield]

12.5.1Static Semantics: IsFunctionDefinition#

UnaryExpression:UpdateExpression deleteUnaryExpression voidUnaryExpression typeofUnaryExpression +UnaryExpression -UnaryExpression ~UnaryExpression !UnaryExpression
  1. Return false.

12.5.2Static Semantics: IsValidSimpleAssignmentTarget#

UnaryExpression:UpdateExpression deleteUnaryExpression voidUnaryExpression typeofUnaryExpression +UnaryExpression -UnaryExpression ~UnaryExpression !UnaryExpression
  1. Return false.

12.5.3The delete Operator#

12.5.3.1Static Semantics: Early Errors#

UnaryExpression:deleteUnaryExpression Note

The last rule means that expressions such as delete (((foo))) produce early errors because of recursive application of the first rule.

12.5.3.2Runtime Semantics: Evaluation#

UnaryExpression:deleteUnaryExpression
  1. Let ref be the result of evaluating UnaryExpression.
  2. ReturnIfAbrupt(ref).
  3. If Type(ref) is not Reference, return true.
  4. If IsUnresolvableReference(ref) is true, then
    1. Assert: IsStrictReference(ref) is false.
    2. Return true.
  5. If IsPropertyReference(ref) is true, then
    1. If IsSuperReference(ref) is true, throw a ReferenceError exception.
    2. Let baseObj be ! ToObject(GetBase(ref)).
    3. Let deleteStatus be ? baseObj.[[Delete]](GetReferencedName(ref)).
    4. If deleteStatus is false and IsStrictReference(ref) is true, throw a TypeError exception.
    5. Return deleteStatus.
  6. Else ref is a Reference to an Environment Record binding,
    1. Let bindings be GetBase(ref).
    2. Return ? bindings.DeleteBinding(GetReferencedName(ref)).
Note

当严格模式代码中发生delete操作时,如果一元表达式是变量,函数参数或函数名的直接引用,则会引发SyntaxError异常。 另外,如果在严格模式代码中发生删除操作,并且要删除的属性具有属性{[[Configurable]]:false},则抛出TypeError异常。

12.5.4The void Operator#

12.5.4.1Runtime Semantics: Evaluation#

UnaryExpression:voidUnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Perform ? GetValue(expr).
  3. Return undefined.
Note

GetValue 必须调用,即使它的值不被使用,因为它可能具有可观察到的副作用。

12.5.5The typeof Operator#(typeof 操作符)

12.5.5.1Runtime Semantics: Evaluation#

UnaryExpression:typeofUnaryExpression
  1. Let val be the result of evaluating UnaryExpression.
  2. If Type(val) is Reference, then
    1. If IsUnresolvableReference(val) is true, return "undefined".
  3. Let val be ? GetValue(val).
  4. Return a String according to Table 35.
Table 35: typeof Operator Results
Type of val Result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Symbol "symbol"
Object (ordinary and does not implement [[Call]]) 普通且不实现[[Call]]内部方法的对象 "object"
Object (standard exotic and does not implement [[Call]]) 非普通且不实现[[Call]]内部方法的对象 "object"
Object (implements [[Call]]) 实现[[Call]]内部方法的对象 "function"
Object (non-standard exotic and does not implement [[Call]]) 非标准且没有实现[[Call]]的对象 实现定义。 不能是“undefined”,“boolean”,“function”,“number”,“symbol”或“string”。
Note

不鼓励实现对非标准对象定义新的结果值。 如果可能的话"object"应该用于这样的对象。

12.5.6Unary + Operator#(一元+运算符)

Note

The unary + operator converts its operand to Number type.(一元+运算符将其操作数转换为数字类型。)

12.5.6.1Runtime Semantics: Evaluation#

UnaryExpression:+UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Return ? ToNumber(? GetValue(expr)).

12.5.7Unary - Operator#(一元-运算符)

Note

一元运算符将其操作数转换为Number类型,然后将其取反。 取反+0产生-0,-0产生+0。

12.5.7.1Runtime Semantics: Evaluation#

UnaryExpression:-UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Let oldValue be ? ToNumber(? GetValue(expr)).
  3. If oldValue is NaN, return NaN.
  4. Return the result of negating oldValue; that is, compute a Number with the same magnitude but opposite sign.

12.5.8Bitwise NOT Operator ( ~ )#

12.5.8.1Runtime Semantics: Evaluation#

UnaryExpression:~UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Let oldValue be ? ToInt32(? GetValue(expr)).
  3. Return the result of applying bitwise complement to oldValue. The result is a signed 32-bit integer.

12.5.9Logical NOT Operator ( ! )#

12.5.9.1Runtime Semantics: Evaluation#

UnaryExpression:!UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Let oldValue be ToBoolean(? GetValue(expr)).
  3. If oldValue is true, return false.
  4. Return true.

12.6Exponentiation Operator#(指数操作符)

Syntax

ExponentiationExpression[Yield]:UnaryExpression[?Yield] UpdateExpression[?Yield]**ExponentiationExpression[?Yield]

12.6.1Static Semantics: IsFunctionDefinition#

ExponentiationExpression:UpdateExpression**ExponentiationExpression
  1. Return false.

12.6.2Static Semantics: IsValidSimpleAssignmentTarget#

ExponentiationExpression:UpdateExpression**ExponentiationExpression
  1. Return false.

12.6.3Runtime Semantics: Evaluation#

ExponentiationExpression:UpdateExpression**ExponentiationExpression
  1. Let left be the result of evaluating UpdateExpression.
  2. Let leftValue be ? GetValue(left).
  3. Let right be the result of evaluating ExponentiationExpression.
  4. Let rightValue be ? GetValue(right).
  5. Let base be ? ToNumber(leftValue).
  6. Let exponent be ? ToNumber(rightValue).
  7. Return the result of Applying the ** operator with base and exponent as specified in 12.7.3.4.

12.7Multiplicative Operators#(乘数运算符)

Syntax

MultiplicativeExpression[Yield]:ExponentiationExpression[?Yield] MultiplicativeExpression[?Yield]MultiplicativeOperatorExponentiationExpression[?Yield] MultiplicativeOperator:one of*/%

12.7.1Static Semantics: IsFunctionDefinition#

MultiplicativeExpression:MultiplicativeExpressionMultiplicativeOperatorExponentiationExpression
  1. Return false.

12.7.2Static Semantics: IsValidSimpleAssignmentTarget#

MultiplicativeExpression:MultiplicativeExpressionMultiplicativeOperatorExponentiationExpression
  1. Return false.

12.7.3Runtime Semantics: Evaluation#

MultiplicativeExpression:MultiplicativeExpressionMultiplicativeOperatorExponentiationExpression
  1. Let left be the result of evaluating MultiplicativeExpression.
  2. Let leftValue be ? GetValue(left).
  3. Let right be the result of evaluating ExponentiationExpression.
  4. Let rightValue be ? GetValue(right).
  5. Let lnum be ? ToNumber(leftValue).
  6. Let rnum be ? ToNumber(rightValue).
  7. Return the result of applying the MultiplicativeOperator (*, /, or %) to lnum and rnum as specified in 12.7.3.1, 12.7.3.2, or 12.7.3.3.

12.7.3.1Applying the * Operator#(应用*运算符)

*乘法运算符执行乘法,产生其操作数的乘积。乘法是交换的。由于有限精度,乘法并不总是在ECMAScript中关联。

浮点乘法的结果由IEEE 754-2008二进制双精度算术的规则控制:

  • 如果任一操作数是NaN,结果是NaN。
  • 如果两个操作数具有相同的符号,则结果的符号为正,如果操作数具有不同的符号,则为负。
  • 将无穷大乘以零结果为NaN。
  • 无穷大与无穷大的乘积结果为无穷大。符号由上述规则确定。
  • 通过有限非零值乘以无限大可导致带符号无穷大。符号由上述规则确定。
  • 在剩余的情况下,无论是无穷还是NaN,表达式都被计算,并使用IEEE 754-2008近似到最接近的可表示值,最接近偶数模式。如果幅度太大而不能表示,则结果是无穷大的适当标志。如果幅度太小而不能表示,则结果为适当符号的零。 ECMAScript语言需要支持IEEE 754-2008定义的逐步下溢。

12.7.3.2Applying the / Operator#(应用/运算符)

/乘法运算符执行除法,产生其操作数的商。 左操作数是被除数,右操作数是除数。 ECMAScript不执行整数除法。 所有除法运算的操作数和结果都是双精度浮点数。 划分的结果由IEEE 754-2008算术规范确定:

  • If either operand is NaN, the result is NaN.
  • The sign of the result is positive if both operands have the same sign, negative if the operands have different signs.
  • Division of an infinity by an infinity results in NaN.
  • Division of an infinity by a zero results in an infinity. The sign is determined by the rule already stated above.
  • Division of an infinity by a nonzero finite value results in a signed infinity. The sign is determined by the rule already stated above.
  • Division of a finite value by an infinity results in zero. The sign is determined by the rule already stated above.
  • Division of a zero by a zero results in NaN; division of zero by any other finite value results in zero, with the sign determined by the rule already stated above.
  • Division of a nonzero finite value by a zero results in a signed infinity. The sign is determined by the rule already stated above.
  • In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, the quotient is computed and rounded to the nearest representable value using IEEE 754-2008 round to nearest, ties to even mode. If the magnitude is too large to represent, the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of the appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754-2008.
  • 如果任一操作数是NaN,结果是NaN。
  • 如果两个操作数具有相同的符号,则结果的符号为正,如果操作数具有不同的符号,则为负。
  • 无穷大除以无穷大导致NaN。
  • 零除无穷大导致无穷大。符号由上述规则确定。
  • 非零有限值除无穷大导致带符号无穷大。符号由上述规则确定。
  • 无穷大有限值的分数导致零。符号由上述规则确定。
  • 零除以零得到NaN;通过任何其他有限值除零结果为零,其中由上述规则确定的符号。
  • 一个零除非零有限值导致一个有符号的无穷大。符号由上述规则确定。
  • 在剩余的情况下,既不涉及无穷大,也不包括零,也不涉及NaN,则使用IEEE 754-2008循环计算商并将其舍入为最接近的可表示值,最接近偶数模式。如果幅度太大而无法表示,则操作溢出;结果是一个无穷大的适当标志。如果幅度太小而不能表示,则操作下降,结果为适当符号的零。 ECMAScript语言需要支持IEEE 754-2008定义的逐步下溢。

12.7.3.3Applying the % Operator#(应用%运算符)

%MultiplicativeOperator从隐含的除法中产生余数的操作数; 左操作数被除数,右操作数是除数。

Note

在C和C ++中,余数运算符只接受整数操作数; 在ECMAScript中,它也接受浮点操作数。

T由%运算符计算的浮点余数运算的结果与IEEE 754-2008定义的“余数”运算不同。 IEEE 754-2008“余数”操作计算来自舍入除法的余数,而不是截断除法,因此其行为与通常的整数余数运算符的行为不同。 相反,ECMAScript语言将浮点运算的%定义为与Java整数余数运算符类似的方式运行; 这可能与C库函数fmod进行比较。

ECMAScript浮点余数运算的结果由IEEE算法的规则确定:

  • If either operand is NaN, the result is NaN.
  • The sign of the result equals the sign of the dividend.
  • If the dividend is an infinity, or the divisor is a zero, or both, the result is NaN.
  • If the dividend is finite and the divisor is an infinity, the result equals the dividend.
  • If the dividend is a zero and the divisor is nonzero and finite, the result is the same as the dividend.
  • In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, the floating-point remainder r from a dividend n and a divisor d is defined by the mathematical relation r = n - (d × q) where q is an integer that is negative only if n/d is negative and positive only if n/d is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of n and d. r is computed and rounded to the nearest representable value using IEEE 754-2008 round to nearest, ties to even mode.
  • 如果任一操作数是NaN,结果是NaN。
  • 结果的符号等于被除数的符号。
  • 如果被除数是无穷大,或者除数为零,或者二者都是,结果为NaN。
  • 如果被除数是有限的,除数是无穷大的,结果等于被除数。如果被除数是零,除数是非零和有限的,结果与被除数相同。
  • 在剩余的情况下,既不涉及无穷大,也不包括零,也不涉及NaN,来自被除数n和除数d的浮点余数r由数学关系r = n - (d×q)定义,其中q 是仅当n / d为负数时为负的整数,只有在n / d为正时为正,并且其幅度尽可能大,而不超过n和d的真数学商的幅度。 r被计算,并使用IEEE 754-2008回合到最接近的可表示值,最接近偶数模式。

12.7.3.4Applying the ** Operator#

Returns an implementation-dependent approximation of the result of raising base to the power exponent.

  • If exponent is NaN, the result is NaN.
  • If exponent is +0, the result is 1, even if base is NaN.
  • If exponent is -0, the result is 1, even if base is NaN.
  • If base is NaN and exponent is nonzero, the result is NaN.
  • If abs(base) > 1 and exponent is +∞, the result is +∞.
  • If abs(base) > 1 and exponent is -∞, the result is +0.
  • If abs(base) is 1 and exponent is +∞, the result is NaN.
  • If abs(base) is 1 and exponent is -∞, the result is NaN.
  • If abs(base) < 1 and exponent is +∞, the result is +0.
  • If abs(base) < 1 and exponent is -∞, the result is +∞.
  • If base is +∞ and exponent > 0, the result is +∞.
  • If base is +∞ and exponent < 0, the result is +0.
  • If base is -∞ and exponent > 0 and exponent is an odd integer, the result is -∞.
  • If base is -∞ and exponent > 0 and exponent is not an odd integer, the result is +∞.
  • If base is -∞ and exponent < 0 and exponent is an odd integer, the result is -0.
  • If base is -∞ and exponent < 0 and exponent is not an odd integer, the result is +0.
  • If base is +0 and exponent > 0, the result is +0.
  • If base is +0 and exponent < 0, the result is +∞.
  • If base is -0 and exponent > 0 and exponent is an odd integer, the result is -0.
  • If base is -0 and exponent > 0 and exponent is not an odd integer, the result is +0.
  • If base is -0 and exponent < 0 and exponent is an odd integer, the result is -∞.
  • If base is -0 and exponent < 0 and exponent is not an odd integer, the result is +∞.
  • If base < 0 and base is finite and exponent is finite and exponent is not an integer, the result is NaN.
Note

The result of base ** exponent when base is 1 or -1 and exponent is +Infinity or -Infinity differs from IEEE 754-2008. The first edition of ECMAScript specified a result of NaN for this operation, whereas later versions of IEEE 754-2008 specified 1. The historical ECMAScript behaviour is preserved for compatibility reasons.

12.8Additive Operators#

Syntax

AdditiveExpression[Yield]:MultiplicativeExpression[?Yield] AdditiveExpression[?Yield]+MultiplicativeExpression[?Yield] AdditiveExpression[?Yield]-MultiplicativeExpression[?Yield]

12.8.1Static Semantics: IsFunctionDefinition#

AdditiveExpression:AdditiveExpression+MultiplicativeExpression AdditiveExpression-MultiplicativeExpression
  1. Return false.

12.8.2Static Semantics: IsValidSimpleAssignmentTarget#

AdditiveExpression:AdditiveExpression+MultiplicativeExpression AdditiveExpression-MultiplicativeExpression
  1. Return false.

12.8.3The Addition Operator ( + )#

Note

The addition operator either performs string concatenation or numeric addition.

12.8.3.1Runtime Semantics: Evaluation#

AdditiveExpression:AdditiveExpression+MultiplicativeExpression
  1. Let lref be the result of evaluating AdditiveExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating MultiplicativeExpression.
  4. Let rval be ? GetValue(rref).
  5. Let lprim be ? ToPrimitive(lval).
  6. Let rprim be ? ToPrimitive(rval).
  7. If Type(lprim) is String or Type(rprim) is String, then
    1. Let lstr be ? ToString(lprim).
    2. Let rstr be ? ToString(rprim).
    3. Return the String that is the result of concatenating lstr and rstr.
  8. Let lnum be ? ToNumber(lprim).
  9. Let rnum be ? ToNumber(rprim).
  10. Return the result of applying the addition operation to lnum and rnum. See the Note below 12.8.5.
Note 1

No hint is provided in the calls to ToPrimitive in steps 5 and 6. All standard objects except Date objects handle the absence of a hint as if the hint Number were given; Date objects handle the absence of a hint as if the hint String were given. Exotic objects may handle the absence of a hint in some other manner.

Note 2

Step 7 differs from step 5 of the Abstract Relational Comparison algorithm, by using the logical-or operation instead of the logical-and operation.

12.8.4The Subtraction Operator ( - )#

12.8.4.1Runtime Semantics: Evaluation#

AdditiveExpression:AdditiveExpression-MultiplicativeExpression
  1. Let lref be the result of evaluating AdditiveExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating MultiplicativeExpression.
  4. Let rval be ? GetValue(rref).
  5. Let lnum be ? ToNumber(lval).
  6. Let rnum be ? ToNumber(rval).
  7. Return the result of applying the subtraction operation to lnum and rnum. See the note below 12.8.5.

12.8.5Applying the Additive Operators to Numbers#

The + operator performs addition when applied to two operands of numeric type, producing the sum of the operands. The - operator performs subtraction, producing the difference of two numeric operands.

Addition is a commutative operation, but not always associative.

The result of an addition is determined using the rules of IEEE 754-2008 binary double-precision arithmetic:

  • If either operand is NaN, the result is NaN.
  • The sum of two infinities of opposite sign is NaN.
  • The sum of two infinities of the same sign is the infinity of that sign.
  • The sum of an infinity and a finite value is equal to the infinite operand.
  • The sum of two negative zeroes is -0. The sum of two positive zeroes, or of two zeroes of opposite sign, is +0.
  • The sum of a zero and a nonzero finite value is equal to the nonzero operand.
  • The sum of two nonzero finite values of the same magnitude and opposite sign is +0.
  • In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, and the operands have the same sign or have different magnitudes, the sum is computed and rounded to the nearest representable value using IEEE 754-2008 round to nearest, ties to even mode. If the magnitude is too large to represent, the operation overflows and the result is then an infinity of appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754-2008.
Note

The - operator performs subtraction when applied to two operands of numeric type, producing the difference of its operands; the left operand is the minuend and the right operand is the subtrahend. Given numeric operands a and b, it is always the case that a-b produces the same result as a+(-b).

12.9Bitwise Shift Operators#

Syntax

ShiftExpression[Yield]:AdditiveExpression[?Yield] ShiftExpression[?Yield]<<AdditiveExpression[?Yield] ShiftExpression[?Yield]>>AdditiveExpression[?Yield] ShiftExpression[?Yield]>>>AdditiveExpression[?Yield]

12.9.1Static Semantics: IsFunctionDefinition#

ShiftExpression:ShiftExpression<<AdditiveExpression ShiftExpression>>AdditiveExpression ShiftExpression>>>AdditiveExpression
  1. Return false.

12.9.2Static Semantics: IsValidSimpleAssignmentTarget#

ShiftExpression:ShiftExpression<<AdditiveExpression ShiftExpression>>AdditiveExpression ShiftExpression>>>AdditiveExpression
  1. Return false.

12.9.3The Left Shift Operator ( << )#

Note

Performs a bitwise left shift operation on the left operand by the amount specified by the right operand.

12.9.3.1Runtime Semantics: Evaluation#

ShiftExpression:ShiftExpression<<AdditiveExpression
  1. Let lref be the result of evaluating ShiftExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating AdditiveExpression.
  4. Let rval be ? GetValue(rref).
  5. Let lnum be ? ToInt32(lval).
  6. Let rnum be ? ToUint32(rval).
  7. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
  8. Return the result of left shifting lnum by shiftCount bits. The result is a signed 32-bit integer.

12.9.4The Signed Right Shift Operator ( >> )#

Note

Performs a sign-filling bitwise right shift operation on the left operand by the amount specified by the right operand.

12.9.4.1Runtime Semantics: Evaluation#

ShiftExpression:ShiftExpression>>AdditiveExpression
  1. Let lref be the result of evaluating ShiftExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating AdditiveExpression.
  4. Let rval be ? GetValue(rref).
  5. Let lnum be ? ToInt32(lval).
  6. Let rnum be ? ToUint32(rval).
  7. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
  8. Return the result of performing a sign-extending right shift of lnum by shiftCount bits. The most significant bit is propagated. The result is a signed 32-bit integer.

12.9.5The Unsigned Right Shift Operator ( >>> )#

Note

Performs a zero-filling bitwise right shift operation on the left operand by the amount specified by the right operand.

12.9.5.1Runtime Semantics: Evaluation#

ShiftExpression:ShiftExpression>>>AdditiveExpression
  1. Let lref be the result of evaluating ShiftExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating AdditiveExpression.
  4. Let rval be ? GetValue(rref).
  5. Let lnum be ? ToUint32(lval).
  6. Let rnum be ? ToUint32(rval).
  7. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
  8. Return the result of performing a zero-filling right shift of lnum by shiftCount bits. Vacated bits are filled with zero. The result is an unsigned 32-bit integer.

12.10Relational Operators#

Note 1

The result of evaluating a relational operator is always of type Boolean, reflecting whether the relationship named by the operator holds between its two operands.

Syntax

RelationalExpression[In, Yield]:ShiftExpression[?Yield] RelationalExpression[?In, ?Yield]<ShiftExpression[?Yield] RelationalExpression[?In, ?Yield]>ShiftExpression[?Yield] RelationalExpression[?In, ?Yield]<=ShiftExpression[?Yield] RelationalExpression[?In, ?Yield]>=ShiftExpression[?Yield] RelationalExpression[?In, ?Yield]instanceofShiftExpression[?Yield] [+In]RelationalExpression[In, ?Yield]inShiftExpression[?Yield] Note 2

The [In] grammar parameter is needed to avoid confusing the in operator in a relational expression with the in operator in a for statement.

12.10.1Static Semantics: IsFunctionDefinition#

RelationalExpression:RelationalExpression<ShiftExpression RelationalExpression>ShiftExpression RelationalExpression<=ShiftExpression RelationalExpression>=ShiftExpression RelationalExpressioninstanceofShiftExpression RelationalExpressioninShiftExpression
  1. Return false.

12.10.2Static Semantics: IsValidSimpleAssignmentTarget#

RelationalExpression:RelationalExpression<ShiftExpression RelationalExpression>ShiftExpression RelationalExpression<=ShiftExpression RelationalExpression>=ShiftExpression RelationalExpressioninstanceofShiftExpression RelationalExpressioninShiftExpression
  1. Return false.

12.10.3Runtime Semantics: Evaluation#

RelationalExpression:RelationalExpression<ShiftExpression
  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating ShiftExpression.
  4. Let rval be ? GetValue(rref).
  5. Let r be the result of performing Abstract Relational Comparison lval < rval.
  6. ReturnIfAbrupt(r).
  7. If r is undefined, return false. Otherwise, return r.
RelationalExpression:RelationalExpression>ShiftExpression
  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating ShiftExpression.
  4. Let rval be ? GetValue(rref).
  5. Let r be the result of performing Abstract Relational Comparison rval < lval with LeftFirst equal to false.
  6. ReturnIfAbrupt(r).
  7. If r is undefined, return false. Otherwise, return r.
RelationalExpression:RelationalExpression<=ShiftExpression
  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating ShiftExpression.
  4. Let rval be ? GetValue(rref).
  5. Let r be the result of performing Abstract Relational Comparison rval < lval with LeftFirst equal to false.
  6. ReturnIfAbrupt(r).
  7. If r is true or undefined, return false. Otherwise, return true.
RelationalExpression:RelationalExpression>=ShiftExpression
  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating ShiftExpression.
  4. Let rval be ? GetValue(rref).
  5. Let r be the result of performing Abstract Relational Comparison lval < rval.
  6. ReturnIfAbrupt(r).
  7. If r is true or undefined, return false. Otherwise, return true.
RelationalExpression:RelationalExpressioninstanceofShiftExpression
  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating ShiftExpression.
  4. Let rval be ? GetValue(rref).
  5. Return ? InstanceofOperator(lval, rval).
RelationalExpression:RelationalExpressioninShiftExpression
  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating ShiftExpression.
  4. Let rval be ? GetValue(rref).
  5. If Type(rval) is not Object, throw a TypeError exception.
  6. Return ? HasProperty(rval, ToPropertyKey(lval)).

12.10.4Runtime Semantics: InstanceofOperator(O, C)#

The abstract operation InstanceofOperator(O, C) implements the generic algorithm for determining if an object O inherits from the inheritance path defined by constructor C. This abstract operation performs the following steps:

  1. If Type(C) is not Object, throw a TypeError exception.
  2. Let instOfHandler be ? GetMethod(C, @@hasInstance).
  3. If instOfHandler is not undefined, then
    1. Return ToBoolean(? Call(instOfHandler, C, « O »)).
  4. If IsCallable(C) is false, throw a TypeError exception.
  5. Return ? OrdinaryHasInstance(C, O).
Note

Steps 5 and 6 provide compatibility with previous editions of ECMAScript that did not use a @@hasInstance method to define the instanceof operator semantics. If a function object does not define or inherit @@hasInstance it uses the default instanceof semantics.

12.11Equality Operators#

Note

The result of evaluating an equality operator is always of type Boolean, reflecting whether the relationship named by the operator holds between its two operands.

Syntax

EqualityExpression[In, Yield]:RelationalExpression[?In, ?Yield] EqualityExpression[?In, ?Yield]==RelationalExpression[?In, ?Yield] EqualityExpression[?In, ?Yield]!=RelationalExpression[?In, ?Yield] EqualityExpression[?In, ?Yield]===RelationalExpression[?In, ?Yield] EqualityExpression[?In, ?Yield]!==RelationalExpression[?In, ?Yield]

12.11.1Static Semantics: IsFunctionDefinition#

EqualityExpression:EqualityExpression==RelationalExpression EqualityExpression!=RelationalExpression EqualityExpression===RelationalExpression EqualityExpression!==RelationalExpression
  1. Return false.

12.11.2Static Semantics: IsValidSimpleAssignmentTarget#

EqualityExpression:EqualityExpression==RelationalExpression EqualityExpression!=RelationalExpression EqualityExpression===RelationalExpression EqualityExpression!==RelationalExpression
  1. Return false.

12.11.3Runtime Semantics: Evaluation#

EqualityExpression:EqualityExpression==RelationalExpression
  1. Let lref be the result of evaluating EqualityExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating RelationalExpression.
  4. Let rval be ? GetValue(rref).
  5. Return the result of performing Abstract Equality Comparison rval == lval.
EqualityExpression:EqualityExpression!=RelationalExpression
  1. Let lref be the result of evaluating EqualityExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating RelationalExpression.
  4. Let rval be ? GetValue(rref).
  5. Let r be the result of performing Abstract Equality Comparison rval == lval.
  6. If r is true, return false. Otherwise, return true.
EqualityExpression:EqualityExpression===RelationalExpression
  1. Let lref be the result of evaluating EqualityExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating RelationalExpression.
  4. Let rval be ? GetValue(rref).
  5. Return the result of performing Strict Equality Comparison rval === lval.
EqualityExpression:EqualityExpression!==RelationalExpression
  1. Let lref be the result of evaluating EqualityExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating RelationalExpression.
  4. Let rval be ? GetValue(rref).
  5. Let r be the result of performing Strict Equality Comparison rval === lval.
  6. If r is true, return false. Otherwise, return true.
Note 1

Given the above definition of equality:

  • String comparison can be forced by: "" + a == "" + b.
  • Numeric comparison can be forced by: +a == +b.
  • Boolean comparison can be forced by: !a == !b.
Note 2

The equality operators maintain the following invariants:

  • A != B is equivalent to !(A == B).
  • A == B is equivalent to B == A, except in the order of evaluation of A and B.
Note 3

The equality operator is not always transitive. For example, there might be two distinct String objects, each representing the same String value; each String object would be considered equal to the String value by the == operator, but the two String objects would not be equal to each other. For example:

  • new String("a") == "a" and "a" == new String("a") are both true.
  • new String("a") == new String("a") is false.
Note 4

Comparison of Strings uses a simple equality test on sequences of code unit values. There is no attempt to use the more complex, semantically oriented definitions of character or string equality and collating order defined in the Unicode specification. Therefore Strings values that are canonically equal according to the Unicode standard could test as unequal. In effect this algorithm assumes that both Strings are already in normalized form.

12.12Binary Bitwise Operators#

Syntax

BitwiseANDExpression[In, Yield]:EqualityExpression[?In, ?Yield] BitwiseANDExpression[?In, ?Yield]&EqualityExpression[?In, ?Yield] BitwiseXORExpression[In, Yield]:BitwiseANDExpression[?In, ?Yield] BitwiseXORExpression[?In, ?Yield]^BitwiseANDExpression[?In, ?Yield] BitwiseORExpression[In, Yield]:BitwiseXORExpression[?In, ?Yield] BitwiseORExpression[?In, ?Yield]|BitwiseXORExpression[?In, ?Yield]

12.12.1Static Semantics: IsFunctionDefinition#

BitwiseANDExpression:BitwiseANDExpression&EqualityExpression BitwiseXORExpression:BitwiseXORExpression^BitwiseANDExpression BitwiseORExpression:BitwiseORExpression|BitwiseXORExpression
  1. Return false.

12.12.2Static Semantics: IsValidSimpleAssignmentTarget#

BitwiseANDExpression:BitwiseANDExpression&EqualityExpression BitwiseXORExpression:BitwiseXORExpression^BitwiseANDExpression BitwiseORExpression:BitwiseORExpression|BitwiseXORExpression
  1. Return false.

12.12.3Runtime Semantics: Evaluation#

The production A:A@B , where @ is one of the bitwise operators in the productions above, is evaluated as follows:

  1. Let lref be the result of evaluating A.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating B.
  4. Let rval be ? GetValue(rref).
  5. Let lnum be ? ToInt32(lval).
  6. Let rnum be ? ToInt32(rval).
  7. Return the result of applying the bitwise operator @ to lnum and rnum. The result is a signed 32 bit integer.

12.13Binary Logical Operators#

Syntax

LogicalANDExpression[In, Yield]:BitwiseORExpression[?In, ?Yield] LogicalANDExpression[?In, ?Yield]&&BitwiseORExpression[?In, ?Yield] LogicalORExpression[In, Yield]:LogicalANDExpression[?In, ?Yield] LogicalORExpression[?In, ?Yield]||LogicalANDExpression[?In, ?Yield] Note

The value produced by a && or || operator is not necessarily of type Boolean. The value produced will always be the value of one of the two operand expressions.

12.13.1Static Semantics: IsFunctionDefinition#

LogicalANDExpression:LogicalANDExpression&&BitwiseORExpression LogicalORExpression:LogicalORExpression||LogicalANDExpression
  1. Return false.

12.13.2Static Semantics: IsValidSimpleAssignmentTarget#

LogicalANDExpression:LogicalANDExpression&&BitwiseORExpression LogicalORExpression:LogicalORExpression||LogicalANDExpression
  1. Return false.

12.13.3Runtime Semantics: Evaluation#

LogicalANDExpression:LogicalANDExpression&&BitwiseORExpression
  1. Let lref be the result of evaluating LogicalANDExpression.
  2. Let lval be ? GetValue(lref).
  3. Let lbool be ToBoolean(lval).
  4. If lbool is false, return lval.
  5. Let rref be the result of evaluating BitwiseORExpression.
  6. Return ? GetValue(rref).
LogicalORExpression:LogicalORExpression||LogicalANDExpression
  1. Let lref be the result of evaluating LogicalORExpression.
  2. Let lval be ? GetValue(lref).
  3. Let lbool be ToBoolean(lval).
  4. If lbool is true, return lval.
  5. Let rref be the result of evaluating LogicalANDExpression.
  6. Return ? GetValue(rref).

12.14Conditional Operator ( ? : )#

Syntax

ConditionalExpression[In, Yield]:LogicalORExpression[?In, ?Yield] LogicalORExpression[?In, ?Yield]?AssignmentExpression[In, ?Yield]:AssignmentExpression[?In, ?Yield] Note

The grammar for a ConditionalExpression in ECMAScript is slightly different from that in C and Java, which each allow the second subexpression to be an Expression but restrict the third expression to be a ConditionalExpression. The motivation for this difference in ECMAScript is to allow an assignment expression to be governed by either arm of a conditional and to eliminate the confusing and fairly useless case of a comma expression as the centre expression.

12.14.1Static Semantics: IsFunctionDefinition#

ConditionalExpression:LogicalORExpression?AssignmentExpression:AssignmentExpression
  1. Return false.

12.14.2Static Semantics: IsValidSimpleAssignmentTarget#

ConditionalExpression:LogicalORExpression?AssignmentExpression:AssignmentExpression
  1. Return false.

12.14.3Runtime Semantics: Evaluation#

ConditionalExpression:LogicalORExpression?AssignmentExpression:AssignmentExpression
  1. Let lref be the result of evaluating LogicalORExpression.
  2. Let lval be ToBoolean(? GetValue(lref)).
  3. If lval is true, then
    1. Let trueRef be the result of evaluating the first AssignmentExpression.
    2. Return ? GetValue(trueRef).
  4. Else,
    1. Let falseRef be the result of evaluating the second AssignmentExpression.
    2. Return ? GetValue(falseRef).

12.15Assignment Operators#

Syntax

AssignmentExpression[In, Yield]:ConditionalExpression[?In, ?Yield] [+Yield]YieldExpression[?In] ArrowFunction[?In, ?Yield] LeftHandSideExpression[?Yield]=AssignmentExpression[?In, ?Yield] LeftHandSideExpression[?Yield]AssignmentOperatorAssignmentExpression[?In, ?Yield] AssignmentOperator:one of*=/=%=+=-=<<=>>=>>>=&=^=|=**=

12.15.1Static Semantics: Early Errors#

AssignmentExpression:LeftHandSideExpression=AssignmentExpression AssignmentExpression:LeftHandSideExpressionAssignmentOperatorAssignmentExpression

12.15.2Static Semantics: IsFunctionDefinition#

AssignmentExpression:ArrowFunction
  1. Return true.
AssignmentExpression:YieldExpression LeftHandSideExpression=AssignmentExpression LeftHandSideExpressionAssignmentOperatorAssignmentExpression
  1. Return false.

12.15.3Static Semantics: IsValidSimpleAssignmentTarget#

AssignmentExpression:YieldExpression ArrowFunction LeftHandSideExpression=AssignmentExpression LeftHandSideExpressionAssignmentOperatorAssignmentExpression
  1. Return false.

12.15.4Runtime Semantics: Evaluation#

AssignmentExpression[In, Yield]:LeftHandSideExpression[?Yield]=AssignmentExpression[?In, ?Yield]
  1. If LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral, then
    1. Let lref be the result of evaluating LeftHandSideExpression.
    2. ReturnIfAbrupt(lref).
    3. Let rref be the result of evaluating AssignmentExpression.
    4. Let rval be ? GetValue(rref).
    5. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
      1. Let hasNameProperty be ? HasOwnProperty(rval, "name").
      2. If hasNameProperty is false, perform SetFunctionName(rval, GetReferencedName(lref)).
    6. Perform ? PutValue(lref, rval).
    7. Return rval.
  2. Let assignmentPattern be the parse of the source text corresponding to LeftHandSideExpression using AssignmentPattern[?Yield] as the goal symbol.
  3. Let rref be the result of evaluating AssignmentExpression.
  4. Let rval be ? GetValue(rref).
  5. Let status be the result of performing DestructuringAssignmentEvaluation of assignmentPattern using rval as the argument.
  6. ReturnIfAbrupt(status).
  7. Return rval.
AssignmentExpression:LeftHandSideExpressionAssignmentOperatorAssignmentExpression
  1. Let lref be the result of evaluating LeftHandSideExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating AssignmentExpression.
  4. Let rval be ? GetValue(rref).
  5. Let op be the @ where AssignmentOperator is @=.
  6. Let r be the result of applying op to lval and rval as if evaluating the expression lval op rval.
  7. Perform ? PutValue(lref, r).
  8. Return r.
Note

When an assignment occurs within strict mode code, it is an runtime error if lref in step 1.f of the first algorithm or step 7 of the second algorithm it is an unresolvable reference. If it is, a ReferenceError exception is thrown. The LeftHandSideExpression also may not be a reference to a data property with the attribute value {[[Writable]]: false}, to an accessor property with the attribute value {[[Set]]: undefined}, nor to a non-existent property of an object for which the IsExtensible predicate returns the value false. In these cases a TypeError exception is thrown.

12.15.5Destructuring Assignment#

Supplemental Syntax

In certain circumstances when processing the production AssignmentExpression:LeftHandSideExpression=AssignmentExpression the following grammar is used to refine the interpretation of LeftHandSideExpression.

AssignmentPattern[Yield]:ObjectAssignmentPattern[?Yield] ArrayAssignmentPattern[?Yield] ObjectAssignmentPattern[Yield]:{} {AssignmentPropertyList[?Yield]} {AssignmentPropertyList[?Yield],} ArrayAssignmentPattern[Yield]:[ElisionoptAssignmentRestElement[?Yield]opt] [AssignmentElementList[?Yield]] [AssignmentElementList[?Yield],ElisionoptAssignmentRestElement[?Yield]opt] AssignmentPropertyList[Yield]:AssignmentProperty[?Yield] AssignmentPropertyList[?Yield],AssignmentProperty[?Yield] AssignmentElementList[Yield]:AssignmentElisionElement[?Yield] AssignmentElementList[?Yield],AssignmentElisionElement[?Yield] AssignmentElisionElement[Yield]:ElisionoptAssignmentElement[?Yield] AssignmentProperty[Yield]:IdentifierReference[?Yield]Initializer[In, ?Yield]opt PropertyName[?Yield]:AssignmentElement[?Yield] AssignmentElement[Yield]:DestructuringAssignmentTarget[?Yield]Initializer[In, ?Yield]opt AssignmentRestElement[Yield]:...DestructuringAssignmentTarget[?Yield] DestructuringAssignmentTarget[Yield]:LeftHandSideExpression[?Yield]

12.15.5.1Static Semantics: Early Errors#

AssignmentProperty:IdentifierReferenceInitializeropt DestructuringAssignmentTarget:LeftHandSideExpression

12.15.5.2Runtime Semantics: DestructuringAssignmentEvaluation#

with parameter value

ObjectAssignmentPattern:{}
  1. Perform ? RequireObjectCoercible(value).
  2. Return NormalCompletion(empty).
ObjectAssignmentPattern:{AssignmentPropertyList} {AssignmentPropertyList,}
  1. Perform ? RequireObjectCoercible(value).
  2. Return the result of performing DestructuringAssignmentEvaluation for AssignmentPropertyList using value as the argument.
ArrayAssignmentPattern:[]
  1. Let iterator be ? GetIterator(value).
  2. Return ? IteratorClose(iterator, NormalCompletion(empty)).
ArrayAssignmentPattern:[Elision]
  1. Let iterator be ? GetIterator(value).
  2. Let iteratorRecord be Record {[[Iterator]]: iterator, [[Done]]: false}.
  3. Let result be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
  4. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iterator, result).
  5. Return result.
ArrayAssignmentPattern:[ElisionoptAssignmentRestElement]
  1. Let iterator be ? GetIterator(value).
  2. Let iteratorRecord be Record {[[Iterator]]: iterator, [[Done]]: false}.
  3. If Elision is present, then
    1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
    2. If status is an abrupt completion, then
      1. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iterator, status).
      2. Return Completion(status).
  4. Let result be the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with iteratorRecord as the argument.
  5. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iterator, result).
  6. Return result.
ArrayAssignmentPattern:[AssignmentElementList]
  1. Let iterator be ? GetIterator(value).
  2. Let iteratorRecord be Record {[[Iterator]]: iterator, [[Done]]: false}.
  3. Let result be the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElementList using iteratorRecord as the argument.
  4. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iterator, result).
  5. Return result.
ArrayAssignmentPattern:[AssignmentElementList,ElisionoptAssignmentRestElementopt]
  1. Let iterator be ? GetIterator(value).
  2. Let iteratorRecord be Record {[[Iterator]]: iterator, [[Done]]: false}.
  3. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElementList using iteratorRecord as the argument.
  4. If status is an abrupt completion, then
    1. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iterator, status).
    2. Return Completion(status).
  5. If Elision is present, then
    1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
    2. If status is an abrupt completion, then
      1. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iterator, status).
      2. Return Completion(status).
  6. If AssignmentRestElement is present, then
    1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with iteratorRecord as the argument.
  7. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iterator, status).
  8. Return Completion(status).
AssignmentPropertyList:AssignmentPropertyList,AssignmentProperty
  1. Let status be the result of performing DestructuringAssignmentEvaluation for AssignmentPropertyList using value as the argument.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing DestructuringAssignmentEvaluation for AssignmentProperty using value as the argument.
AssignmentProperty:IdentifierReferenceInitializeropt
  1. Let P be StringValue of IdentifierReference.
  2. Let lref be ? ResolveBinding(P).
  3. Let v be ? GetV(value, P).
  4. If Initializeropt is present and v is undefined, then
    1. Let defaultValue be the result of evaluating Initializer.
    2. Let v be ? GetValue(defaultValue).
    3. If IsAnonymousFunctionDefinition(Initializer) is true, then
      1. Let hasNameProperty be ? HasOwnProperty(v, "name").
      2. If hasNameProperty is false, perform SetFunctionName(v, P).
  5. Return ? PutValue(lref, v).
AssignmentProperty:PropertyName:AssignmentElement
  1. Let name be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(name).
  3. Return the result of performing KeyedDestructuringAssignmentEvaluation of AssignmentElement with value and name as the arguments.

12.15.5.3Runtime Semantics: IteratorDestructuringAssignmentEvaluation#

with parameters iteratorRecord

AssignmentElementList:AssignmentElisionElement
  1. Return the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElisionElement using iteratorRecord as the argument.
AssignmentElementList:AssignmentElementList,AssignmentElisionElement
  1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElementList using iteratorRecord as the argument.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElisionElement using iteratorRecord as the argument.
AssignmentElisionElement:AssignmentElement
  1. Return the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElement with iteratorRecord as the argument.
AssignmentElisionElement:ElisionAssignmentElement
  1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElement with iteratorRecord as the argument.
Elision:,
  1. If iteratorRecord.[[Done]] is false, then
    1. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, set iteratorRecord.[[Done]] to true.
  2. Return NormalCompletion(empty).
Elision:Elision,
  1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
  2. ReturnIfAbrupt(status).
  3. If iteratorRecord.[[Done]] is false, then
    1. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, set iteratorRecord.[[Done]] to true.
  4. Return NormalCompletion(empty).
AssignmentElement[Yield]:DestructuringAssignmentTargetInitializeropt
  1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
    1. Let lref be the result of evaluating DestructuringAssignmentTarget.
    2. ReturnIfAbrupt(lref).
  2. If iteratorRecord.[[Done]] is false, then
    1. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, set iteratorRecord.[[Done]] to true.
    5. Else,
      1. Let value be IteratorValue(next).
      2. If value is an abrupt completion, set iteratorRecord.[[Done]] to true.
      3. ReturnIfAbrupt(value).
  3. If iteratorRecord.[[Done]] is true, let value be undefined.
  4. If Initializer is present and value is undefined, then
    1. Let defaultValue be the result of evaluating Initializer.
    2. Let v be ? GetValue(defaultValue).
  5. Else, let v be value.
  6. If DestructuringAssignmentTarget is an ObjectLiteral or an ArrayLiteral, then
    1. Let nestedAssignmentPattern be the parse of the source text corresponding to DestructuringAssignmentTarget using either AssignmentPattern or AssignmentPattern[Yield] as the goal symbol depending upon whether this AssignmentElement has the [Yield] parameter.
    2. Return the result of performing DestructuringAssignmentEvaluation of nestedAssignmentPattern with v as the argument.
  7. If Initializer is present and value is undefined and IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of DestructuringAssignmentTarget are both true, then
    1. Let hasNameProperty be ? HasOwnProperty(v, "name").
    2. If hasNameProperty is false, perform SetFunctionName(v, GetReferencedName(lref)).
  8. Return ? PutValue(lref, v).
Note

Left to right evaluation order is maintained by evaluating a DestructuringAssignmentTarget that is not a destructuring pattern prior to accessing the iterator or evaluating the Initializer.

AssignmentRestElement[Yield]:...DestructuringAssignmentTarget
  1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
    1. Let lref be the result of evaluating DestructuringAssignmentTarget.
    2. ReturnIfAbrupt(lref).
  2. Let A be ArrayCreate(0).
  3. Let n be 0.
  4. Repeat while iteratorRecord.[[Done]] is false,
    1. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, set iteratorRecord.[[Done]] to true.
    5. Else,
      1. Let nextValue be IteratorValue(next).
      2. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
      3. ReturnIfAbrupt(nextValue).
      4. Let status be CreateDataProperty(A, ! ToString(n), nextValue).
      5. Assert: status is true.
      6. Increment n by 1.
  5. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
    1. Return ? PutValue(lref, A).
  6. Let nestedAssignmentPattern be the parse of the source text corresponding to DestructuringAssignmentTarget using either AssignmentPattern or AssignmentPattern[Yield] as the goal symbol depending upon whether this AssignmentElement has the [Yield] parameter.
  7. Return the result of performing DestructuringAssignmentEvaluation of nestedAssignmentPattern with A as the argument.

12.15.5.4Runtime Semantics: KeyedDestructuringAssignmentEvaluation#

with parameters value and propertyName

AssignmentElement[Yield]:DestructuringAssignmentTargetInitializeropt
  1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
    1. Let lref be the result of evaluating DestructuringAssignmentTarget.
    2. ReturnIfAbrupt(lref).
  2. Let v be ? GetV(value, propertyName).
  3. If Initializer is present and v is undefined, then
    1. Let defaultValue be the result of evaluating Initializer.
    2. Let rhsValue be ? GetValue(defaultValue).
  4. Else, let rhsValue be v.
  5. If DestructuringAssignmentTarget is an ObjectLiteral or an ArrayLiteral, then
    1. Let assignmentPattern be the parse of the source text corresponding to DestructuringAssignmentTarget using either AssignmentPattern or AssignmentPattern[Yield] as the goal symbol depending upon whether this AssignmentElement has the [Yield] parameter.
    2. Return the result of performing DestructuringAssignmentEvaluation of assignmentPattern with rhsValue as the argument.
  6. If Initializer is present and v is undefined and IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of DestructuringAssignmentTarget are both true, then
    1. Let hasNameProperty be ? HasOwnProperty(rhsValue, "name").
    2. If hasNameProperty is false, perform SetFunctionName(rhsValue, GetReferencedName(lref)).
  7. Return ? PutValue(lref, rhsValue).

12.16Comma Operator ( , )#

Syntax

Expression[In, Yield]:AssignmentExpression[?In, ?Yield] Expression[?In, ?Yield],AssignmentExpression[?In, ?Yield]

12.16.1Static Semantics: IsFunctionDefinition#

Expression:Expression,AssignmentExpression
  1. Return false.

12.16.2Static Semantics: IsValidSimpleAssignmentTarget#

Expression:Expression,AssignmentExpression
  1. Return false.

12.16.3Runtime Semantics: Evaluation#

Expression:Expression,AssignmentExpression
  1. Let lref be the result of evaluating Expression.
  2. Perform ? GetValue(lref).
  3. Let rref be the result of evaluating AssignmentExpression.
  4. Return ? GetValue(rref).
Note

GetValue must be called even though its value is not used because it may have observable side-effects.

13ECMAScript Language: Statements and Declarations(ECMAScript语言:语句和声明)#

Syntax

Statement[Yield, Return]:BlockStatement[?Yield, ?Return] VariableStatement[?Yield] EmptyStatement ExpressionStatement[?Yield] IfStatement[?Yield, ?Return] BreakableStatement[?Yield, ?Return] ContinueStatement[?Yield] BreakStatement[?Yield] [+Return]ReturnStatement[?Yield] WithStatement[?Yield, ?Return] LabelledStatement[?Yield, ?Return] ThrowStatement[?Yield] TryStatement[?Yield, ?Return] DebuggerStatement Declaration[Yield]:HoistableDeclaration[?Yield] ClassDeclaration[?Yield] LexicalDeclaration[In, ?Yield] HoistableDeclaration[Yield, Default]:FunctionDeclaration[?Yield, ?Default] GeneratorDeclaration[?Yield, ?Default] BreakableStatement[Yield, Return]:IterationStatement[?Yield, ?Return] SwitchStatement[?Yield, ?Return]

13.1Statement Semantics#

13.1.1Static Semantics(语句语义): ContainsDuplicateLabels#

With argument labelSet.

Statement:VariableStatement EmptyStatement ExpressionStatement ContinueStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement
  1. Return false.

13.1.2Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

Statement:VariableStatement EmptyStatement ExpressionStatement ContinueStatement ReturnStatement ThrowStatement DebuggerStatement
  1. Return false.

13.1.3Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

Statement:VariableStatement EmptyStatement ExpressionStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement
  1. Return false.
BreakableStatement:IterationStatement
  1. Let newIterationSet be a copy of iterationSet with all the elements of labelSet appended.
  2. Return ContainsUndefinedContinueTarget of IterationStatement with arguments newIterationSet and « ».

13.1.4Static Semantics: DeclarationPart#

HoistableDeclaration:FunctionDeclaration
  1. Return FunctionDeclaration.
HoistableDeclaration:GeneratorDeclaration
  1. Return GeneratorDeclaration.
Declaration:ClassDeclaration
  1. Return ClassDeclaration.
Declaration:LexicalDeclaration
  1. Return LexicalDeclaration.

13.1.5Static Semantics: VarDeclaredNames#

Statement:EmptyStatement ExpressionStatement ContinueStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement
  1. Return a new empty List.

13.1.6Static Semantics: VarScopedDeclarations#

Statement:EmptyStatement ExpressionStatement ContinueStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement
  1. Return a new empty List.

13.1.7Runtime Semantics: LabelledEvaluation#

With argument labelSet.

BreakableStatement:IterationStatement
  1. Let stmtResult be the result of performing LabelledEvaluation of IterationStatement with argument labelSet.
  2. If stmtResult.[[Type]] is break, then
    1. If stmtResult.[[Target]] is empty, then
      1. If stmtResult.[[Value]] is empty, let stmtResult be NormalCompletion(undefined).
      2. Else, let stmtResult be NormalCompletion(stmtResult.[[Value]]).
  3. Return Completion(stmtResult).
BreakableStatement:SwitchStatement
  1. Let stmtResult be the result of evaluating SwitchStatement.
  2. If stmtResult.[[Type]] is break, then
    1. If stmtResult.[[Target]] is empty, then
      1. If stmtResult.[[Value]] is empty, let stmtResult be NormalCompletion(undefined).
      2. Else, let stmtResult be NormalCompletion(stmtResult.[[Value]]).
  3. Return Completion(stmtResult).
Note

A BreakableStatement is one that can be exited via an unlabelled BreakStatement.

BreakableStatement是可以通过未标记的Break语句退出的语句。

13.1.8Runtime Semantics: Evaluation#

HoistableDeclaration:GeneratorDeclaration
  1. Return NormalCompletion(empty).
HoistableDeclaration:FunctionDeclaration
  1. Return the result of evaluating FunctionDeclaration.
BreakableStatement:IterationStatement SwitchStatement
  1. Let newLabelSet be a new empty List.
  2. Return the result of performing LabelledEvaluation of this BreakableStatement with argument newLabelSet.

13.2Block(块)#

Syntax

BlockStatement[Yield, Return]:Block[?Yield, ?Return] Block[Yield, Return]:{StatementList[?Yield, ?Return]opt} StatementList[Yield, Return]:StatementListItem[?Yield, ?Return] StatementList[?Yield, ?Return]StatementListItem[?Yield, ?Return] StatementListItem[Yield, Return]:Statement[?Yield, ?Return] Declaration[?Yield]

13.2.1Static Semantics: Early Errors#

Block:{StatementList}
  • It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries.
  • It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the VarDeclaredNames of StatementList.

13.2.2Static Semantics: ContainsDuplicateLabels#

With argument labelSet.

Block:{}
  1. Return false.
StatementList:StatementListStatementListItem
  1. Let hasDuplicates be ContainsDuplicateLabels of StatementList with argument labelSet.
  2. If hasDuplicates is true, return true.
  3. Return ContainsDuplicateLabels of StatementListItem with argument labelSet.
StatementListItem:Declaration
  1. Return false.

13.2.3Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

Block:{}
  1. Return false.
StatementList:StatementListStatementListItem
  1. Let hasUndefinedLabels be ContainsUndefinedBreakTarget of StatementList with argument labelSet.
  2. If hasUndefinedLabels is true, return true.
  3. Return ContainsUndefinedBreakTarget of StatementListItem with argument labelSet.
StatementListItem:Declaration
  1. Return false.

13.2.4Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

Block:{}
  1. Return false.
StatementList:StatementListStatementListItem
  1. Let hasUndefinedLabels be ContainsUndefinedContinueTarget of StatementList with arguments iterationSet and « ».
  2. If hasUndefinedLabels is true, return true.
  3. Return ContainsUndefinedContinueTarget of StatementListItem with arguments iterationSet and « ».
StatementListItem:Declaration
  1. Return false.

13.2.5Static Semantics: LexicallyDeclaredNames#

Block:{}
  1. Return a new empty List.
StatementList:StatementListStatementListItem
  1. Let names be LexicallyDeclaredNames of StatementList.
  2. Append to names the elements of the LexicallyDeclaredNames of StatementListItem.
  3. Return names.
StatementListItem:Statement
  1. If Statement is Statement:LabelledStatement , return LexicallyDeclaredNames of LabelledStatement.
  2. Return a new empty List.
StatementListItem:Declaration
  1. Return the BoundNames of Declaration.

13.2.6Static Semantics: LexicallyScopedDeclarations#

StatementList:StatementListStatementListItem
  1. Let declarations be LexicallyScopedDeclarations of StatementList.
  2. Append to declarations the elements of the LexicallyScopedDeclarations of StatementListItem.
  3. Return declarations.
StatementListItem:Statement
  1. If Statement is Statement:LabelledStatement , return LexicallyScopedDeclarations of LabelledStatement.
  2. Return a new empty List.
StatementListItem:Declaration
  1. Return a new List containing DeclarationPart of Declaration.

13.2.7Static Semantics: TopLevelLexicallyDeclaredNames#

StatementList:StatementListStatementListItem
  1. Let names be TopLevelLexicallyDeclaredNames of StatementList.
  2. Append to names the elements of the TopLevelLexicallyDeclaredNames of StatementListItem.
  3. Return names.
StatementListItem:Statement
  1. Return a new empty List.
StatementListItem:Declaration
  1. If Declaration is Declaration:HoistableDeclaration , then
    1. Return « ».
  2. Return the BoundNames of Declaration.
Note

At the top level of a function, or script, function declarations are treated like var declarations rather than like lexical declarations.

13.2.8Static Semantics: TopLevelLexicallyScopedDeclarations#

Block:{}
  1. Return a new empty List.
StatementList:StatementListStatementListItem
  1. Let declarations be TopLevelLexicallyScopedDeclarations of StatementList.
  2. Append to declarations the elements of the TopLevelLexicallyScopedDeclarations of StatementListItem.
  3. Return declarations.
StatementListItem:Statement
  1. Return a new empty List.
StatementListItem:Declaration
  1. If Declaration is Declaration:HoistableDeclaration , then
    1. Return « ».
  2. Return a new List containing Declaration.

13.2.9Static Semantics: TopLevelVarDeclaredNames#

Block:{}
  1. Return a new empty List.
StatementList:StatementListStatementListItem
  1. Let names be TopLevelVarDeclaredNames of StatementList.
  2. Append to names the elements of the TopLevelVarDeclaredNames of StatementListItem.
  3. Return names.
StatementListItem:Declaration
  1. If Declaration is Declaration:HoistableDeclaration , then
    1. Return the BoundNames of HoistableDeclaration.
  2. Return a new empty List.
StatementListItem:Statement
  1. If Statement is Statement:LabelledStatement , return TopLevelVarDeclaredNames of Statement.
  2. Return VarDeclaredNames of Statement.
Note

At the top level of a function or script, inner function declarations are treated like var declarations.

13.2.10Static Semantics: TopLevelVarScopedDeclarations#

Block:{}
  1. Return a new empty List.
StatementList:StatementListStatementListItem
  1. Let declarations be TopLevelVarScopedDeclarations of StatementList.
  2. Append to declarations the elements of the TopLevelVarScopedDeclarations of StatementListItem.
  3. Return declarations.
StatementListItem:Statement
  1. If Statement is Statement:LabelledStatement , return TopLevelVarScopedDeclarations of Statement.
  2. Return VarScopedDeclarations of Statement.
StatementListItem:Declaration
  1. If Declaration is Declaration:HoistableDeclaration , then
    1. Let declaration be DeclarationPart of HoistableDeclaration.
    2. Return « declaration ».
  2. Return a new empty List.

13.2.11Static Semantics: VarDeclaredNames#

Block:{}
  1. Return a new empty List.
StatementList:StatementListStatementListItem
  1. Let names be VarDeclaredNames of StatementList.
  2. Append to names the elements of the VarDeclaredNames of StatementListItem.
  3. Return names.
StatementListItem:Declaration
  1. Return a new empty List.

13.2.12Static Semantics: VarScopedDeclarations#

Block:{}
  1. Return a new empty List.
StatementList:StatementListStatementListItem
  1. Let declarations be VarScopedDeclarations of StatementList.
  2. Append to declarations the elements of the VarScopedDeclarations of StatementListItem.
  3. Return declarations.
StatementListItem:Declaration
  1. Return a new empty List.

13.2.13Runtime Semantics: Evaluation#

Block:{}
  1. Return NormalCompletion(empty).
Block:{StatementList}
  1. Let oldEnv be the running execution context's LexicalEnvironment.
  2. Let blockEnv be NewDeclarativeEnvironment(oldEnv).
  3. Perform BlockDeclarationInstantiation(StatementList, blockEnv).
  4. Set the running execution context's LexicalEnvironment to blockEnv.
  5. Let blockValue be the result of evaluating StatementList.
  6. Set the running execution context's LexicalEnvironment to oldEnv.
  7. Return blockValue.
Note 1

No matter how control leaves the Block the LexicalEnvironment is always restored to its former state.

StatementList:StatementListStatementListItem
  1. Let sl be the result of evaluating StatementList.
  2. ReturnIfAbrupt(sl).
  3. Let s be the result of evaluating StatementListItem.
  4. Return Completion(UpdateEmpty(s, sl)).
Note 2

The value of a StatementList is the value of the last value producing item in the StatementList. For example, the following calls to the eval function all return the value 1:


eval("1;;;;;")
eval("1;{}")
eval("1;var a;")
        

13.2.14Runtime Semantics: BlockDeclarationInstantiation( code, env )#

Note

When a Block or CaseBlock production is evaluated a new declarative Environment Record is created and bindings for each block scoped variable, constant, function, generator function, or class declared in the block are instantiated in the Environment Record.

BlockDeclarationInstantiation is performed as follows using arguments code and env. code is the grammar production corresponding to the body of the block. env is the Lexical Environment in which bindings are to be created.

  1. Let envRec be env's EnvironmentRecord.
  2. Assert: envRec is a declarative Environment Record.
  3. Let declarations be the LexicallyScopedDeclarations of code.
  4. For each element d in declarations do
    1. For each element dn of the BoundNames of d do
      1. If IsConstantDeclaration of d is true, then
        1. Perform ! envRec.CreateImmutableBinding(dn, true).
      2. Else,
        1. Perform ! envRec.CreateMutableBinding(dn, false).
    2. If d is a GeneratorDeclaration production or a FunctionDeclaration production, then
      1. Let fn be the sole element of the BoundNames of d.
      2. Let fo be the result of performing InstantiateFunctionObject for d with argument env.
      3. Perform envRec.InitializeBinding(fn, fo).

13.3Declarations and the Variable Statement(声明和变量语句)#

13.3.1Let and Const Declarations(let const声明)#

Note

let and const declarations define variables that are scoped to the running execution context's LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable's LexicalBinding is evaluated. A variable defined by a LexicalBinding with an Initializer is assigned the value of its Initializer's AssignmentExpression when the LexicalBinding is evaluated, not when the variable is created. If a LexicalBinding in a let declaration does not have an Initializer the variable is assigned the value undefined when the LexicalBinding is evaluated.

let和const声明定义了作用域是正在运行的执行上下文的词法环境的变量。 当它们包含词法环境被实例化时,这些变量被创建,但是在执行变量的词法绑定之前,不能以任何方式被访问。 由词法绑定和初始化程序定义的变量在执行词法绑定时被分配其初始化程序的赋值表达式的值,而不是在创建变量时。 如果let声明中的词法绑定没有初始化程序,则在执行词法绑定时将为该变量赋值undefined。

Syntax

LexicalDeclaration[In, Yield]:LetOrConstBindingList[?In, ?Yield]; LetOrConst:let const BindingList[In, Yield]:LexicalBinding[?In, ?Yield] BindingList[?In, ?Yield],LexicalBinding[?In, ?Yield] LexicalBinding[In, Yield]:BindingIdentifier[?Yield]Initializer[?In, ?Yield]opt BindingPattern[?Yield]Initializer[?In, ?Yield]

13.3.1.1Static Semantics: Early Errors(静态语义:早期的错误)#

LexicalDeclaration:LetOrConstBindingList;
  • It is a Syntax Error if the BoundNames of BindingList contains "let".

    如果BindingList的BoundNames包含“let”,那么这是一个语法错误。

    let let =2 let is disallowed as a lexically bound name
  • It is a Syntax Error if the BoundNames of BindingList contains any duplicate entries.

    如果BindingList的BoundNames包含任何重复的条目,则这是一个语法错误。

    let a = 1; let a = 2 Uncaught SyntaxError: Identifier 'a' has already been declared
LexicalBinding:BindingIdentifierInitializeropt
  • It is a Syntax Error if Initializer is not present and IsConstantDeclaration of the LexicalDeclaration containing this production is true.

    如果初始化程序不存在,并且包含此产生式的LexicalDeclaration的IsConstantDeclaration为true,则为语法错误。
    意思是,常量如果未赋值,则报语法错误

    const con; Uncaught SyntaxError: Missing initializer in const declaration

13.3.1.2Static Semantics: BoundNames#

LexicalDeclaration:LetOrConstBindingList;
  1. Return the BoundNames of BindingList.
BindingList:BindingList,LexicalBinding
  1. Let names be the BoundNames of BindingList.
  2. Append to names the elements of the BoundNames of LexicalBinding.
  3. Return names.
LexicalBinding:BindingIdentifierInitializeropt
  1. Return the BoundNames of BindingIdentifier.
LexicalBinding:BindingPatternInitializer
  1. Return the BoundNames of BindingPattern.

13.3.1.3Static Semantics: IsConstantDeclaration#

LexicalDeclaration:LetOrConstBindingList;
  1. Return IsConstantDeclaration of LetOrConst.
LetOrConst:let
  1. Return false.
LetOrConst:const
  1. Return true.

13.3.1.4Runtime Semantics: Evaluation#

LexicalDeclaration:LetOrConstBindingList;
  1. Let next be the result of evaluating BindingList.
  2. ReturnIfAbrupt(next).
  3. Return NormalCompletion(empty).
BindingList:BindingList,LexicalBinding
  1. Let next be the result of evaluating BindingList.
  2. ReturnIfAbrupt(next).
  3. Return the result of evaluating LexicalBinding.
LexicalBinding:BindingIdentifier
  1. Let lhs be ResolveBinding(StringValue of BindingIdentifier).
  2. Return InitializeReferencedBinding(lhs, undefined).
Note

A static semantics rule ensures that this form of LexicalBinding never occurs in a const declaration.

静态语义规则确保这种形式的LexicalBinding永远不会出现在const声明中。即const不能绑定undefined

LexicalBinding:BindingIdentifierInitializer
  1. Let bindingId be StringValue of BindingIdentifier.
  2. Let lhs be ResolveBinding(bindingId).
  3. Let rhs be the result of evaluating Initializer.
  4. Let value be ? GetValue(rhs).
  5. If IsAnonymousFunctionDefinition(Initializer) is true, then
    1. Let hasNameProperty be ? HasOwnProperty(value, "name").
    2. If hasNameProperty is false, perform SetFunctionName(value, bindingId).
  6. Return InitializeReferencedBinding(lhs, value).
LexicalBinding:BindingPatternInitializer
  1. Let rhs be the result of evaluating Initializer.
  2. Let value be ? GetValue(rhs).
  3. Let env be the running execution context's LexicalEnvironment.
  4. Return the result of performing BindingInitialization for BindingPattern using value and env as the arguments.

13.3.2Variable Statement(var语句)#

Note

A var statement declares variables that are scoped to the running execution context's VariableEnvironment. Var variables are created when their containing Lexical Environment is instantiated and are initialized to undefined when created. Within the scope of any VariableEnvironment a common BindingIdentifier may appear in more than one VariableDeclaration but those declarations collective define only one variable. A variable defined by a VariableDeclaration with an Initializer is assigned the value of its Initializer's AssignmentExpression when the VariableDeclaration is executed, not when the variable is created.

var语句声明了作用域为运行的执行上下文的VariableEnvironment的变量。 Var变量在包含Lexical Environment的实例化时创建,并在创建时初始化为undefined。 在任何VariableEnvironment的范围内,一个公共的BindingIdentifier可能出现在多个VariableDeclaration中,但这些声明集合只定义一个变量。 变量声明定义的变量与初始化方法一起被赋值为执行变量声明时的初始化方法赋值表达式的值,而不是变量被创建的时候。
var变量初始化值为undefined,可以声明多个一样的var变量,但是最终只有一个变量,最终赋予初始化方法的值

Syntax

VariableStatement[Yield]:varVariableDeclarationList[In, ?Yield]; VariableDeclarationList[In, Yield]:VariableDeclaration[?In, ?Yield] VariableDeclarationList[?In, ?Yield],VariableDeclaration[?In, ?Yield] VariableDeclaration[In, Yield]:BindingIdentifier[?Yield]Initializer[?In, ?Yield]opt BindingPattern[?Yield]Initializer[?In, ?Yield]

13.3.2.1Static Semantics: BoundNames#

VariableDeclarationList:VariableDeclarationList,VariableDeclaration
  1. Let names be BoundNames of VariableDeclarationList.
  2. Append to names the elements of BoundNames of VariableDeclaration.
  3. Return names.
VariableDeclaration:BindingIdentifierInitializeropt
  1. Return the BoundNames of BindingIdentifier.
VariableDeclaration:BindingPatternInitializer
  1. Return the BoundNames of BindingPattern.

13.3.2.2Static Semantics: VarDeclaredNames#

VariableStatement:varVariableDeclarationList;
  1. Return BoundNames of VariableDeclarationList.

13.3.2.3Static Semantics: VarScopedDeclarations#

VariableDeclarationList:VariableDeclaration
  1. Return a new List containing VariableDeclaration.
VariableDeclarationList:VariableDeclarationList,VariableDeclaration
  1. Let declarations be VarScopedDeclarations of VariableDeclarationList.
  2. Append VariableDeclaration to declarations.
  3. Return declarations.

13.3.2.4Runtime Semantics: Evaluation#

VariableStatement:varVariableDeclarationList;
  1. Let next be the result of evaluating VariableDeclarationList.
  2. ReturnIfAbrupt(next).
  3. Return NormalCompletion(empty).
VariableDeclarationList:VariableDeclarationList,VariableDeclaration
  1. Let next be the result of evaluating VariableDeclarationList.
  2. ReturnIfAbrupt(next).
  3. Return the result of evaluating VariableDeclaration.
VariableDeclaration:BindingIdentifier
  1. Return NormalCompletion(empty).
VariableDeclaration:BindingIdentifierInitializer
  1. Let bindingId be StringValue of BindingIdentifier.
  2. Let lhs be ? ResolveBinding(bindingId).
  3. Let rhs be the result of evaluating Initializer.
  4. Let value be ? GetValue(rhs).
  5. If IsAnonymousFunctionDefinition(Initializer) is true(如果是匿名函数), then
    1. Let hasNameProperty be ? HasOwnProperty(value, "name").
    2. If hasNameProperty is false, perform SetFunctionName(value, bindingId).
  6. Return ? PutValue(lhs, value).
Note

If a VariableDeclaration is nested within a with statement and the BindingIdentifier in the VariableDeclaration is the same as a property name of the binding object of the with statement's object Environment Record, then step 6 will assign value to the property instead of assigning to the VariableEnvironment binding of the Identifier.

如果VariableDeclaration嵌套在with语句中,并且VariableDeclaration中的BindingIdentifier与with语句的对象Environment Record的绑定对象的属性名称相同,则第6步将赋值给该属性,而不是分配给VariableEnvironment绑定 的标识符。

var obj = { a: 1 }; with (obj) { var a = 2; } console.log(obj.a); 2
VariableDeclaration:BindingPatternInitializer
  1. Let rhs be the result of evaluating Initializer.
  2. Let rval be ? GetValue(rhs).
  3. Return the result of performing BindingInitialization for BindingPattern passing rval and undefined as arguments.

13.3.3Destructuring Binding Patterns(解构绑定模式)#

Syntax(语法)

BindingPattern[Yield]:ObjectBindingPattern[?Yield] ArrayBindingPattern[?Yield] ObjectBindingPattern[Yield]:{} {BindingPropertyList[?Yield]} {BindingPropertyList[?Yield],} ArrayBindingPattern[Yield]:[ElisionoptBindingRestElement[?Yield]opt] [BindingElementList[?Yield]] [BindingElementList[?Yield],ElisionoptBindingRestElement[?Yield]opt] BindingPropertyList[Yield]:BindingProperty[?Yield] BindingPropertyList[?Yield],BindingProperty[?Yield] BindingElementList[Yield]:BindingElisionElement[?Yield] BindingElementList[?Yield],BindingElisionElement[?Yield] BindingElisionElement[Yield]:ElisionoptBindingElement[?Yield] BindingProperty[Yield]:SingleNameBinding[?Yield] PropertyName[?Yield]:BindingElement[?Yield] BindingElement[Yield]:SingleNameBinding[?Yield] BindingPattern[?Yield]Initializer[In, ?Yield]opt SingleNameBinding[Yield]:BindingIdentifier[?Yield]Initializer[In, ?Yield]opt BindingRestElement[Yield]:...BindingIdentifier[?Yield] ...BindingPattern[?Yield] // destructure let des = { desp: 2 }; let {desp} = des; console.log(desp); 2 let des2 = { desp2: 2, }; let {desp2} = des2; console.log(desp2); 2 let {} = des2; let desArr = [1, 2, 3]; let [...desArr2] = desArr; console.log(desArr2); [1, 2, 3] let [desElement1, desElement2, desElement3] = desArr; console.log(desElement1); console.log(desElement2); console.log(desElement3); 1 2 3 let [desElement4] = desArr; console.log(desElement4); 1 let [desElement5, ...restElement] = desArr; console.log(desElement5); console.log(restElement); 1 [2, 3] let desObj = { property1: 2, propertyEle: { property3: 5 } }; let {property1, propertyEle} = desObj; console.log(property1); console.log(propertyEle); 2 {property3: 5} let {property1: property6} = desObj; console.log(property6); 2 // 嵌套 let {propertyEle: {property3}} = desObj; console.log(propertyEle); console.log(property3); {property3: 5} 5 // 初始值 let {property7 = 99} = desObj; console.log(property7); 99

13.3.3.1Static Semantics: BoundNames#

ObjectBindingPattern:{}
  1. Return a new empty List.
ArrayBindingPattern:[Elisionopt]
  1. Return a new empty List.
ArrayBindingPattern:[ElisionoptBindingRestElement]
  1. Return the BoundNames of BindingRestElement.
ArrayBindingPattern:[BindingElementList,Elisionopt]
  1. Return the BoundNames of BindingElementList.
ArrayBindingPattern:[BindingElementList,ElisionoptBindingRestElement]
  1. Let names be BoundNames of BindingElementList.
  2. Append to names the elements of BoundNames of BindingRestElement.
  3. Return names.
BindingPropertyList:BindingPropertyList,BindingProperty
  1. Let names be BoundNames of BindingPropertyList.
  2. Append to names the elements of BoundNames of BindingProperty.
  3. Return names.
BindingElementList:BindingElementList,BindingElisionElement
  1. Let names be BoundNames of BindingElementList.
  2. Append to names the elements of BoundNames of BindingElisionElement.
  3. Return names.
BindingElisionElement:ElisionoptBindingElement
  1. Return BoundNames of BindingElement.
BindingProperty:PropertyName:BindingElement
  1. Return the BoundNames of BindingElement.
SingleNameBinding:BindingIdentifierInitializeropt
  1. Return the BoundNames of BindingIdentifier.
BindingElement:BindingPatternInitializeropt
  1. Return the BoundNames of BindingPattern.

13.3.3.2Static Semantics: ContainsExpression#

ObjectBindingPattern:{}
  1. Return false.
ArrayBindingPattern:[Elisionopt]
  1. Return false.
ArrayBindingPattern:[ElisionoptBindingRestElement]
  1. Return ContainsExpression of BindingRestElement.
ArrayBindingPattern:[BindingElementList,Elisionopt]
  1. Return ContainsExpression of BindingElementList.
ArrayBindingPattern:[BindingElementList,ElisionoptBindingRestElement]
  1. Let has be ContainsExpression of BindingElementList.
  2. If has is true, return true.
  3. Return ContainsExpression of BindingRestElement.
BindingPropertyList:BindingPropertyList,BindingProperty
  1. Let has be ContainsExpression of BindingPropertyList.
  2. If has is true, return true.
  3. Return ContainsExpression of BindingProperty.
BindingElementList:BindingElementList,BindingElisionElement
  1. Let has be ContainsExpression of BindingElementList.
  2. If has is true, return true.
  3. Return ContainsExpression of BindingElisionElement.
BindingElisionElement:ElisionoptBindingElement
  1. Return ContainsExpression of BindingElement.
BindingProperty:PropertyName:BindingElement
  1. Let has be IsComputedPropertyKey of PropertyName.
  2. If has is true, return true.
  3. Return ContainsExpression of BindingElement.
BindingElement:BindingPatternInitializer
  1. Return true.
SingleNameBinding:BindingIdentifier
  1. Return false.
SingleNameBinding:BindingIdentifierInitializer
  1. Return true.
BindingRestElement:...BindingIdentifier
  1. Return false.
BindingRestElement:...BindingPattern
  1. Return ContainsExpression of BindingPattern.

13.3.3.3Static Semantics: HasInitializer#

BindingElement:BindingPattern
  1. Return false.
BindingElement:BindingPatternInitializer
  1. Return true.
SingleNameBinding:BindingIdentifier
  1. Return false.
SingleNameBinding:BindingIdentifierInitializer
  1. Return true.

13.3.3.4Static Semantics: IsSimpleParameterList#

BindingElement:BindingPattern
  1. Return false.
BindingElement:BindingPatternInitializer
  1. Return false.
SingleNameBinding:BindingIdentifier
  1. Return true.
SingleNameBinding:BindingIdentifierInitializer
  1. Return false.

13.3.3.5Runtime Semantics: BindingInitialization#

With parameters value and environment.

Note

When undefined is passed for environment it indicates that a PutValue operation should be used to assign the initialization value. This is the case for formal parameter lists of non-strict functions. In that case the formal parameter bindings are preinitialized in order to deal with the possibility of multiple parameters with the same name.

当environment传入未定义时,表示应该使用PutValue操作来分配初始化值。 非严格模式函数的形式参数列表就是这种情况。 在这种情况下,为了处理具有相同名称的多个参数的可能性,形式参数绑定被初始化。

BindingPattern:ObjectBindingPattern
  1. Perform ? RequireObjectCoercible(value).
  2. Return the result of performing BindingInitialization for ObjectBindingPattern using value and environment as arguments.
BindingPattern:ArrayBindingPattern
  1. Let iterator be ? GetIterator(value).
  2. Let iteratorRecord be Record {[[Iterator]]: iterator, [[Done]]: false}.
  3. Let result be IteratorBindingInitialization for ArrayBindingPattern using iteratorRecord and environment as arguments.
  4. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iterator, result).
  5. Return result.
ObjectBindingPattern:{}
  1. Return NormalCompletion(empty).
BindingPropertyList:BindingPropertyList,BindingProperty
  1. Let status be the result of performing BindingInitialization for BindingPropertyList using value and environment as arguments.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing BindingInitialization for BindingProperty using value and environment as arguments.
BindingProperty:SingleNameBinding
  1. Let name be the string that is the only element of BoundNames of SingleNameBinding.
  2. Return the result of performing KeyedBindingInitialization for SingleNameBinding using value, environment, and name as the arguments.
BindingProperty:PropertyName:BindingElement
  1. Let P be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(P).
  3. Return the result of performing KeyedBindingInitialization for BindingElement using value, environment, and P as arguments.

13.3.3.6Runtime Semantics: IteratorBindingInitialization#

With parameters iteratorRecord, and environment.

Note

When undefined is passed for environment it indicates that a PutValue operation should be used to assign the initialization value. This is the case for formal parameter lists of non-strict functions. In that case the formal parameter bindings are preinitialized in order to deal with the possibility of multiple parameters with the same name.

ArrayBindingPattern:[]
  1. Return NormalCompletion(empty).
ArrayBindingPattern:[Elision]
  1. Return the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
ArrayBindingPattern:[ElisionoptBindingRestElement]
  1. If Elision is present, then
    1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
    2. ReturnIfAbrupt(status).
  2. Return the result of performing IteratorBindingInitialization for BindingRestElement with iteratorRecord and environment as arguments.
ArrayBindingPattern:[BindingElementList]
  1. Return the result of performing IteratorBindingInitialization for BindingElementList with iteratorRecord and environment as arguments.
ArrayBindingPattern:[BindingElementList,]
  1. Return the result of performing IteratorBindingInitialization for BindingElementList with iteratorRecord and environment as arguments.
ArrayBindingPattern:[BindingElementList,Elision]
  1. Let status be the result of performing IteratorBindingInitialization for BindingElementList with iteratorRecord and environment as arguments.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
ArrayBindingPattern:[BindingElementList,ElisionoptBindingRestElement]
  1. Let status be the result of performing IteratorBindingInitialization for BindingElementList with iteratorRecord and environment as arguments.
  2. ReturnIfAbrupt(status).
  3. If Elision is present, then
    1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
    2. ReturnIfAbrupt(status).
  4. Return the result of performing IteratorBindingInitialization for BindingRestElement with iteratorRecord and environment as arguments.
BindingElementList:BindingElisionElement
  1. Return the result of performing IteratorBindingInitialization for BindingElisionElement with iteratorRecord and environment as arguments.
BindingElementList:BindingElementList,BindingElisionElement
  1. Let status be the result of performing IteratorBindingInitialization for BindingElementList with iteratorRecord and environment as arguments.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing IteratorBindingInitialization for BindingElisionElement using iteratorRecord and environment as arguments.
BindingElisionElement:BindingElement
  1. Return the result of performing IteratorBindingInitialization of BindingElement with iteratorRecord and environment as the arguments.
BindingElisionElement:ElisionBindingElement
  1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing IteratorBindingInitialization of BindingElement with iteratorRecord and environment as the arguments.
BindingElement:SingleNameBinding
  1. Return the result of performing IteratorBindingInitialization for SingleNameBinding with iteratorRecord and environment as the arguments.
SingleNameBinding:BindingIdentifierInitializeropt
  1. Let bindingId be StringValue of BindingIdentifier.
  2. Let lhs be ? ResolveBinding(bindingId, environment).
  3. If iteratorRecord.[[Done]] is false, then
    1. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, set iteratorRecord.[[Done]] to true.
    5. Else,
      1. Let v be IteratorValue(next).
      2. If v is an abrupt completion, set iteratorRecord.[[Done]] to true.
      3. ReturnIfAbrupt(v).
  4. If iteratorRecord.[[Done]] is true, let v be undefined.
  5. If Initializer is present and v is undefined, then
    1. Let defaultValue be the result of evaluating Initializer.
    2. Let v be ? GetValue(defaultValue).
    3. If IsAnonymousFunctionDefinition(Initializer) is true, then
      1. Let hasNameProperty be ? HasOwnProperty(v, "name").
      2. If hasNameProperty is false, perform SetFunctionName(v, bindingId).
  6. If environment is undefined, return ? PutValue(lhs, v).
  7. Return InitializeReferencedBinding(lhs, v).
BindingElement:BindingPatternInitializeropt
  1. If iteratorRecord.[[Done]] is false, then
    1. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, set iteratorRecord.[[Done]] to true.
    5. Else,
      1. Let v be IteratorValue(next).
      2. If v is an abrupt completion, set iteratorRecord.[[Done]] to true.
      3. ReturnIfAbrupt(v).
  2. If iteratorRecord.[[Done]] is true, let v be undefined.
  3. If Initializer is present and v is undefined, then
    1. Let defaultValue be the result of evaluating Initializer.
    2. Let v be ? GetValue(defaultValue).
  4. Return the result of performing BindingInitialization of BindingPattern with v and environment as the arguments.
BindingRestElement:...BindingIdentifier
  1. Let lhs be ? ResolveBinding(StringValue of BindingIdentifier, environment).
  2. Let A be ArrayCreate(0).
  3. Let n be 0.
  4. Repeat,
    1. If iteratorRecord.[[Done]] is false, then
      1. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
      2. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
      3. ReturnIfAbrupt(next).
      4. If next is false, set iteratorRecord.[[Done]] to true.
    2. If iteratorRecord.[[Done]] is true, then
      1. If environment is undefined, return ? PutValue(lhs, A).
      2. Return InitializeReferencedBinding(lhs, A).
    3. Let nextValue be IteratorValue(next).
    4. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
    5. ReturnIfAbrupt(nextValue).
    6. Let status be CreateDataProperty(A, ! ToString(n), nextValue).
    7. Assert: status is true.
    8. Increment n by 1.
BindingRestElement:...BindingPattern
  1. Let A be ArrayCreate(0).
  2. Let n be 0.
  3. Repeat,
    1. If iteratorRecord.[[Done]] is false, then
      1. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
      2. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
      3. ReturnIfAbrupt(next).
      4. If next is false, set iteratorRecord.[[Done]] to true.
    2. If iteratorRecord.[[Done]] is true, then
      1. Return the result of performing BindingInitialization of BindingPattern with A and environment as the arguments.
    3. Let nextValue be IteratorValue(next).
    4. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
    5. ReturnIfAbrupt(nextValue).
    6. Let status be CreateDataProperty(A, ! ToString(n), nextValue).
    7. Assert: status is true.
    8. Increment n by 1.

13.3.3.7Runtime Semantics: KeyedBindingInitialization#

With parameters value, environment, and propertyName.

Note

When undefined is passed for environment it indicates that a PutValue operation should be used to assign the initialization value. This is the case for formal parameter lists of non-strict functions. In that case the formal parameter bindings are preinitialized in order to deal with the possibility of multiple parameters with the same name.

BindingElement:BindingPatternInitializeropt
  1. Let v be ? GetV(value, propertyName).
  2. If Initializer is present and v is undefined, then
    1. Let defaultValue be the result of evaluating Initializer.
    2. Let v be ? GetValue(defaultValue).
  3. Return the result of performing BindingInitialization for BindingPattern passing v and environment as arguments.
SingleNameBinding:BindingIdentifierInitializeropt
  1. Let bindingId be StringValue of BindingIdentifier.
  2. Let lhs be ? ResolveBinding(bindingId, environment).
  3. Let v be ? GetV(value, propertyName).
  4. If Initializer is present and v is undefined, then
    1. Let defaultValue be the result of evaluating Initializer.
    2. Let v be ? GetValue(defaultValue).
    3. If IsAnonymousFunctionDefinition(Initializer) is true, then
      1. Let hasNameProperty be ? HasOwnProperty(v, "name").
      2. If hasNameProperty is false, perform SetFunctionName(v, bindingId).
  5. If environment is undefined, return ? PutValue(lhs, v).
  6. Return InitializeReferencedBinding(lhs, v).

13.4Empty Statement(空语句)#

Syntax

EmptyStatement:;

13.4.1Runtime Semantics: Evaluation#

EmptyStatement:;
  1. Return NormalCompletion(empty).

13.5Expression Statement(表达式语句)#

Syntax

ExpressionStatement[Yield]:[lookahead ∉ { {, function, class, let [ }]Expression[In, ?Yield]; Note

An ExpressionStatement cannot start with a U+007B (LEFT CURLY BRACKET) because that might make it ambiguous with a Block. Also, an ExpressionStatement cannot start with the function or class keywords because that would make it ambiguous with a FunctionDeclaration, a GeneratorDeclaration, or a ClassDeclaration. An ExpressionStatement cannot start with the two token sequence let [ because that would make it ambiguous with a let LexicalDeclaration whose first LexicalBinding was an ArrayBindingPattern.

表达式语句不能以U+007B(左大括号)开头,因为这可能会使其与块不一致。 此外,表达式语句不能以function或class关键字开始,因为这会使它与函数声明,生成器声明或类声明不一致。 一个表达式语句不能以两个token序列let [ 开始,因为这会使得第一个词法绑定是一个ArrayBindingPattern的let 词法声明不明确。

13.5.1Runtime Semantics: Evaluation#

ExpressionStatement:Expression;
  1. Let exprRef be the result of evaluating Expression.
  2. Return ? GetValue(exprRef).

13.6The if Statement#

Syntax

IfStatement[Yield, Return]:if(Expression[In, ?Yield])Statement[?Yield, ?Return]elseStatement[?Yield, ?Return] if(Expression[In, ?Yield])Statement[?Yield, ?Return]

Each else for which the choice of associated if is ambiguous shall be associated with the nearest possible if that would otherwise have no corresponding else.

13.6.1Static Semantics: Early Errors#

IfStatement:if(Expression)StatementelseStatement if(Expression)Statement Note

It is only necessary to apply this rule if the extension specified in B.3.2 is implemented.

13.6.2Static Semantics: ContainsDuplicateLabels#

With argument labelSet.

IfStatement:if(Expression)StatementelseStatement
  1. Let hasDuplicate be ContainsDuplicateLabels of the first Statement with argument labelSet.
  2. If hasDuplicate is true, return true.
  3. Return ContainsDuplicateLabels of the second Statement with argument labelSet.
IfStatement:if(Expression)Statement
  1. Return ContainsDuplicateLabels of Statement with argument labelSet.

13.6.3Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

IfStatement:if(Expression)StatementelseStatement
  1. Let hasUndefinedLabels be ContainsUndefinedBreakTarget of the first Statement with argument labelSet.
  2. If hasUndefinedLabels is true, return true.
  3. Return ContainsUndefinedBreakTarget of the second Statement with argument labelSet.
IfStatement:if(Expression)Statement
  1. Return ContainsUndefinedBreakTarget of Statement with argument labelSet.

13.6.4Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

IfStatement:if(Expression)StatementelseStatement
  1. Let hasUndefinedLabels be ContainsUndefinedContinueTarget of the first Statement with arguments iterationSet and « ».
  2. If hasUndefinedLabels is true, return true.
  3. Return ContainsUndefinedContinueTarget of the second Statement with arguments iterationSet and « ».
IfStatement:if(Expression)Statement
  1. Return ContainsUndefinedContinueTarget of Statement with arguments iterationSet and « ».

13.6.5Static Semantics: VarDeclaredNames#

IfStatement:if(Expression)StatementelseStatement
  1. Let names be VarDeclaredNames of the first Statement.
  2. Append to names the elements of the VarDeclaredNames of the second Statement.
  3. Return names.
IfStatement:if(Expression)Statement
  1. Return the VarDeclaredNames of Statement.

13.6.6Static Semantics: VarScopedDeclarations#

IfStatement:if(Expression)StatementelseStatement
  1. Let declarations be VarScopedDeclarations of the first Statement.
  2. Append to declarations the elements of the VarScopedDeclarations of the second Statement.
  3. Return declarations.
IfStatement:if(Expression)Statement
  1. Return the VarScopedDeclarations of Statement.

13.6.7Runtime Semantics: Evaluation#

IfStatement:if(Expression)StatementelseStatement
  1. Let exprRef be the result of evaluating Expression.
  2. Let exprValue be ToBoolean(? GetValue(exprRef)).
  3. If exprValue is true, then
    1. Let stmtCompletion be the result of evaluating the first Statement.
  4. Else,
    1. Let stmtCompletion be the result of evaluating the second Statement.
  5. Return Completion(UpdateEmpty(stmtCompletion, undefined)).
IfStatement:if(Expression)Statement
  1. Let exprRef be the result of evaluating Expression.
  2. Let exprValue be ToBoolean(? GetValue(exprRef)).
  3. If exprValue is false, then
    1. Return NormalCompletion(undefined).
  4. Else,
    1. Let stmtCompletion be the result of evaluating Statement.
    2. Return Completion(UpdateEmpty(stmtCompletion, undefined)).

13.7Iteration Statements#

Syntax

IterationStatement[Yield, Return]:doStatement[?Yield, ?Return]while(Expression[In, ?Yield]); while(Expression[In, ?Yield])Statement[?Yield, ?Return] for([lookahead ∉ { let [ }]Expression[?Yield]opt;Expression[In, ?Yield]opt;Expression[In, ?Yield]opt)Statement[?Yield, ?Return] for(varVariableDeclarationList[?Yield];Expression[In, ?Yield]opt;Expression[In, ?Yield]opt)Statement[?Yield, ?Return] for(LexicalDeclaration[?Yield]Expression[In, ?Yield]opt;Expression[In, ?Yield]opt)Statement[?Yield, ?Return] for([lookahead ∉ { let [ }]LeftHandSideExpression[?Yield]inExpression[In, ?Yield])Statement[?Yield, ?Return] for(varForBinding[?Yield]inExpression[In, ?Yield])Statement[?Yield, ?Return] for(ForDeclaration[?Yield]inExpression[In, ?Yield])Statement[?Yield, ?Return] for([lookahead ≠ let]LeftHandSideExpression[?Yield]ofAssignmentExpression[In, ?Yield])Statement[?Yield, ?Return] for(varForBinding[?Yield]ofAssignmentExpression[In, ?Yield])Statement[?Yield, ?Return] for(ForDeclaration[?Yield]ofAssignmentExpression[In, ?Yield])Statement[?Yield, ?Return] ForDeclaration[Yield]:LetOrConstForBinding[?Yield] ForBinding[Yield]:BindingIdentifier[?Yield] BindingPattern[?Yield]

13.7.1Semantics#

13.7.1.1Static Semantics: Early Errors#

IterationStatement:doStatementwhile(Expression); while(Expression)Statement for(Expressionopt;Expressionopt;Expressionopt)Statement for(varVariableDeclarationList;Expressionopt;Expressionopt)Statement for(LexicalDeclarationExpressionopt;Expressionopt)Statement for(LeftHandSideExpressioninExpression)Statement for(varForBindinginExpression)Statement for(ForDeclarationinExpression)Statement for(LeftHandSideExpressionofAssignmentExpression)Statement for(varForBindingofAssignmentExpression)Statement for(ForDeclarationofAssignmentExpression)Statement Note

It is only necessary to apply this rule if the extension specified in B.3.2 is implemented.

13.7.1.2Runtime Semantics: LoopContinues(completion, labelSet)#

The abstract operation LoopContinues with arguments completion and labelSet is defined by the following steps:

  1. If completion.[[Type]] is normal, return true.
  2. If completion.[[Type]] is not continue, return false.
  3. If completion.[[Target]] is empty, return true.
  4. If completion.[[Target]] is an element of labelSet, return true.
  5. Return false.
Note

Within the Statement part of an IterationStatement a ContinueStatement may be used to begin a new iteration.

13.7.2The do-while Statement#

13.7.2.1Static Semantics: ContainsDuplicateLabels#

With argument labelSet.

IterationStatement:doStatementwhile(Expression);
  1. Return ContainsDuplicateLabels of Statement with argument labelSet.

13.7.2.2Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

IterationStatement:doStatementwhile(Expression);
  1. Return ContainsUndefinedBreakTarget of Statement with argument labelSet.

13.7.2.3Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

IterationStatement:doStatementwhile(Expression);
  1. Return ContainsUndefinedContinueTarget of Statement with arguments iterationSet and « ».

13.7.2.4Static Semantics: VarDeclaredNames#

IterationStatement:doStatementwhile(Expression);
  1. Return the VarDeclaredNames of Statement.

13.7.2.5Static Semantics: VarScopedDeclarations#

IterationStatement:doStatementwhile(Expression);
  1. Return the VarScopedDeclarations of Statement.

13.7.2.6Runtime Semantics: LabelledEvaluation#

With argument labelSet.

IterationStatement:doStatementwhile(Expression);
  1. Let V be undefined.
  2. Repeat
    1. Let stmt be the result of evaluating Statement.
    2. If LoopContinues(stmt, labelSet) is false, return Completion(UpdateEmpty(stmt, V)).
    3. If stmt.[[Value]] is not empty, let V be stmt.[[Value]].
    4. Let exprRef be the result of evaluating Expression.
    5. Let exprValue be ? GetValue(exprRef).
    6. If ToBoolean(exprValue) is false, return NormalCompletion(V).

13.7.3The while Statement#

13.7.3.1Static Semantics: ContainsDuplicateLabels#

With argument labelSet.

IterationStatement:while(Expression)Statement
  1. Return ContainsDuplicateLabels of Statement with argument labelSet.

13.7.3.2Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

IterationStatement:while(Expression)Statement
  1. Return ContainsUndefinedBreakTarget of Statement with argument labelSet.

13.7.3.3Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

IterationStatement:while(Expression)Statement
  1. Return ContainsUndefinedContinueTarget of Statement with arguments iterationSet and « ».

13.7.3.4Static Semantics: VarDeclaredNames#

IterationStatement:while(Expression)Statement
  1. Return the VarDeclaredNames of Statement.

13.7.3.5Static Semantics: VarScopedDeclarations#

IterationStatement:while(Expression)Statement
  1. Return the VarScopedDeclarations of Statement.

13.7.3.6Runtime Semantics: LabelledEvaluation#

With argument labelSet.

IterationStatement:while(Expression)Statement
  1. Let V be undefined.
  2. Repeat
    1. Let exprRef be the result of evaluating Expression.
    2. Let exprValue be ? GetValue(exprRef).
    3. If ToBoolean(exprValue) is false, return NormalCompletion(V).
    4. Let stmt be the result of evaluating Statement.
    5. If LoopContinues(stmt, labelSet) is false, return Completion(UpdateEmpty(stmt, V)).
    6. If stmt.[[Value]] is not empty, let V be stmt.[[Value]].

13.7.4The for Statement#

13.7.4.1Static Semantics: Early Errors#

IterationStatement:for(LexicalDeclarationExpressionopt;Expressionopt)Statement

13.7.4.2Static Semantics: ContainsDuplicateLabels#

With argument labelSet.

IterationStatement:for(Expressionopt;Expressionopt;Expressionopt)Statement for(varVariableDeclarationList;Expressionopt;Expressionopt)Statement for(LexicalDeclarationExpressionopt;Expressionopt)Statement
  1. Return ContainsDuplicateLabels of Statement with argument labelSet.

13.7.4.3Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

IterationStatement:for(Expressionopt;Expressionopt;Expressionopt)Statement for(varVariableDeclarationList;Expressionopt;Expressionopt)Statement for(LexicalDeclarationExpressionopt;Expressionopt)Statement
  1. Return ContainsUndefinedBreakTarget of Statement with argument labelSet.

13.7.4.4Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

IterationStatement:for(Expressionopt;Expressionopt;Expressionopt)Statement for(varVariableDeclarationList;Expressionopt;Expressionopt)Statement for(LexicalDeclarationExpressionopt;Expressionopt)Statement
  1. Return ContainsUndefinedContinueTarget of Statement with arguments iterationSet and « ».

13.7.4.5Static Semantics: VarDeclaredNames#

IterationStatement:for(Expressionopt;Expressionopt;Expressionopt)Statement
  1. Return the VarDeclaredNames of Statement.
IterationStatement:for(varVariableDeclarationList;Expressionopt;Expressionopt)Statement
  1. Let names be BoundNames of VariableDeclarationList.
  2. Append to names the elements of the VarDeclaredNames of Statement.
  3. Return names.
IterationStatement:for(LexicalDeclarationExpressionopt;Expressionopt)Statement
  1. Return the VarDeclaredNames of Statement.

13.7.4.6Static Semantics: VarScopedDeclarations#

IterationStatement:for(Expressionopt;Expressionopt;Expressionopt)Statement
  1. Return the VarScopedDeclarations of Statement.
IterationStatement:for(varVariableDeclarationList;Expressionopt;Expressionopt)Statement
  1. Let declarations be VarScopedDeclarations of VariableDeclarationList.
  2. Append to declarations the elements of the VarScopedDeclarations of Statement.
  3. Return declarations.
IterationStatement:for(LexicalDeclarationExpressionopt;Expressionopt)Statement
  1. Return the VarScopedDeclarations of Statement.

13.7.4.7Runtime Semantics: LabelledEvaluation#

With argument labelSet.

IterationStatement:for(Expressionopt;Expressionopt;Expressionopt)Statement
  1. If the first Expression is present, then
    1. Let exprRef be the result of evaluating the first Expression.
    2. Perform ? GetValue(exprRef).
  2. Return ? ForBodyEvaluation(the second Expression, the third Expression, Statement, « », labelSet).
IterationStatement:for(varVariableDeclarationList;Expressionopt;Expressionopt)Statement
  1. Let varDcl be the result of evaluating VariableDeclarationList.
  2. ReturnIfAbrupt(varDcl).
  3. Return ? ForBodyEvaluation(the first Expression, the second Expression, Statement, « », labelSet).
IterationStatement:for(LexicalDeclarationExpressionopt;Expressionopt)Statement
  1. Let oldEnv be the running execution context's LexicalEnvironment.
  2. Let loopEnv be NewDeclarativeEnvironment(oldEnv).
  3. Let loopEnvRec be loopEnv's EnvironmentRecord.
  4. Let isConst be the result of performing IsConstantDeclaration of LexicalDeclaration.
  5. Let boundNames be the BoundNames of LexicalDeclaration.
  6. For each element dn of boundNames do
    1. If isConst is true, then
      1. Perform ! loopEnvRec.CreateImmutableBinding(dn, true).
    2. Else,
      1. Perform ! loopEnvRec.CreateMutableBinding(dn, false).
  7. Set the running execution context's LexicalEnvironment to loopEnv.
  8. Let forDcl be the result of evaluating LexicalDeclaration.
  9. If forDcl is an abrupt completion, then
    1. Set the running execution context's LexicalEnvironment to oldEnv.
    2. Return Completion(forDcl).
  10. If isConst is false, let perIterationLets be boundNames; otherwise let perIterationLets be « ».
  11. Let bodyResult be ForBodyEvaluation(the first Expression, the second Expression, Statement, perIterationLets, labelSet).
  12. Set the running execution context's LexicalEnvironment to oldEnv.
  13. Return Completion(bodyResult).

13.7.4.8Runtime Semantics: ForBodyEvaluation( test, increment, stmt, perIterationBindings, labelSet )#

The abstract operation ForBodyEvaluation with arguments test, increment, stmt, perIterationBindings, and labelSet is performed as follows:

  1. Let V be undefined.
  2. Perform ? CreatePerIterationEnvironment(perIterationBindings).
  3. Repeat
    1. If test is not [empty], then
      1. Let testRef be the result of evaluating test.
      2. Let testValue be ? GetValue(testRef).
      3. If ToBoolean(testValue) is false, return NormalCompletion(V).
    2. Let result be the result of evaluating stmt.
    3. If LoopContinues(result, labelSet) is false, return Completion(UpdateEmpty(result, V)).
    4. If result.[[Value]] is not empty, let V be result.[[Value]].
    5. Perform ? CreatePerIterationEnvironment(perIterationBindings).
    6. If increment is not [empty], then
      1. Let incRef be the result of evaluating increment.
      2. Perform ? GetValue(incRef).

13.7.4.9Runtime Semantics: CreatePerIterationEnvironment( perIterationBindings )#

The abstract operation CreatePerIterationEnvironment with argument perIterationBindings is performed as follows:

  1. If perIterationBindings has any elements, then
    1. Let lastIterationEnv be the running execution context's LexicalEnvironment.
    2. Let lastIterationEnvRec be lastIterationEnv's EnvironmentRecord.
    3. Let outer be lastIterationEnv's outer environment reference.
    4. Assert: outer is not null.
    5. Let thisIterationEnv be NewDeclarativeEnvironment(outer).
    6. Let thisIterationEnvRec be thisIterationEnv's EnvironmentRecord.
    7. For each element bn of perIterationBindings do,
      1. Perform ! thisIterationEnvRec.CreateMutableBinding(bn, false).
      2. Let lastValue be ? lastIterationEnvRec.GetBindingValue(bn, true).
      3. Perform thisIterationEnvRec.InitializeBinding(bn, lastValue).
    8. Set the running execution context's LexicalEnvironment to thisIterationEnv.
  2. Return undefined.

13.7.5The for-in and for-of Statements#

13.7.5.1Static Semantics: Early Errors#

IterationStatement:for(LeftHandSideExpressioninExpression)Statement for(LeftHandSideExpressionofAssignmentExpression)Statement

If LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if the lexical token sequence matched by LeftHandSideExpression can be parsed with no tokens left over using AssignmentPattern as the goal symbol then the following rules are not applied. Instead, the Early Error rules for AssignmentPattern are used.

Note

The last rule means that the other rules are applied even if parentheses surround Expression.

IterationStatement:for(ForDeclarationinExpression)Statement for(ForDeclarationofAssignmentExpression)Statement
  • It is a Syntax Error if the BoundNames of ForDeclaration contains "let".
  • It is a Syntax Error if any element of the BoundNames of ForDeclaration also occurs in the VarDeclaredNames of Statement.
  • It is a Syntax Error if the BoundNames of ForDeclaration contains any duplicate entries.

13.7.5.2Static Semantics: BoundNames#

ForDeclaration:LetOrConstForBinding
  1. Return the BoundNames of ForBinding.

13.7.5.3Static Semantics: ContainsDuplicateLabels#

With argument labelSet.

IterationStatement:for(LeftHandSideExpressioninExpression)Statement for(varForBindinginExpression)Statement for(ForDeclarationinExpression)Statement for(LeftHandSideExpressionofAssignmentExpression)Statement for(varForBindingofAssignmentExpression)Statement for(ForDeclarationofAssignmentExpression)Statement
  1. Return ContainsDuplicateLabels of Statement with argument labelSet.

13.7.5.4Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

IterationStatement:for(LeftHandSideExpressioninExpression)Statement for(varForBindinginExpression)Statement for(ForDeclarationinExpression)Statement for(LeftHandSideExpressionofAssignmentExpression)Statement for(varForBindingofAssignmentExpression)Statement for(ForDeclarationofAssignmentExpression)Statement
  1. Return ContainsUndefinedBreakTarget of Statement with argument labelSet.

13.7.5.5Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

IterationStatement:for(LeftHandSideExpressioninExpression)Statement for(varForBindinginExpression)Statement for(ForDeclarationinExpression)Statement for(LeftHandSideExpressionofAssignmentExpression)Statement for(varForBindingofAssignmentExpression)Statement for(ForDeclarationofAssignmentExpression)Statement
  1. Return ContainsUndefinedContinueTarget of Statement with arguments iterationSet and « ».

13.7.5.6Static Semantics: IsDestructuring#

ForDeclaration:LetOrConstForBinding
  1. Return IsDestructuring of ForBinding.
ForBinding:BindingIdentifier
  1. Return false.
ForBinding:BindingPattern
  1. Return true.

13.7.5.7Static Semantics: VarDeclaredNames#

IterationStatement:for(LeftHandSideExpressioninExpression)Statement
  1. Return the VarDeclaredNames of Statement.
IterationStatement:for(varForBindinginExpression)Statement
  1. Let names be the BoundNames of ForBinding.
  2. Append to names the elements of the VarDeclaredNames of Statement.
  3. Return names.
IterationStatement:for(ForDeclarationinExpression)Statement
  1. Return the VarDeclaredNames of Statement.
IterationStatement:for(LeftHandSideExpressionofAssignmentExpression)Statement
  1. Return the VarDeclaredNames of Statement.
IterationStatement:for(varForBindingofAssignmentExpression)Statement
  1. Let names be the BoundNames of ForBinding.
  2. Append to names the elements of the VarDeclaredNames of Statement.
  3. Return names.
IterationStatement:for(ForDeclarationofAssignmentExpression)Statement
  1. Return the VarDeclaredNames of Statement.

13.7.5.8Static Semantics: VarScopedDeclarations#

IterationStatement:for(LeftHandSideExpressioninExpression)Statement
  1. Return the VarScopedDeclarations of Statement.
IterationStatement:for(varForBindinginExpression)Statement
  1. Let declarations be a List containing ForBinding.
  2. Append to declarations the elements of the VarScopedDeclarations of Statement.
  3. Return declarations.
IterationStatement:for(ForDeclarationinExpression)Statement
  1. Return the VarScopedDeclarations of Statement.
IterationStatement:for(LeftHandSideExpressionofAssignmentExpression)Statement
  1. Return the VarScopedDeclarations of Statement.
IterationStatement:for(varForBindingofAssignmentExpression)Statement
  1. Let declarations be a List containing ForBinding.
  2. Append to declarations the elements of the VarScopedDeclarations of Statement.
  3. Return declarations.
IterationStatement:for(ForDeclarationofAssignmentExpression)Statement
  1. Return the VarScopedDeclarations of Statement.

13.7.5.9Runtime Semantics: BindingInitialization#

With arguments value and environment.

Note

undefined is passed for environment to indicate that a PutValue operation should be used to assign the initialization value. This is the case for var statements and the formal parameter lists of some non-strict functions (see 9.2.12). In those cases a lexical binding is hoisted and preinitialized prior to evaluation of its initializer.

ForDeclaration:LetOrConstForBinding
  1. Return the result of performing BindingInitialization for ForBinding passing value and environment as the arguments.

13.7.5.10Runtime Semantics: BindingInstantiation#

With argument environment.

ForDeclaration:LetOrConstForBinding
  1. Let envRec be environment's EnvironmentRecord.
  2. Assert: envRec is a declarative Environment Record.
  3. For each element name of the BoundNames of ForBinding do
    1. If IsConstantDeclaration of LetOrConst is true, then
      1. Perform ! envRec.CreateImmutableBinding(name, true).
    2. Else,
      1. Perform ! envRec.CreateMutableBinding(name, false).

13.7.5.11Runtime Semantics: LabelledEvaluation#

With argument labelSet.

IterationStatement:for(LeftHandSideExpressioninExpression)Statement
  1. Let keyResult be ? ForIn/OfHeadEvaluation(« », Expression, enumerate).
  2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, assignment, labelSet).
IterationStatement:for(varForBindinginExpression)Statement
  1. Let keyResult be ? ForIn/OfHeadEvaluation(« », Expression, enumerate).
  2. Return ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, varBinding, labelSet).
IterationStatement:for(ForDeclarationinExpression)Statement
  1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, Expression, enumerate).
  2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, lexicalBinding, labelSet).
IterationStatement:for(LeftHandSideExpressionofAssignmentExpression)Statement
  1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate).
  2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, assignment, labelSet).
IterationStatement:for(varForBindingofAssignmentExpression)Statement
  1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate).
  2. Return ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, varBinding, labelSet).
IterationStatement:for(ForDeclarationofAssignmentExpression)Statement
  1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, iterate).
  2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, lexicalBinding, labelSet).

13.7.5.12Runtime Semantics: ForIn/OfHeadEvaluation ( TDZnames, expr, iterationKind)#

The abstract operation ForIn/OfHeadEvaluation is called with arguments TDZnames, expr, and iterationKind. The value of iterationKind is either enumerate or iterate.

  1. Let oldEnv be the running execution context's LexicalEnvironment.
  2. If TDZnames is not an empty List, then
    1. Assert: TDZnames has no duplicate entries.
    2. Let TDZ be NewDeclarativeEnvironment(oldEnv).
    3. Let TDZEnvRec be TDZ's EnvironmentRecord.
    4. For each string name in TDZnames, do
      1. Perform ! TDZEnvRec.CreateMutableBinding(name, false).
    5. Set the running execution context's LexicalEnvironment to TDZ.
  3. Let exprRef be the result of evaluating expr.
  4. Set the running execution context's LexicalEnvironment to oldEnv.
  5. Let exprValue be ? GetValue(exprRef).
  6. If iterationKind is enumerate, then
    1. If exprValue.[[Value]] is null or undefined, then
      1. Return Completion{[[Type]]: break, [[Value]]: empty, [[Target]]: empty}.
    2. Let obj be ToObject(exprValue).
    3. Return ? EnumerateObjectProperties(obj).
  7. Else,
    1. Assert: iterationKind is iterate.
    2. Return ? GetIterator(exprValue).

13.7.5.13Runtime Semantics: ForIn/OfBodyEvaluation ( lhs, stmt, iterator, lhsKind, labelSet )#

The abstract operation ForIn/OfBodyEvaluation is called with arguments lhs, stmt, iterator, lhsKind, and labelSet. The value of lhsKind is either assignment, varBinding or lexicalBinding.

  1. Let oldEnv be the running execution context's LexicalEnvironment.
  2. Let V be undefined.
  3. Let destructuring be IsDestructuring of lhs.
  4. If destructuring is true and if lhsKind is assignment, then
    1. Assert: lhs is a LeftHandSideExpression.
    2. Let assignmentPattern be the parse of the source text corresponding to lhs using AssignmentPattern as the goal symbol.
  5. Repeat
    1. Let nextResult be ? IteratorStep(iterator).
    2. If nextResult is false, return NormalCompletion(V).
    3. Let nextValue be ? IteratorValue(nextResult).
    4. If lhsKind is either assignment or varBinding, then
      1. If destructuring is false, then
        1. Let lhsRef be the result of evaluating lhs. (It may be evaluated repeatedly.)
    5. Else,
      1. Assert: lhsKind is lexicalBinding.
      2. Assert: lhs is a ForDeclaration.
      3. Let iterationEnv be NewDeclarativeEnvironment(oldEnv).
      4. Perform BindingInstantiation for lhs passing iterationEnv as the argument.
      5. Set the running execution context's LexicalEnvironment to iterationEnv.
      6. If destructuring is false, then
        1. Assert: lhs binds a single name.
        2. Let lhsName be the sole element of BoundNames of lhs.
        3. Let lhsRef be ! ResolveBinding(lhsName).
    6. If destructuring is false, then
      1. If lhsRef is an abrupt completion, then
        1. Let status be lhsRef.
      2. Else if lhsKind is lexicalBinding, then
        1. Let status be InitializeReferencedBinding(lhsRef, nextValue).
      3. Else,
        1. Let status be PutValue(lhsRef, nextValue).
    7. Else,
      1. If lhsKind is assignment, then
        1. Let status be the result of performing DestructuringAssignmentEvaluation of assignmentPattern using nextValue as the argument.
      2. Else if lhsKind is varBinding, then
        1. Assert: lhs is a ForBinding.
        2. Let status be the result of performing BindingInitialization for lhs passing nextValue and undefined as the arguments.
      3. Else,
        1. Assert: lhsKind is lexicalBinding.
        2. Assert: lhs is a ForDeclaration.
        3. Let status be the result of performing BindingInitialization for lhs passing nextValue and iterationEnv as arguments.
    8. If status is an abrupt completion, then
      1. Set the running execution context's LexicalEnvironment to oldEnv.
      2. Return ? IteratorClose(iterator, status).
    9. Let result be the result of evaluating stmt.
    10. Set the running execution context's LexicalEnvironment to oldEnv.
    11. If LoopContinues(result, labelSet) is false, return ? IteratorClose(iterator, UpdateEmpty(result, V)).
    12. If result.[[Value]] is not empty, let V be result.[[Value]].

13.7.5.14Runtime Semantics: Evaluation#

ForBinding:BindingIdentifier
  1. Let bindingId be StringValue of BindingIdentifier.
  2. Return ? ResolveBinding(bindingId).

13.7.5.15EnumerateObjectProperties (O)#

When the abstract operation EnumerateObjectProperties is called with argument O, the following steps are taken:

  1. Assert: Type(O) is Object.
  2. Return an Iterator object (25.1.1.2) whose next method iterates over all the String-valued keys of enumerable properties of O. The iterator object is never directly accessible to ECMAScript code. The mechanics and order of enumerating the properties is not specified but must conform to the rules specified below.

The iterator's throw and return methods are null and are never invoked. The iterator's next method processes object properties to determine whether the property key should be returned as an iterator value. Returned property keys do not include keys that are Symbols. Properties of the target object may be deleted during enumeration. A property that is deleted before it is processed by the iterator's next method is ignored. If new properties are added to the target object during enumeration, the newly added properties are not guaranteed to be processed in the active enumeration. A property name will be returned by the iterator's next method at most once in any enumeration.

Enumerating the properties of the target object includes enumerating properties of its prototype, and the prototype of the prototype, and so on, recursively; but a property of a prototype is not processed if it has the same name as a property that has already been processed by the iterator's next method. The values of [[Enumerable]] attributes are not considered when determining if a property of a prototype object has already been processed. The enumerable property names of prototype objects must be obtained by invoking EnumerateObjectProperties passing the prototype object as the argument. EnumerateObjectProperties must obtain the own property keys of the target object by calling its [[OwnPropertyKeys]] internal method. Property attributes of the target object must be obtained by calling its [[GetOwnProperty]] internal method.

Note

The following is an informative definition of an ECMAScript generator function that conforms to these rules:


  function* EnumerateObjectProperties(obj) {
    let visited = new Set;
    for (let key of Reflect.ownKeys(obj)) {
      if (typeof key === "string") {
        let desc = Reflect.getOwnPropertyDescriptor(obj, key);
        if (desc && !visited.has(key)) {
          visited.add(key);
          if (desc.enumerable) yield key;
        }
      }
    }
    let proto = Reflect.getPrototypeOf(obj)
    if (proto === null) return;
    for (let protoName of EnumerateObjectProperties(proto)) {
      if (!visited.has(protoName)) yield protoName;
    }
  }
          

13.8The continue Statement#

Syntax

ContinueStatement[Yield]:continue; continue[no LineTerminator here]LabelIdentifier[?Yield];

13.8.1Static Semantics: Early Errors#

ContinueStatement:continue; ContinueStatement:continueLabelIdentifier;
  • It is a Syntax Error if this production is not nested, directly or indirectly (but not crossing function boundaries), within an IterationStatement.

13.8.2Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

ContinueStatement:continue;
  1. Return false.
ContinueStatement:continueLabelIdentifier;
  1. If the StringValue of LabelIdentifier is not an element of iterationSet, return true.
  2. Return false.

13.8.3Runtime Semantics: Evaluation#

ContinueStatement:continue;
  1. Return Completion{[[Type]]: continue, [[Value]]: empty, [[Target]]: empty}.
ContinueStatement:continueLabelIdentifier;
  1. Let label be the StringValue of LabelIdentifier.
  2. Return Completion{[[Type]]: continue, [[Value]]: empty, [[Target]]: label }.

13.9The break Statement#

Syntax

BreakStatement[Yield]:break; break[no LineTerminator here]LabelIdentifier[?Yield];

13.9.1Static Semantics: Early Errors#

BreakStatement:break;
  • It is a Syntax Error if this production is not nested, directly or indirectly (but not crossing function boundaries), within an IterationStatement or a SwitchStatement.

13.9.2Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

BreakStatement:break;
  1. Return false.
BreakStatement:breakLabelIdentifier;
  1. If the StringValue of LabelIdentifier is not an element of labelSet, return true.
  2. Return false.

13.9.3Runtime Semantics: Evaluation#

BreakStatement:break;
  1. Return Completion{[[Type]]: break, [[Value]]: empty, [[Target]]: empty}.
BreakStatement:breakLabelIdentifier;
  1. Let label be the StringValue of LabelIdentifier.
  2. Return Completion{[[Type]]: break, [[Value]]: empty, [[Target]]: label }.

13.10The return Statement#

Syntax

ReturnStatement[Yield]:return; return[no LineTerminator here]Expression[In, ?Yield]; Note

A return statement causes a function to cease execution and return a value to the caller. If Expression is omitted, the return value is undefined. Otherwise, the return value is the value of Expression.

13.10.1Runtime Semantics: Evaluation#

ReturnStatement:return;
  1. Return Completion{[[Type]]: return, [[Value]]: undefined, [[Target]]: empty}.
ReturnStatement:returnExpression;
  1. Let exprRef be the result of evaluating Expression.
  2. Let exprValue be ? GetValue(exprRef).
  3. Return Completion{[[Type]]: return, [[Value]]: exprValue, [[Target]]: empty}.

13.11The with Statement#

Syntax

WithStatement[Yield, Return]:with(Expression[In, ?Yield])Statement[?Yield, ?Return] Note

The with statement adds an object Environment Record for a computed object to the lexical environment of the running execution context. It then executes a statement using this augmented lexical environment. Finally, it restores the original lexical environment.

13.11.1Static Semantics: Early Errors#

WithStatement:with(Expression)Statement
  • It is a Syntax Error if the code that matches this production is contained in strict code.
  • It is a Syntax Error if IsLabelledFunction(Statement) is true.
Note

It is only necessary to apply the second rule if the extension specified in B.3.2 is implemented.

13.11.2Static Semantics: ContainsDuplicateLabels#

With argument labelSet.

WithStatement:with(Expression)Statement
  1. Return ContainsDuplicateLabels of Statement with argument labelSet.

13.11.3Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

WithStatement:with(Expression)Statement
  1. Return ContainsUndefinedBreakTarget of Statement with argument labelSet.

13.11.4Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

WithStatement:with(Expression)Statement
  1. Return ContainsUndefinedContinueTarget of Statement with arguments iterationSet and « ».

13.11.5Static Semantics: VarDeclaredNames#

WithStatement:with(Expression)Statement
  1. Return the VarDeclaredNames of Statement.

13.11.6Static Semantics: VarScopedDeclarations#

WithStatement:with(Expression)Statement
  1. Return the VarScopedDeclarations of Statement.

13.11.7Runtime Semantics: Evaluation#

WithStatement:with(Expression)Statement
  1. Let val be the result of evaluating Expression.
  2. Let obj be ? ToObject(? GetValue(val)).
  3. Let oldEnv be the running execution context's LexicalEnvironment.
  4. Let newEnv be NewObjectEnvironment(obj, oldEnv).
  5. Set the withEnvironment flag of newEnv's EnvironmentRecord to true.
  6. Set the running execution context's LexicalEnvironment to newEnv.
  7. Let C be the result of evaluating Statement.
  8. Set the running execution context's LexicalEnvironment to oldEnv.
  9. Return Completion(UpdateEmpty(C, undefined)).
Note

No matter how control leaves the embedded Statement, whether normally or by some form of abrupt completion or exception, the LexicalEnvironment is always restored to its former state.

13.12The switch Statement#

Syntax

SwitchStatement[Yield, Return]:switch(Expression[In, ?Yield])CaseBlock[?Yield, ?Return] CaseBlock[Yield, Return]:{CaseClauses[?Yield, ?Return]opt} {CaseClauses[?Yield, ?Return]optDefaultClause[?Yield, ?Return]CaseClauses[?Yield, ?Return]opt} CaseClauses[Yield, Return]:CaseClause[?Yield, ?Return] CaseClauses[?Yield, ?Return]CaseClause[?Yield, ?Return] CaseClause[Yield, Return]:caseExpression[In, ?Yield]:StatementList[?Yield, ?Return]opt DefaultClause[Yield, Return]:default:StatementList[?Yield, ?Return]opt

13.12.1Static Semantics: Early Errors#

SwitchStatement:switch(Expression)CaseBlock
  • It is a Syntax Error if the LexicallyDeclaredNames of CaseBlock contains any duplicate entries.
  • It is a Syntax Error if any element of the LexicallyDeclaredNames of CaseBlock also occurs in the VarDeclaredNames of CaseBlock.

13.12.2Static Semantics: ContainsDuplicateLabels#

With argument labelSet.

SwitchStatement:switch(Expression)CaseBlock
  1. Return ContainsDuplicateLabels of CaseBlock with argument labelSet.
CaseBlock:{}
  1. Return false.
CaseBlock:{CaseClausesoptDefaultClauseCaseClausesopt}
  1. If the first CaseClauses is present, then
    1. Let hasDuplicates be ContainsDuplicateLabels of the first CaseClauses with argument labelSet.
    2. If hasDuplicates is true, return true.
  2. Let hasDuplicates be ContainsDuplicateLabels of DefaultClause with argument labelSet.
  3. If hasDuplicates is true, return true.
  4. If the second CaseClauses is not present, return false.
  5. Return ContainsDuplicateLabels of the second CaseClauses with argument labelSet.
CaseClauses:CaseClausesCaseClause
  1. Let hasDuplicates be ContainsDuplicateLabels of CaseClauses with argument labelSet.
  2. If hasDuplicates is true, return true.
  3. Return ContainsDuplicateLabels of CaseClause with argument labelSet.
CaseClause:caseExpression:StatementListopt
  1. If the StatementList is present, return ContainsDuplicateLabels of StatementList with argument labelSet.
  2. Else return false.
DefaultClause:default:StatementListopt
  1. If the StatementList is present, return ContainsDuplicateLabels of StatementList with argument labelSet.
  2. Else return false.

13.12.3Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

SwitchStatement:switch(Expression)CaseBlock
  1. Return ContainsUndefinedBreakTarget of CaseBlock with argument labelSet.
CaseBlock:{}
  1. Return false.
CaseBlock:{CaseClausesoptDefaultClauseCaseClausesopt}
  1. If the first CaseClauses is present, then
    1. Let hasUndefinedLabels be ContainsUndefinedBreakTarget of the first CaseClauses with argument labelSet.
    2. If hasUndefinedLabels is true, return true.
  2. Let hasUndefinedLabels be ContainsUndefinedBreakTarget of DefaultClause with argument labelSet.
  3. If hasUndefinedLabels is true, return true.
  4. If the second CaseClauses is not present, return false.
  5. Return ContainsUndefinedBreakTarget of the second CaseClauses with argument labelSet.
CaseClauses:CaseClausesCaseClause
  1. Let hasUndefinedLabels be ContainsUndefinedBreakTarget of CaseClauses with argument labelSet.
  2. If hasUndefinedLabels is true, return true.
  3. Return ContainsUndefinedBreakTarget of CaseClause with argument labelSet.
CaseClause:caseExpression:StatementListopt
  1. If the StatementList is present, return ContainsUndefinedBreakTarget of StatementList with argument labelSet.
  2. Else return false.
DefaultClause:default:StatementListopt
  1. If the StatementList is present, return ContainsUndefinedBreakTarget of StatementList with argument labelSet.
  2. Else return false.

13.12.4Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

SwitchStatement:switch(Expression)CaseBlock
  1. Return ContainsUndefinedContinueTarget of CaseBlock with arguments iterationSet and « ».
CaseBlock:{}
  1. Return false.
CaseBlock:{CaseClausesoptDefaultClauseCaseClausesopt}
  1. If the first CaseClauses is present, then
    1. Let hasUndefinedLabels be ContainsUndefinedContinueTarget of the first CaseClauses with arguments iterationSet and « ».
    2. If hasUndefinedLabels is true, return true.
  2. Let hasUndefinedLabels be ContainsUndefinedContinueTarget of DefaultClause with arguments iterationSet and « ».
  3. If hasUndefinedLabels is true, return true.
  4. If the second CaseClauses is not present, return false.
  5. Return ContainsUndefinedContinueTarget of the second CaseClauses with arguments iterationSet and « ».
CaseClauses:CaseClausesCaseClause
  1. Let hasUndefinedLabels be ContainsUndefinedContinueTarget of CaseClauses with arguments iterationSet and « ».
  2. If hasUndefinedLabels is true, return true.
  3. Return ContainsUndefinedContinueTarget of CaseClause with arguments iterationSet and « ».
CaseClause:caseExpression:StatementListopt
  1. If the StatementList is present, return ContainsUndefinedContinueTarget of StatementList with arguments iterationSet and « ».
  2. Else return false.
DefaultClause:default:StatementListopt
  1. If the StatementList is present, return ContainsUndefinedContinueTarget of StatementList with arguments iterationSet and « ».
  2. Else return false.

13.12.5Static Semantics: LexicallyDeclaredNames#

CaseBlock:{}
  1. Return a new empty List.
CaseBlock:{CaseClausesoptDefaultClauseCaseClausesopt}
  1. If the first CaseClauses is present, let names be the LexicallyDeclaredNames of the first CaseClauses.
  2. Else let names be a new empty List.
  3. Append to names the elements of the LexicallyDeclaredNames of the DefaultClause.
  4. If the second CaseClauses is not present, return names.
  5. Else return the result of appending to names the elements of the LexicallyDeclaredNames of the second CaseClauses.
CaseClauses:CaseClausesCaseClause
  1. Let names be LexicallyDeclaredNames of CaseClauses.
  2. Append to names the elements of the LexicallyDeclaredNames of CaseClause.
  3. Return names.
CaseClause:caseExpression:StatementListopt
  1. If the StatementList is present, return the LexicallyDeclaredNames of StatementList.
  2. Else return a new empty List.
DefaultClause:default:StatementListopt
  1. If the StatementList is present, return the LexicallyDeclaredNames of StatementList.
  2. Else return a new empty List.

13.12.6Static Semantics: LexicallyScopedDeclarations#

CaseBlock:{}
  1. Return a new empty List.
CaseBlock:{CaseClausesoptDefaultClauseCaseClausesopt}
  1. If the first CaseClauses is present, let declarations be the LexicallyScopedDeclarations of the first CaseClauses.
  2. Else let declarations be a new empty List.
  3. Append to declarations the elements of the LexicallyScopedDeclarations of the DefaultClause.
  4. If the second CaseClauses is not present, return declarations.
  5. Else return the result of appending to declarations the elements of the LexicallyScopedDeclarations of the second CaseClauses.
CaseClauses:CaseClausesCaseClause
  1. Let declarations be LexicallyScopedDeclarations of CaseClauses.
  2. Append to declarations the elements of the LexicallyScopedDeclarations of CaseClause.
  3. Return declarations.
CaseClause:caseExpression:StatementListopt
  1. If the StatementList is present, return the LexicallyScopedDeclarations of StatementList.
  2. Else return a new empty List.
DefaultClause:default:StatementListopt
  1. If the StatementList is present, return the LexicallyScopedDeclarations of StatementList.
  2. Else return a new empty List.

13.12.7Static Semantics: VarDeclaredNames#

SwitchStatement:switch(Expression)CaseBlock
  1. Return the VarDeclaredNames of CaseBlock.
CaseBlock:{}
  1. Return a new empty List.
CaseBlock:{CaseClausesoptDefaultClauseCaseClausesopt}
  1. If the first CaseClauses is present, let names be the VarDeclaredNames of the first CaseClauses.
  2. Else let names be a new empty List.
  3. Append to names the elements of the VarDeclaredNames of the DefaultClause.
  4. If the second CaseClauses is not present, return names.
  5. Else return the result of appending to names the elements of the VarDeclaredNames of the second CaseClauses.
CaseClauses:CaseClausesCaseClause
  1. Let names be VarDeclaredNames of CaseClauses.
  2. Append to names the elements of the VarDeclaredNames of CaseClause.
  3. Return names.
CaseClause:caseExpression:StatementListopt
  1. If the StatementList is present, return the VarDeclaredNames of StatementList.
  2. Else return a new empty List.
DefaultClause:default:StatementListopt
  1. If the StatementList is present, return the VarDeclaredNames of StatementList.
  2. Else return a new empty List.

13.12.8Static Semantics: VarScopedDeclarations#

SwitchStatement:switch(Expression)CaseBlock
  1. Return the VarScopedDeclarations of CaseBlock.
CaseBlock:{}
  1. Return a new empty List.
CaseBlock:{CaseClausesoptDefaultClauseCaseClausesopt}
  1. If the first CaseClauses is present, let declarations be the VarScopedDeclarations of the first CaseClauses.
  2. Else let declarations be a new empty List.
  3. Append to declarations the elements of the VarScopedDeclarations of the DefaultClause.
  4. If the second CaseClauses is not present, return declarations.
  5. Else return the result of appending to declarations the elements of the VarScopedDeclarations of the second CaseClauses.
CaseClauses:CaseClausesCaseClause
  1. Let declarations be VarScopedDeclarations of CaseClauses.
  2. Append to declarations the elements of the VarScopedDeclarations of CaseClause.
  3. Return declarations.
CaseClause:caseExpression:StatementListopt
  1. If the StatementList is present, return the VarScopedDeclarations of StatementList.
  2. Else return a new empty List.
DefaultClause:default:StatementListopt
  1. If the StatementList is present, return the VarScopedDeclarations of StatementList.
  2. Else return a new empty List.

13.12.9Runtime Semantics: CaseBlockEvaluation#

With argument input.

CaseBlock:{}
  1. Return NormalCompletion(undefined).
CaseBlock:{CaseClauses}
  1. Let V be undefined.
  2. Let A be the List of CaseClause items in CaseClauses, in source text order.
  3. Let found be false.
  4. Repeat for each CaseClause C in A,
    1. If found is false, then
      1. Let clauseSelector be the result of CaseSelectorEvaluation of C.
      2. ReturnIfAbrupt(clauseSelector).
      3. Let found be the result of performing Strict Equality Comparison input === clauseSelector.[[Value]].
    2. If found is true, then
      1. Let R be the result of evaluating C.
      2. If R.[[Value]] is not empty, let V be R.[[Value]].
      3. If R is an abrupt completion, return Completion(UpdateEmpty(R, V)).
  5. Return NormalCompletion(V).
CaseBlock:{CaseClausesoptDefaultClauseCaseClausesopt}
  1. Let V be undefined.
  2. Let A be the List of CaseClause items in the first CaseClauses, in source text order. If the first CaseClauses is not present, A is « ».
  3. Let found be false.
  4. Repeat for each CaseClause C in A
    1. If found is false, then
      1. Let clauseSelector be the result of CaseSelectorEvaluation of C.
      2. ReturnIfAbrupt(clauseSelector).
      3. Let found be the result of performing Strict Equality Comparison input === clauseSelector.[[Value]].
    2. If found is true, then
      1. Let R be the result of evaluating C.
      2. If R.[[Value]] is not empty, let V be R.[[Value]].
      3. If R is an abrupt completion, return Completion(UpdateEmpty(R, V)).
  5. Let foundInB be false.
  6. Let B be the List containing the CaseClause items in the second CaseClauses, in source text order. If the second CaseClauses is not present, B is « ».
  7. If found is false, then
    1. Repeat for each CaseClause C in B
      1. If foundInB is false, then
        1. Let clauseSelector be the result of CaseSelectorEvaluation of C.
        2. ReturnIfAbrupt(clauseSelector).
        3. Let foundInB be the result of performing Strict Equality Comparison input === clauseSelector.[[Value]].
      2. If foundInB is true, then
        1. Let R be the result of evaluating CaseClause C.
        2. If R.[[Value]] is not empty, let V be R.[[Value]].
        3. If R is an abrupt completion, return Completion(UpdateEmpty(R, V)).
  8. If foundInB is true, return NormalCompletion(V).
  9. Let R be the result of evaluating DefaultClause.
  10. If R.[[Value]] is not empty, let V be R.[[Value]].
  11. If R is an abrupt completion, return Completion(UpdateEmpty(R, V)).
  12. Repeat for each CaseClause C in B (NOTE this is another complete iteration of the second CaseClauses)
    1. Let R be the result of evaluating CaseClause C.
    2. If R.[[Value]] is not empty, let V be R.[[Value]].
    3. If R is an abrupt completion, return Completion(UpdateEmpty(R, V)).
  13. Return NormalCompletion(V).

13.12.10Runtime Semantics: CaseSelectorEvaluation#

CaseClause:caseExpression:StatementListopt
  1. Let exprRef be the result of evaluating Expression.
  2. Return ? GetValue(exprRef).
Note

CaseSelectorEvaluation does not execute the associated StatementList. It simply evaluates the Expression and returns the value, which the CaseBlock algorithm uses to determine which StatementList to start executing.

13.12.11Runtime Semantics: Evaluation#

SwitchStatement:switch(Expression)CaseBlock
  1. Let exprRef be the result of evaluating Expression.
  2. Let switchValue be ? GetValue(exprRef).
  3. Let oldEnv be the running execution context's LexicalEnvironment.
  4. Let blockEnv be NewDeclarativeEnvironment(oldEnv).
  5. Perform BlockDeclarationInstantiation(CaseBlock, blockEnv).
  6. Set the running execution context's LexicalEnvironment to blockEnv.
  7. Let R be the result of performing CaseBlockEvaluation of CaseBlock with argument switchValue.
  8. Set the running execution context's LexicalEnvironment to oldEnv.
  9. Return R.
Note

No matter how control leaves the SwitchStatement the LexicalEnvironment is always restored to its former state.

CaseClause:caseExpression:
  1. Return NormalCompletion(empty).
CaseClause:caseExpression:StatementList
  1. Return the result of evaluating StatementList.
DefaultClause:default:
  1. Return NormalCompletion(empty).
DefaultClause:default:StatementList
  1. Return the result of evaluating StatementList.

13.13Labelled Statements#

Syntax

LabelledStatement[Yield, Return]:LabelIdentifier[?Yield]:LabelledItem[?Yield, ?Return] LabelledItem[Yield, Return]:Statement[?Yield, ?Return] FunctionDeclaration[?Yield] Note

A Statement may be prefixed by a label. Labelled statements are only used in conjunction with labelled break and continue statements. ECMAScript has no goto statement. A Statement can be part of a LabelledStatement, which itself can be part of a LabelledStatement, and so on. The labels introduced this way are collectively referred to as the “current label set” when describing the semantics of individual statements.

13.13.1Static Semantics: Early Errors#

LabelledItem:FunctionDeclaration
  • It is a Syntax Error if any source text matches this rule.
Note

An alternative definition for this rule is provided in B.3.2.

13.13.2Static Semantics: ContainsDuplicateLabels#

With argument labelSet.

LabelledStatement:LabelIdentifier:LabelledItem
  1. Let label be the StringValue of LabelIdentifier.
  2. If label is an element of labelSet, return true.
  3. Let newLabelSet be a copy of labelSet with label appended.
  4. Return ContainsDuplicateLabels of LabelledItem with argument newLabelSet.
LabelledItem:FunctionDeclaration
  1. Return false.

13.13.3Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

LabelledStatement:LabelIdentifier:LabelledItem
  1. Let label be the StringValue of LabelIdentifier.
  2. Let newLabelSet be a copy of labelSet with label appended.
  3. Return ContainsUndefinedBreakTarget of LabelledItem with argument newLabelSet.
LabelledItem:FunctionDeclaration
  1. Return false.

13.13.4Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

LabelledStatement:LabelIdentifier:LabelledItem
  1. Let label be the StringValue of LabelIdentifier.
  2. Let newLabelSet be a copy of labelSet with label appended.
  3. Return ContainsUndefinedContinueTarget of LabelledItem with arguments iterationSet and newLabelSet.
LabelledItem:FunctionDeclaration
  1. Return false.

13.13.5Static Semantics: IsLabelledFunction ( stmt )#

The abstract operation IsLabelledFunction with argument stmt performs the following steps:

  1. If stmt is not a LabelledStatement, return false.
  2. Let item be the LabelledItem component of stmt.
  3. If item is LabelledItem:FunctionDeclaration , return true.
  4. Let subStmt be the Statement component of item.
  5. Return IsLabelledFunction(subStmt).

13.13.6Static Semantics: LexicallyDeclaredNames#

LabelledStatement:LabelIdentifier:LabelledItem
  1. Return the LexicallyDeclaredNames of LabelledItem.
LabelledItem:Statement
  1. Return a new empty List.
LabelledItem:FunctionDeclaration
  1. Return BoundNames of FunctionDeclaration.

13.13.7Static Semantics: LexicallyScopedDeclarations#

LabelledStatement:LabelIdentifier:LabelledItem
  1. Return the LexicallyScopedDeclarations of LabelledItem.
LabelledItem:Statement
  1. Return a new empty List.
LabelledItem:FunctionDeclaration
  1. Return a new List containing FunctionDeclaration.

13.13.8Static Semantics: TopLevelLexicallyDeclaredNames#

LabelledStatement:LabelIdentifier:LabelledItem
  1. Return a new empty List.

13.13.9Static Semantics: TopLevelLexicallyScopedDeclarations#

LabelledStatement:LabelIdentifier:LabelledItem
  1. Return a new empty List.

13.13.10Static Semantics: TopLevelVarDeclaredNames#

LabelledStatement:LabelIdentifier:LabelledItem
  1. Return the TopLevelVarDeclaredNames of LabelledItem.
LabelledItem:Statement
  1. If Statement is Statement:LabelledStatement , return TopLevelVarDeclaredNames of Statement.
  2. Return VarDeclaredNames of Statement.
LabelledItem:FunctionDeclaration
  1. Return BoundNames of FunctionDeclaration.

13.13.11Static Semantics: TopLevelVarScopedDeclarations#

LabelledStatement:LabelIdentifier:LabelledItem
  1. Return the TopLevelVarScopedDeclarations of LabelledItem.
LabelledItem:Statement
  1. If Statement is Statement:LabelledStatement , return TopLevelVarScopedDeclarations of Statement.
  2. Return VarScopedDeclarations of Statement.
LabelledItem:FunctionDeclaration
  1. Return a new List containing FunctionDeclaration.

13.13.12Static Semantics: VarDeclaredNames#

LabelledStatement:LabelIdentifier:LabelledItem
  1. Return the VarDeclaredNames of LabelledItem.
LabelledItem:FunctionDeclaration
  1. Return a new empty List.

13.13.13Static Semantics: VarScopedDeclarations#

LabelledStatement:LabelIdentifier:LabelledItem
  1. Return the VarScopedDeclarations of LabelledItem.
LabelledItem:FunctionDeclaration
  1. Return a new empty List.

13.13.14Runtime Semantics: LabelledEvaluation#

With argument labelSet.

LabelledStatement:LabelIdentifier:LabelledItem
  1. Let label be the StringValue of LabelIdentifier.
  2. Append label as an element of labelSet.
  3. Let stmtResult be LabelledEvaluation of LabelledItem with argument labelSet.
  4. If stmtResult.[[Type]] is break and SameValue(stmtResult.[[Target]], label) is true, then
    1. Let stmtResult be NormalCompletion(stmtResult.[[Value]]).
  5. Return Completion(stmtResult).
LabelledItem:Statement
  1. If Statement is either a LabelledStatement or a BreakableStatement, then
    1. Return LabelledEvaluation of Statement with argument labelSet.
  2. Else,
    1. Return the result of evaluating Statement.
LabelledItem:FunctionDeclaration
  1. Return the result of evaluating FunctionDeclaration.

13.13.15Runtime Semantics: Evaluation#

LabelledStatement:LabelIdentifier:LabelledItem
  1. Let newLabelSet be a new empty List.
  2. Return LabelledEvaluation of this LabelledStatement with argument newLabelSet.

13.14The throw Statement#

Syntax

ThrowStatement[Yield]:throw[no LineTerminator here]Expression[In, ?Yield];

13.14.1Runtime Semantics: Evaluation#

ThrowStatement:throwExpression;
  1. Let exprRef be the result of evaluating Expression.
  2. Let exprValue be ? GetValue(exprRef).
  3. Return Completion{[[Type]]: throw, [[Value]]: exprValue, [[Target]]: empty}.

13.15The try Statement#

Syntax

TryStatement[Yield, Return]:tryBlock[?Yield, ?Return]Catch[?Yield, ?Return] tryBlock[?Yield, ?Return]Finally[?Yield, ?Return] tryBlock[?Yield, ?Return]Catch[?Yield, ?Return]Finally[?Yield, ?Return] Catch[Yield, Return]:catch(CatchParameter[?Yield])Block[?Yield, ?Return] Finally[Yield, Return]:finallyBlock[?Yield, ?Return] CatchParameter[Yield]:BindingIdentifier[?Yield] BindingPattern[?Yield] Note

The try statement encloses a block of code in which an exceptional condition can occur, such as a runtime error or a throw statement. The catch clause provides the exception-handling code. When a catch clause catches an exception, its CatchParameter is bound to that exception.

13.15.1Static Semantics: Early Errors#

Catch:catch(CatchParameter)Block
  • It is a Syntax Error if BoundNames of CatchParameter contains any duplicate elements.
  • It is a Syntax Error if any element of the BoundNames of CatchParameter also occurs in the LexicallyDeclaredNames of Block.
  • It is a Syntax Error if any element of the BoundNames of CatchParameter also occurs in the VarDeclaredNames of Block.
Note

An alternative static semantics for this production is given in B.3.5.

13.15.2Static Semantics: ContainsDuplicateLabels#

With argument labelSet.

TryStatement:tryBlockCatch
  1. Let hasDuplicates be ContainsDuplicateLabels of Block with argument labelSet.
  2. If hasDuplicates is true, return true.
  3. Return ContainsDuplicateLabels of Catch with argument labelSet.
TryStatement:tryBlockFinally
  1. Let hasDuplicates be ContainsDuplicateLabels of Block with argument labelSet.
  2. If hasDuplicates is true, return true.
  3. Return ContainsDuplicateLabels of Finally with argument labelSet.
TryStatement:tryBlockCatchFinally
  1. Let hasDuplicates be ContainsDuplicateLabels of Block with argument labelSet.
  2. If hasDuplicates is true, return true.
  3. Let hasDuplicates be ContainsDuplicateLabels of Catch with argument labelSet.
  4. If hasDuplicates is true, return true.
  5. Return ContainsDuplicateLabels of Finally with argument labelSet.
Catch:catch(CatchParameter)Block
  1. Return ContainsDuplicateLabels of Block with argument labelSet.

13.15.3Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

TryStatement:tryBlockCatch
  1. Let hasUndefinedLabels be ContainsUndefinedBreakTarget of Block with argument labelSet.
  2. If hasUndefinedLabels is true, return true.
  3. Return ContainsUndefinedBreakTarget of Catch with argument labelSet.
TryStatement:tryBlockFinally
  1. Let hasUndefinedLabels be ContainsUndefinedBreakTarget of Block with argument labelSet.
  2. If hasUndefinedLabels is true, return true.
  3. Return ContainsUndefinedBreakTarget of Finally with argument labelSet.
TryStatement:tryBlockCatchFinally
  1. Let hasUndefinedLabels be ContainsUndefinedBreakTarget of Block with argument labelSet.
  2. If hasUndefinedLabels is true, return true.
  3. Let hasUndefinedLabels be ContainsUndefinedBreakTarget of Catch with argument labelSet.
  4. If hasUndefinedLabels is true, return true.
  5. Return ContainsUndefinedBreakTarget of Finally with argument labelSet.
Catch:catch(CatchParameter)Block
  1. Return ContainsUndefinedBreakTarget of Block with argument labelSet.

13.15.4Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

TryStatement:tryBlockCatch
  1. Let hasUndefinedLabels be ContainsUndefinedContinueTarget of Block with arguments iterationSet and « ».
  2. If hasUndefinedLabels is true, return true.
  3. Return ContainsUndefinedContinueTarget of Catch with arguments iterationSet and « ».
TryStatement:tryBlockFinally
  1. Let hasUndefinedLabels be ContainsUndefinedContinueTarget of Block with arguments iterationSet and « ».
  2. If hasUndefinedLabels is true, return true.
  3. Return ContainsUndefinedContinueTarget of Finally with arguments iterationSet and « ».
TryStatement:tryBlockCatchFinally
  1. Let hasUndefinedLabels be ContainsUndefinedContinueTarget of Block with arguments iterationSet and « ».
  2. If hasUndefinedLabels is true, return true.
  3. Let hasUndefinedLabels be ContainsUndefinedContinueTarget of Catch with arguments iterationSet and « ».
  4. If hasUndefinedLabels is true, return true.
  5. Return ContainsUndefinedContinueTarget of Finally with arguments iterationSet and « ».
Catch:catch(CatchParameter)Block
  1. Return ContainsUndefinedContinueTarget of Block with arguments iterationSet and « ».

13.15.5Static Semantics: VarDeclaredNames#

TryStatement:tryBlockCatch
  1. Let names be VarDeclaredNames of Block.
  2. Append to names the elements of the VarDeclaredNames of Catch.
  3. Return names.
TryStatement:tryBlockFinally
  1. Let names be VarDeclaredNames of Block.
  2. Append to names the elements of the VarDeclaredNames of Finally.
  3. Return names.
TryStatement:tryBlockCatchFinally
  1. Let names be VarDeclaredNames of Block.
  2. Append to names the elements of the VarDeclaredNames of Catch.
  3. Append to names the elements of the VarDeclaredNames of Finally.
  4. Return names.
Catch:catch(CatchParameter)Block
  1. Return the VarDeclaredNames of Block.

13.15.6Static Semantics: VarScopedDeclarations#

TryStatement:tryBlockCatch
  1. Let declarations be VarScopedDeclarations of Block.
  2. Append to declarations the elements of the VarScopedDeclarations of Catch.
  3. Return declarations.
TryStatement:tryBlockFinally
  1. Let declarations be VarScopedDeclarations of Block.
  2. Append to declarations the elements of the VarScopedDeclarations of Finally.
  3. Return declarations.
TryStatement:tryBlockCatchFinally
  1. Let declarations be VarScopedDeclarations of Block.
  2. Append to declarations the elements of the VarScopedDeclarations of Catch.
  3. Append to declarations the elements of the VarScopedDeclarations of Finally.
  4. Return declarations.
Catch:catch(CatchParameter)Block
  1. Return the VarScopedDeclarations of Block.

13.15.7Runtime Semantics: CatchClauseEvaluation#

with parameter thrownValue

Catch:catch(CatchParameter)Block
  1. Let oldEnv be the running execution context's LexicalEnvironment.
  2. Let catchEnv be NewDeclarativeEnvironment(oldEnv).
  3. Let catchEnvRec be catchEnv's EnvironmentRecord.
  4. For each element argName of the BoundNames of CatchParameter, do
    1. Perform ! catchEnvRec.CreateMutableBinding(argName, false).
  5. Set the running execution context's LexicalEnvironment to catchEnv.
  6. Let status be the result of performing BindingInitialization for CatchParameter passing thrownValue and catchEnv as arguments.
  7. If status is an abrupt completion, then
    1. Set the running execution context's LexicalEnvironment to oldEnv.
    2. Return Completion(status).
  8. Let B be the result of evaluating Block.
  9. Set the running execution context's LexicalEnvironment to oldEnv.
  10. Return Completion(B).
Note

No matter how control leaves the Block the LexicalEnvironment is always restored to its former state.

13.15.8Runtime Semantics: Evaluation#

TryStatement:tryBlockCatch
  1. Let B be the result of evaluating Block.
  2. If B.[[Type]] is throw, let C be CatchClauseEvaluation of Catch with parameter B.[[Value]].
  3. Else, let C be B.
  4. Return Completion(UpdateEmpty(C, undefined)).
TryStatement:tryBlockFinally
  1. Let B be the result of evaluating Block.
  2. Let F be the result of evaluating Finally.
  3. If F.[[Type]] is normal, let F be B.
  4. Return Completion(UpdateEmpty(F, undefined)).
TryStatement:tryBlockCatchFinally
  1. Let B be the result of evaluating Block.
  2. If B.[[Type]] is throw, let C be CatchClauseEvaluation of Catch with parameter B.[[Value]].
  3. Else, let C be B.
  4. Let F be the result of evaluating Finally.
  5. If F.[[Type]] is normal, let F be C.
  6. Return Completion(UpdateEmpty(F, undefined)).

13.16The debugger Statement#

Syntax

DebuggerStatement:debugger;

13.16.1Runtime Semantics: Evaluation#

Note

执行DebuggerStatement表达式,可能允许实现在调试器下运行时导致断点。 如果调试器不存在或不活跃,则此语句无法观察到效果。

DebuggerStatement:debugger;
  1. If an implementation defined debugging facility is available and enabled, then
    1. Perform an implementation defined debugging action.
    2. Let result be an implementation defined Completion value.
  2. Else,
    1. Let result be NormalCompletion(empty).
  3. Return result.

14ECMAScript Language: Functions and Classes(ECMAScript语言:函数和类)#

Note

各种ECMAScript语言元素创建ECMAScript函数对象(9.2)。 这种方法的执行从执行[[Call]]内部方法(9.2.1)开始。

14.1Function Definitions(Function定义)#

Syntax(语法)

FunctionDeclaration[Yield, Default]:functionBindingIdentifier[?Yield](FormalParameters){FunctionBody} [+Default]function(FormalParameters){FunctionBody} FunctionExpression:functionBindingIdentifieropt(FormalParameters){FunctionBody} StrictFormalParameters[Yield]:FormalParameters[?Yield] FormalParameters[Yield]:[empty] FormalParameterList[?Yield] FormalParameterList[Yield]:FunctionRestParameter[?Yield] FormalsList[?Yield] FormalsList[?Yield],FunctionRestParameter[?Yield] FormalsList[Yield]:FormalParameter[?Yield] FormalsList[?Yield],FormalParameter[?Yield] FunctionRestParameter[Yield]:BindingRestElement[?Yield] FormalParameter[Yield]:BindingElement[?Yield] FunctionBody[Yield]:FunctionStatementList[?Yield] FunctionStatementList[Yield]:StatementList[?Yield, Return]opt

14.1.1Directive Prologues and the Use Strict Directive(指令序言和使用严格指令)#

A Directive Prologue is the longest sequence of ExpressionStatement productions occurring as the initial StatementListItem or ModuleItem productions of a FunctionBody, a ScriptBody, or a ModuleBody and where each ExpressionStatement in the sequence consists entirely of a StringLiteral token followed by a semicolon. The semicolon may appear explicitly or may be inserted by automatic semicolon insertion. A Directive Prologue may be an empty sequence.(指令序言是作为FunctionBody,ScriptBody或ModuleBody的初始声明列表项或模块项产生而出现的最长的表达式语句产生序列,并且序列中的每个表达式语句完全由字符串字面值标记后跟分号组成。 分号可能会显式出现,或者可能通过自动分号插入。 指令序言可能是一个空的序列。)

使用严格指令是指令序言中的表达式语句,它的字符串字面量(StringLiteral)是严格的代码单元序列“use strict”或“use strict”。 使用严格指令不得包含转义序列(EscapeSequence)或行连续符(LineContinuation)。

指令序言可能包含多个使用严格指令。 但是,如果发生这种情况,具体实施(比如浏览器)可能会发出警告。

Note

指令序言的表达式语句生成在包含表达式的执行过程中通常被执行。 实现可以为ExpressionStatement生成定义实现特定的含义,这不是使用严格指令,而是发生在指令序言中。 如果存在适当的通知机制,则实现应该在指令序言中遇到不是使用严格指令的表达式语句并且没有实现定义的含义时发出警告。

14.1.2Static Semantics: Early Errors#

FunctionDeclaration:functionBindingIdentifier(FormalParameters){FunctionBody} FunctionDeclaration:function(FormalParameters){FunctionBody} FunctionExpression:functionBindingIdentifieropt(FormalParameters){FunctionBody} Note 1

The LexicallyDeclaredNames of a FunctionBody does not include identifiers bound using var or function declarations.

StrictFormalParameters:FormalParameters
  • It is a Syntax Error if BoundNames of FormalParameters contains any duplicate elements.
FormalParameters:FormalParameterList Note 2

Multiple occurrences of the same BindingIdentifier in a FormalParameterList is only allowed for functions and generator functions which have simple parameter lists and which are not defined in strict mode code.

FunctionBody:FunctionStatementList

14.1.3Static Semantics: BoundNames#

FunctionDeclaration:functionBindingIdentifier(FormalParameters){FunctionBody}
  1. Return the BoundNames of BindingIdentifier.
FunctionDeclaration:function(FormalParameters){FunctionBody}
  1. Return « "*default*" ».
Note

"*default*" is used within this specification as a synthetic name for hoistable anonymous functions that are defined using export declarations.

FormalParameters:[empty]
  1. Return a new empty List.
FormalParameterList:FormalsList,FunctionRestParameter
  1. Let names be BoundNames of FormalsList.
  2. Append to names the BoundNames of FunctionRestParameter.
  3. Return names.
FormalsList:FormalsList,FormalParameter
  1. Let names be BoundNames of FormalsList.
  2. Append to names the elements of BoundNames of FormalParameter.
  3. Return names.

14.1.4Static Semantics: Contains#

With parameter symbol.

FunctionDeclaration:functionBindingIdentifier(FormalParameters){FunctionBody} FunctionDeclaration:function(FormalParameters){FunctionBody} FunctionExpression:functionBindingIdentifieropt(FormalParameters){FunctionBody}
  1. Return false.
Note

Static semantic rules that depend upon substructure generally do not look into function definitions.

14.1.5Static Semantics: ContainsExpression#

FormalParameters:[empty]
  1. Return false.
FormalParameterList:FunctionRestParameter
  1. Return ContainsExpression of FunctionRestParameter.
FormalParameterList:FormalsList,FunctionRestParameter
  1. If ContainsExpression of FormalsList is true, return true.
  2. Return ContainsExpression of FunctionRestParameter.
FormalsList:FormalsList,FormalParameter
  1. If ContainsExpression of FormalsList is true, return true.
  2. Return ContainsExpression of FormalParameter.

14.1.6Static Semantics: ContainsUseStrict#

FunctionBody:FunctionStatementList
  1. If the Directive Prologue of FunctionStatementList contains a Use Strict Directive, return true; otherwise, return false.

14.1.7Static Semantics: ExpectedArgumentCount#

FormalParameters:[empty]
  1. Return 0.
FormalParameterList:FunctionRestParameter
  1. Return 0.
FormalParameterList:FormalsList,FunctionRestParameter
  1. Return the ExpectedArgumentCount of FormalsList.
Note

The ExpectedArgumentCount of a FormalParameterList is the number of FormalParameters to the left of either the rest parameter or the first FormalParameter with an Initializer. A FormalParameter without an initializer is allowed after the first parameter with an initializer but such parameters are considered to be optional with undefined as their default value.

FormalsList:FormalParameter
  1. If HasInitializer of FormalParameter is true, return 0.
  2. Return 1.
FormalsList:FormalsList,FormalParameter
  1. Let count be the ExpectedArgumentCount of FormalsList.
  2. If HasInitializer of FormalsList is true or HasInitializer of FormalParameter is true, return count.
  3. Return count+1.

14.1.8Static Semantics: HasInitializer#

FormalsList:FormalsList,FormalParameter
  1. If HasInitializer of FormalsList is true, return true.
  2. Return HasInitializer of FormalParameter.

14.1.9Static Semantics: HasName#

FunctionExpression:function(FormalParameters){FunctionBody}
  1. Return false.
FunctionExpression:functionBindingIdentifier(FormalParameters){FunctionBody}
  1. Return true.

14.1.10Static Semantics: IsAnonymousFunctionDefinition ( production )(匿名函数定义)#

The abstract operation IsAnonymousFunctionDefinition determines if its argument is a function definition that does not bind a name. The argument production is the result of parsing an AssignmentExpression or Initializer. The following steps are taken:

  1. If IsFunctionDefinition of production is false, return false.
  2. Let hasName be the result of HasName of production.
  3. If hasName is true, return false.
  4. Return true.

14.1.11Static Semantics: IsConstantDeclaration(是否常量声明)#

FunctionDeclaration:functionBindingIdentifier(FormalParameters){FunctionBody} FunctionDeclaration:function(FormalParameters){FunctionBody}
  1. Return false.

14.1.12Static Semantics: IsFunctionDefinition#

FunctionExpression:functionBindingIdentifieropt(FormalParameters){FunctionBody}
  1. Return true.

14.1.13Static Semantics: IsSimpleParameterList(是简单的参数列表)#

FormalParameters:[empty]
  1. Return true.
FormalParameterList:FunctionRestParameter
  1. Return false.
FormalParameterList:FormalsList,FunctionRestParameter
  1. Return false.
FormalsList:FormalsList,FormalParameter
  1. If IsSimpleParameterList of FormalsList is false, return false.
  2. Return IsSimpleParameterList of FormalParameter.
FormalParameter:BindingElement
  1. Return IsSimpleParameterList of BindingElement.

不包含rest parameter定义的就是简单参数列表,就是参数列表不包含...args这类定义

14.1.14Static Semantics: LexicallyDeclaredNames(已声明的词法名称)#

FunctionStatementList:[empty]
  1. Return a new empty List.
FunctionStatementList:StatementList
  1. Return TopLevelLexicallyDeclaredNames of StatementList.

14.1.15Static Semantics: LexicallyScopedDeclarations(词法作用域声明)#

FunctionStatementList:[empty]
  1. Return a new empty List.
FunctionStatementList:StatementList
  1. Return the TopLevelLexicallyScopedDeclarations of StatementList.

14.1.16Static Semantics: VarDeclaredNames(Var声明的变量名)#

FunctionStatementList:[empty]
  1. Return a new empty List.
FunctionStatementList:StatementList
  1. Return TopLevelVarDeclaredNames of StatementList.

14.1.17Static Semantics: VarScopedDeclarations(Var作用域声明)#

FunctionStatementList:[empty]
  1. Return a new empty List.
FunctionStatementList:StatementList
  1. Return the TopLevelVarScopedDeclarations of StatementList.

14.1.18Runtime Semantics: EvaluateBody#

With parameter functionObject.

FunctionBody:FunctionStatementList
  1. Return the result of evaluating FunctionStatementList.

14.1.19Runtime Semantics: IteratorBindingInitialization(迭代器绑定初始化)#

With parameters iteratorRecord and environment.

Note 1

当environment传入undefined时,表示应该使用PutValue操作来分配初始化值。 非严格函数的形式参数列表就是这种情况。 在这种情况下,为了处理具有相同名称的多个参数的可能性,形式参数绑定被初始化。

FormalParameters(形式参数):[empty]
  1. Return NormalCompletion(empty).
FormalParameterList:FormalsList,FunctionRestParameter
  1. Let restIndex be the result of performing IteratorBindingInitialization for FormalsList using iteratorRecord and environment as the arguments.
  2. ReturnIfAbrupt(restIndex).
  3. Return the result of performing IteratorBindingInitialization for FunctionRestParameter using iteratorRecord and environment as the arguments.
FormalsList:FormalsList,FormalParameter
  1. Let status be the result of performing IteratorBindingInitialization for FormalsList using iteratorRecord and environment as the arguments.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing IteratorBindingInitialization for FormalParameter using iteratorRecord and environment as the arguments.
FormalParameter:BindingElement
  1. If ContainsExpression of BindingElement is false, return the result of performing IteratorBindingInitialization for BindingElement using iteratorRecord and environment as the arguments.
  2. Let currentContext be the running execution context.
  3. Let originalEnv be the VariableEnvironment of currentContext.
  4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext are the same.
  5. Assert: environment and originalEnv are the same.
  6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv).
  7. Set the VariableEnvironment of currentContext to paramVarEnv.
  8. Set the LexicalEnvironment of currentContext to paramVarEnv.
  9. Let result be the result of performing IteratorBindingInitialization for BindingElement using iteratorRecord and environment as the arguments.
  10. Set the VariableEnvironment of currentContext to originalEnv.
  11. Set the LexicalEnvironment of currentContext to originalEnv.
  12. Return result.
Note 2

The new Environment Record created in step 6 is only used if the BindingElement contains a direct eval.

FunctionRestParameter:BindingRestElement
  1. If ContainsExpression of BindingRestElement is false, return the result of performing IteratorBindingInitialization for BindingRestElement using iteratorRecord and environment as the arguments.
  2. Let currentContext be the running execution context.
  3. Let originalEnv be the VariableEnvironment of currentContext.
  4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext are the same.
  5. Assert: environment and originalEnv are the same.
  6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv).
  7. Set the VariableEnvironment of currentContext to paramVarEnv.
  8. Set the LexicalEnvironment of currentContext to paramVarEnv.
  9. Let result be the result of performing IteratorBindingInitialization for BindingRestElement using iteratorRecord and environment as the arguments.
  10. Set the VariableEnvironment of currentContext to originalEnv.
  11. Set the LexicalEnvironment of currentContext to originalEnv.
  12. Return result.
Note 3

The new Environment Record created in step 6 is only used if the BindingRestElement contains a direct eval.

14.1.20Runtime Semantics: InstantiateFunctionObject#

With parameter scope.

FunctionDeclaration:functionBindingIdentifier(FormalParameters){FunctionBody}
  1. If the function code for FunctionDeclaration is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let name be StringValue of BindingIdentifier.
  3. Let F be FunctionCreate(Normal, FormalParameters, FunctionBody, scope, strict).
  4. Perform MakeConstructor(F).
  5. Perform SetFunctionName(F, name).
  6. Return F.
FunctionDeclaration:function(FormalParameters){FunctionBody}
  1. If the function code for FunctionDeclaration is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let F be FunctionCreate(Normal, FormalParameters, FunctionBody, scope, strict).
  3. Perform MakeConstructor(F).
  4. Perform SetFunctionName(F, "default").
  5. Return F.
Note

An anonymous FunctionDeclaration can only occur as part of an export default declaration.

14.1.21Runtime Semantics: Evaluation#

FunctionDeclaration:functionBindingIdentifier(FormalParameters){FunctionBody}
  1. Return NormalCompletion(empty).
Note 1

An alternative semantics is provided in B.3.3.

FunctionDeclaration:function(FormalParameters){FunctionBody}
  1. Return NormalCompletion(empty).
FunctionExpression:function(FormalParameters){FunctionBody}
  1. If the function code for FunctionExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let closure be FunctionCreate(Normal, FormalParameters, FunctionBody, scope, strict).
  4. Perform MakeConstructor(closure).
  5. Return closure.
FunctionExpression:functionBindingIdentifier(FormalParameters){FunctionBody}
  1. If the function code for FunctionExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the running execution context's LexicalEnvironment.
  3. Let funcEnv be NewDeclarativeEnvironment(scope).
  4. Let envRec be funcEnv's EnvironmentRecord.
  5. Let name be StringValue of BindingIdentifier.
  6. Perform envRec.CreateImmutableBinding(name, false).
  7. Let closure be FunctionCreate(Normal, FormalParameters, FunctionBody, funcEnv, strict).
  8. Perform MakeConstructor(closure).
  9. Perform SetFunctionName(closure, name).
  10. Perform envRec.InitializeBinding(name, closure).
  11. Return closure.
Note 2

The BindingIdentifier in a FunctionExpression can be referenced from inside the FunctionExpression's FunctionBody to allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the BindingIdentifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression.

FunctionExpression中的BindingIdentifier可以从FunctionExpression的FunctionBody中被引用,以允许函数递归地调用它自己。 但是,与FunctionDeclaration不同,FunctionExpression中的BindingIdentifier不能被引用,也不会影响包含FunctionExpression的作用域。

Note 3

A prototype property is automatically created for every function defined using a FunctionDeclaration or FunctionExpression, to allow for the possibility that the function will be used as a constructor.

对于使用FunctionDeclaration或FunctionExpression定义的每个函数,会自动创建一个prototype属性,以允许将该函数用作构造函数。

FunctionStatementList:[empty]
  1. Return NormalCompletion(undefined).

14.2Arrow Function Definitions(箭头函数定义)#

Syntax

ArrowFunction[In, Yield]:ArrowParameters[?Yield][no LineTerminator here]=>ConciseBody[?In] ArrowParameters[Yield]:BindingIdentifier[?Yield] CoverParenthesizedExpressionAndArrowParameterList[?Yield] ConciseBody[In]:[lookahead ≠ {]AssignmentExpression[?In] {FunctionBody}

Supplemental Syntax

When the production
ArrowParameters[Yield]:CoverParenthesizedExpressionAndArrowParameterList[?Yield]
is recognized the following grammar is used to refine the interpretation of CoverParenthesizedExpressionAndArrowParameterList:

ArrowFormalParameters[Yield]:(StrictFormalParameters[?Yield])

14.2.1Static Semantics: Early Errors#

ArrowFunction:ArrowParameters=>ConciseBody ArrowParameters[Yield]:CoverParenthesizedExpressionAndArrowParameterList[?Yield]

14.2.2Static Semantics: BoundNames#

ArrowParameters:CoverParenthesizedExpressionAndArrowParameterList
  1. Let formals be CoveredFormalsList of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return the BoundNames of formals.

14.2.3Static Semantics: Contains#

With parameter symbol.

ArrowFunction:ArrowParameters=>ConciseBody
  1. If symbol is not one of NewTarget, SuperProperty, SuperCall, super or this, return false.
  2. If ArrowParameters Contains symbol is true, return true.
  3. Return ConciseBody Contains symbol.
Note

Normally, Contains does not look inside most function forms. However, Contains is used to detect new.target, this, and super usage within an ArrowFunction.

ArrowParameters:CoverParenthesizedExpressionAndArrowParameterList
  1. Let formals be CoveredFormalsList of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return formals Contains symbol.

14.2.4Static Semantics: ContainsExpression#

ArrowParameters:BindingIdentifier
  1. Return false.

14.2.5Static Semantics: ContainsUseStrict#

ConciseBody:AssignmentExpression
  1. Return false.

14.2.6Static Semantics: ExpectedArgumentCount#

ArrowParameters:BindingIdentifier
  1. Return 1.

14.2.7Static Semantics: HasName#

ArrowFunction:ArrowParameters=>ConciseBody
  1. Return false.

14.2.8Static Semantics: IsSimpleParameterList#

ArrowParameters:BindingIdentifier
  1. Return true.
ArrowParameters:CoverParenthesizedExpressionAndArrowParameterList
  1. Let formals be CoveredFormalsList of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return IsSimpleParameterList of formals.

14.2.9Static Semantics: CoveredFormalsList#

ArrowParameters:BindingIdentifier
  1. Return this ArrowParameters.
CoverParenthesizedExpressionAndArrowParameterList[Yield]:(Expression) () (...BindingIdentifier) (...BindingPattern) (Expression,...BindingIdentifier) (Expression,...BindingPattern)
  1. If the [Yield] grammar parameter is present for CoverParenthesizedExpressionAndArrowParameterList[Yield], return the result of parsing the lexical token stream matched by CoverParenthesizedExpressionAndArrowParameterList[Yield] using ArrowFormalParameters[Yield] as the goal symbol.
  2. If the [Yield] grammar parameter is not present for CoverParenthesizedExpressionAndArrowParameterList[Yield], return the result of parsing the lexical token stream matched by CoverParenthesizedExpressionAndArrowParameterList using ArrowFormalParameters as the goal symbol.

14.2.10Static Semantics: LexicallyDeclaredNames#

ConciseBody:AssignmentExpression
  1. Return a new empty List.

14.2.11Static Semantics: LexicallyScopedDeclarations#

ConciseBody:AssignmentExpression
  1. Return a new empty List.

14.2.12Static Semantics: VarDeclaredNames#

ConciseBody:AssignmentExpression
  1. Return a new empty List.

14.2.13Static Semantics: VarScopedDeclarations#

ConciseBody:AssignmentExpression
  1. Return a new empty List.

14.2.14Runtime Semantics: IteratorBindingInitialization#

With parameters iteratorRecord and environment.

Note

When undefined is passed for environment it indicates that a PutValue operation should be used to assign the initialization value. This is the case for formal parameter lists of non-strict functions. In that case the formal parameter bindings are preinitialized in order to deal with the possibility of multiple parameters with the same name.

ArrowParameters:BindingIdentifier
  1. Assert: iteratorRecord.[[Done]] is false.
  2. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
  3. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
  4. ReturnIfAbrupt(next).
  5. If next is false, set iteratorRecord.[[Done]] to true.
  6. Else,
    1. Let v be IteratorValue(next).
    2. If v is an abrupt completion, set iteratorRecord.[[Done]] to true.
    3. ReturnIfAbrupt(v).
  7. If iteratorRecord.[[Done]] is true, let v be undefined.
  8. Return the result of performing BindingInitialization for BindingIdentifier using v and environment as the arguments.

14.2.15Runtime Semantics: EvaluateBody#

With parameter functionObject.

ConciseBody:AssignmentExpression
  1. Let exprRef be the result of evaluating AssignmentExpression.
  2. Let exprValue be ? GetValue(exprRef).
  3. Return Completion{[[Type]]: return, [[Value]]: exprValue, [[Target]]: empty}.

14.2.16Runtime Semantics: Evaluation#

ArrowFunction:ArrowParameters=>ConciseBody
  1. If the function code for this ArrowFunction is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let parameters be CoveredFormalsList of ArrowParameters.
  4. Let closure be FunctionCreate(Arrow, parameters, ConciseBody, scope, strict).
  5. Return closure.
Note

An ArrowFunction does not define local bindings for arguments, super, this, or new.target. Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment. Typically this will be the Function Environment of an immediately enclosing function. Even though an ArrowFunction may contain references to super, the function object created in step 4 is not made into a method by performing MakeMethod. An ArrowFunction that references super is always contained within a non-ArrowFunction and the necessary state to implement super is accessible via the scope that is captured by the function object of the ArrowFunction.

14.3Method Definitions#

Syntax

MethodDefinition[Yield]:PropertyName[?Yield](StrictFormalParameters){FunctionBody} GeneratorMethod[?Yield] getPropertyName[?Yield](){FunctionBody} setPropertyName[?Yield](PropertySetParameterList){FunctionBody} PropertySetParameterList:FormalParameter

14.3.1Static Semantics: Early Errors#

MethodDefinition:PropertyName(StrictFormalParameters){FunctionBody}
  • 如果FunctionBody的ContainsUseStrict为true,并且StrictFormalParameters的IsSimpleParameterList为false,则为语法错误。

    注解: function a(...list) { 'use strict' console.log(list); } 在chrome中会报语法错误:Uncaught SyntaxError: Illegal 'use strict' directive in function with non-simple parameter list

  • 如果StrictFormalParameters的BoundNames的任何元素也出现在FunctionBody的LexicallyDeclaredNames中,那么这是一个语法错误。

    注解: 暂时不知道含义

MethodDefinition:setPropertyName(PropertySetParameterList){FunctionBody}

14.3.2Static Semantics: ComputedPropertyContains#

With parameter symbol.

MethodDefinition:PropertyName(StrictFormalParameters){FunctionBody} getPropertyName(){FunctionBody} setPropertyName(PropertySetParameterList){FunctionBody}
  1. Return the result of ComputedPropertyContains for PropertyName with argument symbol.

14.3.3Static Semantics: ExpectedArgumentCount#

PropertySetParameterList:FormalParameter
  1. If HasInitializer of FormalParameter is true, return 0.
  2. Return 1.

14.3.4Static Semantics: HasComputedPropertyKey#

MethodDefinition:PropertyName(StrictFormalParameters){FunctionBody} getPropertyName(){FunctionBody} setPropertyName(PropertySetParameterList){FunctionBody}
  1. Return IsComputedPropertyKey of PropertyName.

14.3.5Static Semantics: HasDirectSuper#

MethodDefinition:PropertyName(StrictFormalParameters){FunctionBody}
  1. If StrictFormalParameters Contains SuperCall is true, return true.
  2. Return FunctionBody Contains SuperCall.
MethodDefinition:getPropertyName(){FunctionBody}
  1. Return FunctionBody Contains SuperCall.
MethodDefinition:setPropertyName(PropertySetParameterList){FunctionBody}
  1. If PropertySetParameterList Contains SuperCall is true, return true.
  2. Return FunctionBody Contains SuperCall.

14.3.6Static Semantics: PropName#

MethodDefinition:PropertyName(StrictFormalParameters){FunctionBody} getPropertyName(){FunctionBody} setPropertyName(PropertySetParameterList){FunctionBody}
  1. Return PropName of PropertyName.

14.3.7Static Semantics: SpecialMethod#

MethodDefinition:PropertyName(StrictFormalParameters){FunctionBody}
  1. Return false.
MethodDefinition:GeneratorMethod getPropertyName(){FunctionBody} setPropertyName(PropertySetParameterList){FunctionBody}
  1. Return true.

14.3.8Runtime Semantics: DefineMethod#

With parameters object and optional parameter functionPrototype.

MethodDefinition:PropertyName(StrictFormalParameters){FunctionBody}
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. If the function code for this MethodDefinition is strict mode code, let strict be true. Otherwise let strict be false.
  4. Let scope be the running execution context's LexicalEnvironment.
  5. If functionPrototype was passed as a parameter, let kind be Normal; otherwise let kind be Method.
  6. Let closure be FunctionCreate(kind, StrictFormalParameters, FunctionBody, scope, strict). If functionPrototype was passed as a parameter, then pass its value as the prototype optional argument of FunctionCreate.
  7. Perform MakeMethod(closure, object).
  8. Return the Record{[[Key]]: propKey, [[Closure]]: closure}.

14.3.9Runtime Semantics: PropertyDefinitionEvaluation#

With parameters object and enumerable.

MethodDefinition:PropertyName(StrictFormalParameters){FunctionBody}
  1. Let methodDef be DefineMethod of MethodDefinition with argument object.
  2. ReturnIfAbrupt(methodDef).
  3. Perform SetFunctionName(methodDef.[[Closure]], methodDef.[[Key]]).
  4. Let desc be the PropertyDescriptor{[[Value]]: methodDef.[[Closure]], [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true}.
  5. Return ? DefinePropertyOrThrow(object, methodDef.[[Key]], desc).
MethodDefinition:GeneratorMethod

See 14.4.

MethodDefinition:getPropertyName(){FunctionBody}
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. If the function code for this MethodDefinition is strict mode code, let strict be true. Otherwise let strict be false.
  4. Let scope be the running execution context's LexicalEnvironment.
  5. Let formalParameterList be the production FormalParameters:[empty] .
  6. Let closure be FunctionCreate(Method, formalParameterList, FunctionBody, scope, strict).
  7. Perform MakeMethod(closure, object).
  8. Perform SetFunctionName(closure, propKey, "get").
  9. Let desc be the PropertyDescriptor{[[Get]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true}.
  10. Return ? DefinePropertyOrThrow(object, propKey, desc).
MethodDefinition:setPropertyName(PropertySetParameterList){FunctionBody}
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. If the function code for this MethodDefinition is strict mode code, let strict be true. Otherwise let strict be false.
  4. Let scope be the running execution context's LexicalEnvironment.
  5. Let closure be FunctionCreate(Method, PropertySetParameterList, FunctionBody, scope, strict).
  6. Perform MakeMethod(closure, object).
  7. Perform SetFunctionName(closure, propKey, "set").
  8. Let desc be the PropertyDescriptor{[[Set]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true}.
  9. Return ? DefinePropertyOrThrow(object, propKey, desc).

14.4Generator Function Definitions#

Syntax

GeneratorMethod[Yield]:*PropertyName[?Yield](StrictFormalParameters[Yield]){GeneratorBody} GeneratorDeclaration[Yield, Default]:function*BindingIdentifier[?Yield](FormalParameters[Yield]){GeneratorBody} [+Default]function*(FormalParameters[Yield]){GeneratorBody} GeneratorExpression:function*BindingIdentifier[Yield]opt(FormalParameters[Yield]){GeneratorBody} GeneratorBody:FunctionBody[Yield] YieldExpression[In]:yield yield[no LineTerminator here]AssignmentExpression[?In, Yield] yield[no LineTerminator here]*AssignmentExpression[?In, Yield] Note 1

紧随yield的语法上下文需要使用InputElementRegExpOrTemplateTail词法目标

Note 2

YieldExpression不能在 generator函数的FormalParameters中使用,因为在生成的generator object处于可恢复状态之前,将对所有属于FormalParameters的表达式进行求值。

Note 3

Abstract operations relating to generator objects are defined in 25.3.3.

14.4.1Static Semantics: Early Errors#

GeneratorMethod:*PropertyName(StrictFormalParameters){GeneratorBody} GeneratorDeclaration:function*BindingIdentifier(FormalParameters){GeneratorBody} GeneratorDeclaration:function*(FormalParameters){GeneratorBody} GeneratorExpression:function*BindingIdentifieropt(FormalParameters){GeneratorBody}

14.4.2Static Semantics: BoundNames#

GeneratorDeclaration:function*BindingIdentifier(FormalParameters){GeneratorBody}
  1. Return the BoundNames of BindingIdentifier.
GeneratorDeclaration:function*(FormalParameters){GeneratorBody}
  1. Return « "*default*" ».
Note

"*default*" is used within this specification as a synthetic name for hoistable anonymous functions that are defined using export declarations.

14.4.3Static Semantics: ComputedPropertyContains#

With parameter symbol.

GeneratorMethod:*PropertyName(StrictFormalParameters){GeneratorBody}
  1. Return the result of ComputedPropertyContains for PropertyName with argument symbol.

14.4.4Static Semantics: Contains#

With parameter symbol.

GeneratorDeclaration:function*BindingIdentifier(FormalParameters){GeneratorBody} GeneratorDeclaration:function*(FormalParameters){GeneratorBody} GeneratorExpression:function*BindingIdentifieropt(FormalParameters){GeneratorBody}
  1. Return false.
Note

依赖于子结构的静态语义规则通常不会关注函数定义。

14.4.5Static Semantics: HasComputedPropertyKey#

GeneratorMethod:*PropertyName(StrictFormalParameters){GeneratorBody}
  1. Return IsComputedPropertyKey of PropertyName.

14.4.6Static Semantics: HasDirectSuper#

GeneratorMethod:*PropertyName(StrictFormalParameters){GeneratorBody}
  1. If StrictFormalParameters Contains SuperCall is true, return true.
  2. Return GeneratorBody Contains SuperCall.

14.4.7Static Semantics: HasName#

GeneratorExpression:function*(FormalParameters){GeneratorBody}
  1. Return false.
GeneratorExpression:function*BindingIdentifier(FormalParameters){GeneratorBody}
  1. Return true.

14.4.8Static Semantics: IsConstantDeclaration#

GeneratorDeclaration:function*BindingIdentifier(FormalParameters){GeneratorBody} GeneratorDeclaration:function*(FormalParameters){GeneratorBody}
  1. Return false.

14.4.9Static Semantics: IsFunctionDefinition#

GeneratorExpression:function*BindingIdentifieropt(FormalParameters){GeneratorBody}
  1. Return true.

14.4.10Static Semantics: PropName#

GeneratorMethod:*PropertyName(StrictFormalParameters){GeneratorBody}
  1. Return PropName of PropertyName.

14.4.11Runtime Semantics: EvaluateBody#

With parameter functionObject.

GeneratorBody:FunctionBody
  1. Let G be ? OrdinaryCreateFromConstructor(functionObject, "%GeneratorPrototype%", « [[GeneratorState]], [[GeneratorContext]] »).
  2. Perform GeneratorStart(G, FunctionBody).
  3. Return Completion{[[Type]]: return, [[Value]]: G, [[Target]]: empty}.

14.4.12Runtime Semantics: InstantiateFunctionObject#

With parameter scope.

GeneratorDeclaration:function*BindingIdentifier(FormalParameters){GeneratorBody}
  1. If the function code for GeneratorDeclaration is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let name be StringValue of BindingIdentifier.
  3. Let F be GeneratorFunctionCreate(Normal, FormalParameters, GeneratorBody, scope, strict).
  4. Let prototype be ObjectCreate(%GeneratorPrototype%).
  5. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  6. Perform SetFunctionName(F, name).
  7. Return F.
GeneratorDeclaration:function*(FormalParameters){GeneratorBody}
  1. If the function code for GeneratorDeclaration is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let F be GeneratorFunctionCreate(Normal, FormalParameters, GeneratorBody, scope, strict).
  3. Let prototype be ObjectCreate(%GeneratorPrototype%).
  4. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  5. Perform SetFunctionName(F, "default").
  6. Return F.
Note

An anonymous GeneratorDeclaration can only occur as part of an export default declaration.

14.4.13Runtime Semantics: PropertyDefinitionEvaluation#

With parameter object and enumerable.

GeneratorMethod:*PropertyName(StrictFormalParameters){GeneratorBody}
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. If the function code for this GeneratorMethod is strict mode code, let strict be true. Otherwise let strict be false.
  4. Let scope be the running execution context's LexicalEnvironment.
  5. Let closure be GeneratorFunctionCreate(Method, StrictFormalParameters, GeneratorBody, scope, strict).
  6. Perform MakeMethod(closure, object).
  7. Let prototype be ObjectCreate(%GeneratorPrototype%).
  8. Perform DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  9. Perform SetFunctionName(closure, propKey).
  10. Let desc be the PropertyDescriptor{[[Value]]: closure, [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true}.
  11. Return ? DefinePropertyOrThrow(object, propKey, desc).

14.4.14Runtime Semantics: Evaluation#

GeneratorExpression:function*(FormalParameters){GeneratorBody}
  1. If the function code for this GeneratorExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let closure be GeneratorFunctionCreate(Normal, FormalParameters, GeneratorBody, scope, strict).
  4. Let prototype be ObjectCreate(%GeneratorPrototype%).
  5. Perform DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  6. Return closure.
GeneratorExpression:function*BindingIdentifier(FormalParameters){GeneratorBody}
  1. If the function code for this GeneratorExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the running execution context's LexicalEnvironment.
  3. Let funcEnv be NewDeclarativeEnvironment(scope).
  4. Let envRec be funcEnv's EnvironmentRecord.
  5. Let name be StringValue of BindingIdentifier.
  6. Perform envRec.CreateImmutableBinding(name, false).
  7. Let closure be GeneratorFunctionCreate(Normal, FormalParameters, GeneratorBody, funcEnv, strict).
  8. Let prototype be ObjectCreate(%GeneratorPrototype%).
  9. Perform DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  10. Perform SetFunctionName(closure, name).
  11. Perform envRec.InitializeBinding(name, closure).
  12. Return closure.
Note

GeneratorExpression中的BindingIdentifier可以从GeneratorExpression的FunctionBody中引用,以允许生成器代码以递归方式调用它自己。 但是,与GeneratorDeclaration不同的是,GeneratorExpression中的BindingIdentifier不能被引用,也不会影响包含GeneratorExpression的作用域。

YieldExpression:yield
  1. Return ? GeneratorYield(CreateIterResultObject(undefined, false)).
YieldExpression:yieldAssignmentExpression
  1. Let exprRef be the result of evaluating AssignmentExpression.
  2. Let value be ? GetValue(exprRef).
  3. Return ? GeneratorYield(CreateIterResultObject(value, false)).
YieldExpression:yield*AssignmentExpression
  1. Let exprRef be the result of evaluating AssignmentExpression.
  2. Let value be ? GetValue(exprRef).
  3. Let iterator be ? GetIterator(value).
  4. Let received be NormalCompletion(undefined).
  5. Repeat
    1. If received.[[Type]] is normal, then
      1. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
      2. Let done be ? IteratorComplete(innerResult).
      3. If done is true, then
        1. Return ? IteratorValue(innerResult).
      4. Let received be GeneratorYield(innerResult).
    2. Else if received.[[Type]] is throw, then
      1. Let throw be ? GetMethod(iterator, "throw").
      2. If throw is not undefined, then
        1. Let innerResult be ? Call(throw, iterator, « received.[[Value]] »).
        2. NOTE: Exceptions from the inner iterator throw method are propagated. Normal completions from an inner throw method are processed similarly to an inner next.
        3. If Type(innerResult) is not Object, throw a TypeError exception.
        4. Let done be ? IteratorComplete(innerResult).
        5. If done is true, then
          1. Return ? IteratorValue(innerResult).
        6. Let received be GeneratorYield(innerResult).
      3. Else,
        1. NOTE: If iterator does not have a throw method, this throw is going to terminate the yield* loop. But first we need to give iterator a chance to clean up.
        2. Perform ? IteratorClose(iterator, Completion{[[Type]]: normal, [[Value]]: empty, [[Target]]: empty}).
        3. NOTE: The next step throws a TypeError to indicate that there was a yield* protocol violation: iterator does not have a throw method.
        4. Throw a TypeError exception.
    3. Else,
      1. Assert: received.[[Type]] is return.
      2. Let return be ? GetMethod(iterator, "return").
      3. If return is undefined, return Completion(received).
      4. Let innerReturnResult be ? Call(return, iterator, « received.[[Value]] »).
      5. If Type(innerReturnResult) is not Object, throw a TypeError exception.
      6. Let done be ? IteratorComplete(innerReturnResult).
      7. If done is true, then
        1. Let value be ? IteratorValue(innerReturnResult).
        2. Return Completion{[[Type]]: return, [[Value]]: value, [[Target]]: empty}.
      8. Let received be GeneratorYield(innerReturnResult).

14.5Class Definitions#

Syntax

ClassDeclaration[Yield, Default]:classBindingIdentifier[?Yield]ClassTail[?Yield] [+Default]classClassTail[?Yield] ClassExpression[Yield]:classBindingIdentifier[?Yield]optClassTail[?Yield] ClassTail[Yield]:ClassHeritage[?Yield]opt{ClassBody[?Yield]opt} ClassHeritage[Yield]:extendsLeftHandSideExpression[?Yield] ClassBody[Yield]:ClassElementList[?Yield] ClassElementList[Yield]:ClassElement[?Yield] ClassElementList[?Yield]ClassElement[?Yield] ClassElement[Yield]:MethodDefinition[?Yield] staticMethodDefinition[?Yield] ; Note

类定义总是严格模式代码

14.5.1Static Semantics: Early Errors#

ClassTail:ClassHeritageopt{ClassBody}
  • It is a Syntax Error if ClassHeritage is not present and the following algorithm evaluates to true:

    1. Let constructor be ConstructorMethod of ClassBody.
    2. If constructor is empty, return false.
    3. Return HasDirectSuper of constructor.
ClassBody:ClassElementList
  • 如果ClassElementList的PrototypePropertyNameList包含多个“构造函数”,则是一个语法错误。 class test { constructor () {} constructor (arg1) {} } Uncaught SyntaxError: A class may only have one constructor
ClassElement:MethodDefinition
  • 如果MethodDefinition的PropName不是“构造函数”,并且MethodDefinition的HasDirectSuper为true,那么这是一个语法错误。 意思是非构造函数不能有super语句 class ClassA { } class ClassB extends ClassA { say () { super(); } } Uncaught SyntaxError: 'super' keyword unexpected here
  • 如果MethodDefinition的PropName是“构造函数”,并且MethodDefinition的SpecialMethod是true,那么它是一个语法错误。 意思是构造函数不能是generator函数,get函数,set函数,否则报错 class ClassC { * constructor() {} } Uncaught SyntaxError: Class constructor may not be a generator
ClassElement:staticMethodDefinition
  • 如果MethodDefinition的HasDirectSuper为true,那么这是一个语法错误。 静态方法不能有super语句 class ClassSt extends ClassA { constructor() {} static say () { super(); } } Uncaught SyntaxError: 'super' keyword unexpected here
  • 如果MethodDefinition的PropName是“prototype”,那么它是一个语法错误。 class ClassP { constructor() {} static prototype () { } } Classes may not have static property named prototype

14.5.2Static Semantics: BoundNames#

ClassDeclaration:classBindingIdentifierClassTail
  1. Return the BoundNames of BindingIdentifier.
ClassDeclaration:classClassTail
  1. Return « "*default*" ».

14.5.3Static Semantics: ConstructorMethod#

ClassElementList:ClassElement
  1. If ClassElement is the production ClassElement:; , return empty.
  2. If IsStatic of ClassElement is true, return empty.
  3. If PropName of ClassElement is not "constructor", return empty.
  4. Return ClassElement.
ClassElementList:ClassElementListClassElement
  1. Let head be ConstructorMethod of ClassElementList.
  2. If head is not empty, return head.
  3. If ClassElement is the production ClassElement:; , return empty.
  4. If IsStatic of ClassElement is true, return empty.
  5. If PropName of ClassElement is not "constructor", return empty.
  6. Return ClassElement.
Note

早期错误规则确保只有一个名为“"constructor"的方法定义,并且它不是访问器属性(accessor property)或生成器(generator)定义。

14.5.4Static Semantics: Contains#

With parameter symbol.

ClassTail:ClassHeritageopt{ClassBody}
  1. If symbol is ClassBody, return true.
  2. If symbol is ClassHeritage, then
    1. If ClassHeritage is present, return true; otherwise return false.
  3. Let inHeritage be ClassHeritage Contains symbol.
  4. If inHeritage is true, return true.
  5. Return the result of ComputedPropertyContains for ClassBody with argument symbol.
Note

Static semantic rules that depend upon substructure generally do not look into class bodies except for PropertyName productions.

取决于子结构的静态语义规则通常不会查看除了PropertyName表达式以外的类体。

14.5.5Static Semantics: ComputedPropertyContains#

With parameter symbol.

ClassElementList:ClassElementListClassElement
  1. Let inList be the result of ComputedPropertyContains for ClassElementList with argument symbol.
  2. If inList is true, return true.
  3. Return the result of ComputedPropertyContains for ClassElement with argument symbol.
ClassElement:MethodDefinition
  1. Return the result of ComputedPropertyContains for MethodDefinition with argument symbol.
ClassElement:staticMethodDefinition
  1. Return the result of ComputedPropertyContains for MethodDefinition with argument symbol.
ClassElement:;
  1. Return false.

14.5.6Static Semantics: HasName#

ClassExpression:classClassTail
  1. Return false.
ClassExpression:classBindingIdentifierClassTail
  1. Return true.

14.5.7Static Semantics: IsConstantDeclaration#

ClassDeclaration:classBindingIdentifierClassTail ClassDeclaration:classClassTail
  1. Return false.

14.5.8Static Semantics: IsFunctionDefinition#

ClassExpression:classBindingIdentifieroptClassTail
  1. Return true.

14.5.9Static Semantics: IsStatic#

ClassElement:MethodDefinition
  1. Return false.
ClassElement:staticMethodDefinition
  1. Return true.
ClassElement:;
  1. Return false.

14.5.10Static Semantics: NonConstructorMethodDefinitions#

ClassElementList:ClassElement
  1. If ClassElement is the production ClassElement:; , return a new empty List.
  2. If IsStatic of ClassElement is false and PropName of ClassElement is "constructor", return a new empty List.
  3. Return a List containing ClassElement.
ClassElementList:ClassElementListClassElement
  1. Let list be NonConstructorMethodDefinitions of ClassElementList.
  2. If ClassElement is the production ClassElement:; , return list.
  3. If IsStatic of ClassElement is false and PropName of ClassElement is "constructor", return list.
  4. Append ClassElement to the end of list.
  5. Return list.

14.5.11Static Semantics: PrototypePropertyNameList#

ClassElementList:ClassElement
  1. If PropName of ClassElement is empty, return a new empty List.
  2. If IsStatic of ClassElement is true, return a new empty List.
  3. Return a List containing PropName of ClassElement.
ClassElementList:ClassElementListClassElement
  1. Let list be PrototypePropertyNameList of ClassElementList.
  2. If PropName of ClassElement is empty, return list.
  3. If IsStatic of ClassElement is true, return list.
  4. Append PropName of ClassElement to the end of list.
  5. Return list.

14.5.12Static Semantics: PropName#

ClassElement:;
  1. Return empty.

14.5.13Static Semantics: StaticPropertyNameList#

ClassElementList:ClassElement
  1. If PropName of ClassElement is empty, return a new empty List.
  2. If IsStatic of ClassElement is false, return a new empty List.
  3. Return a List containing PropName of ClassElement.
ClassElementList:ClassElementListClassElement
  1. Let list be StaticPropertyNameList of ClassElementList.
  2. If PropName of ClassElement is empty, return list.
  3. If IsStatic of ClassElement is false, return list.
  4. Append PropName of ClassElement to the end of list.
  5. Return list.

14.5.14Runtime Semantics: ClassDefinitionEvaluation#

With parameter className.

ClassTail:ClassHeritageopt{ClassBodyopt}
  1. Let lex be the LexicalEnvironment of the running execution context.
  2. Let classScope be NewDeclarativeEnvironment(lex).
  3. Let classScopeEnvRec be classScope's EnvironmentRecord.
  4. If className is not undefined, then
    1. Perform classScopeEnvRec.CreateImmutableBinding(className, true).
  5. If ClassHeritageopt is not present, then
    1. Let protoParent be the intrinsic object %ObjectPrototype%.
    2. Let constructorParent be the intrinsic object %FunctionPrototype%.
  6. Else,
    1. Set the running execution context's LexicalEnvironment to classScope.
    2. Let superclass be the result of evaluating ClassHeritage.
    3. Set the running execution context's LexicalEnvironment to lex.
    4. ReturnIfAbrupt(superclass).
    5. If superclass is null, then
      1. Let protoParent be null.
      2. Let constructorParent be the intrinsic object %FunctionPrototype%.
    6. Else if IsConstructor(superclass) is false, throw a TypeError exception.
    7. Else,
      1. Let protoParent be ? Get(superclass, "prototype").
      2. If Type(protoParent) is neither Object nor Null, throw a TypeError exception.
      3. Let constructorParent be superclass.
  7. Let proto be ObjectCreate(protoParent).
  8. If ClassBodyopt is not present, let constructor be empty.
  9. Else, let constructor be ConstructorMethod of ClassBody.
  10. If constructor is empty, then
    1. If ClassHeritageopt is present, then
      1. Let constructor be the result of parsing the source text
        constructor(... args){ super (...args);}
        using the syntactic grammar with the goal symbol MethodDefinition.
    2. Else,
      1. Let constructor be the result of parsing the source text
        constructor( ){ }
        using the syntactic grammar with the goal symbol MethodDefinition.
  11. Set the running execution context's LexicalEnvironment to classScope.
  12. Let constructorInfo be the result of performing DefineMethod for constructor with arguments proto and constructorParent as the optional functionPrototype argument.
  13. Assert: constructorInfo is not an abrupt completion.
  14. Let F be constructorInfo.[[Closure]].
  15. If ClassHeritageopt is present, set F's [[ConstructorKind]] internal slot to "derived".
  16. Perform MakeConstructor(F, false, proto).
  17. Perform MakeClassConstructor(F).
  18. Perform CreateMethodProperty(proto, "constructor", F).
  19. If ClassBodyopt is not present, let methods be a new empty List.
  20. Else, let methods be NonConstructorMethodDefinitions of ClassBody.
  21. For each ClassElement m in order from methods
    1. If IsStatic of m is false, then
      1. Let status be the result of performing PropertyDefinitionEvaluation for m with arguments proto and false.
    2. Else,
      1. Let status be the result of performing PropertyDefinitionEvaluation for m with arguments F and false.
    3. If status is an abrupt completion, then
      1. Set the running execution context's LexicalEnvironment to lex.
      2. Return Completion(status).
  22. Set the running execution context's LexicalEnvironment to lex.
  23. If className is not undefined, then
    1. Perform classScopeEnvRec.InitializeBinding(className, F).
  24. Return F.

14.5.15Runtime Semantics: BindingClassDeclarationEvaluation#

ClassDeclaration:classBindingIdentifierClassTail
  1. Let className be StringValue of BindingIdentifier.
  2. Let value be the result of ClassDefinitionEvaluation of ClassTail with argument className.
  3. ReturnIfAbrupt(value).
  4. Let hasNameProperty be ? HasOwnProperty(value, "name").
  5. If hasNameProperty is false, perform SetFunctionName(value, className).
  6. Let env be the running execution context's LexicalEnvironment.
  7. Perform ? InitializeBoundName(className, value, env).
  8. Return value.
ClassDeclaration:classClassTail
  1. Return the result of ClassDefinitionEvaluation of ClassTail with argument undefined.
Note

ClassDeclaration:classClassTail classClassTail只作为ExportDeclaration的一部分出现,name属性的设置和绑定作为该表达式的执行操作的一部分进行处理。 见15.2.3.11.

14.5.16Runtime Semantics: Evaluation#

ClassDeclaration:classBindingIdentifierClassTail
  1. Let status be the result of BindingClassDeclarationEvaluation of this ClassDeclaration.
  2. ReturnIfAbrupt(status).
  3. Return NormalCompletion(empty).
Note 1

ClassDeclaration:classClassTail only occurs as part of an ExportDeclaration and is never directly evaluated.

ClassExpression:classBindingIdentifieroptClassTail
  1. If BindingIdentifieropt is not present, let className be undefined.
  2. Else, let className be StringValue of BindingIdentifier.
  3. Let value be the result of ClassDefinitionEvaluation of ClassTail with argument className.
  4. ReturnIfAbrupt(value).
  5. If className is not undefined, then
    1. Let hasNameProperty be ? HasOwnProperty(value, "name").
    2. If hasNameProperty is false, then
      1. Perform SetFunctionName(value, className).
  6. Return NormalCompletion(value).
Note 2

If the class definition included a name static method then that method is not over-written with a name data property for the class name.

如果类定义包含name静态方法,那么该方法不会被类名称的name数据属性覆盖。

class ClassName { static name() { console.log('static name'); } name() { console.log('name'); } } ClassName.name() 打印:static name

14.6Tail Position Calls#

14.6.1Static Semantics: IsInTailPosition(nonterminal)#

The abstract operation IsInTailPosition with argument nonterminal performs the following steps:

  1. Assert: nonterminal is a parsed grammar production.
  2. If the source code matching nonterminal is not strict code, return false.
  3. If nonterminal is not contained within a FunctionBody or ConciseBody, return false.
  4. Let body be the FunctionBody or ConciseBody that most closely contains nonterminal.
  5. If body is the FunctionBody of a GeneratorBody, return false.
  6. Return the result of HasProductionInTailPosition of body with argument nonterminal.
Note

Tail Position calls are only defined in strict mode code because of a common non-standard language extension (see 9.2.7) that enables observation of the chain of caller contexts.

由于通用的非标准语言扩展(见9.2.7),尾部位置调用只能在严格模式代码中定义,因此可以观察调用者上下文链。

14.6.2Static Semantics: HasProductionInTailPosition#

With parameter nonterminal.

Note

nonterminal is a parsed grammar production that represents a specific range of source text. When the following algorithms compare nonterminal to other grammar symbols they are testing whether the same source text was matched by both symbols.

非终结符是一个解析的语法生成,表示特定的源文本范围。 当以下算法将非终结符与其他语法符号进行比较时,他们正在测试相同的源文本是否被两个符号匹配。

14.6.2.1Statement Rules#

ConciseBody:AssignmentExpression
  1. Return HasProductionInTailPosition of AssignmentExpression with argument nonterminal.
StatementList:StatementListStatementListItem
  1. Let has be HasProductionInTailPosition of StatementList with argument nonterminal.
  2. If has is true, return true.
  3. Return HasProductionInTailPosition of StatementListItem with argument nonterminal.
FunctionStatementList:[empty] StatementListItem:Declaration Statement:VariableStatement EmptyStatement ExpressionStatement ContinueStatement BreakStatement ThrowStatement DebuggerStatement Block:{} ReturnStatement:return; LabelledItem:FunctionDeclaration IterationStatement:for(LeftHandSideExpressioninExpression)Statement for(varForBindinginExpression)Statement for(ForDeclarationinExpression)Statement for(LeftHandSideExpressionofAssignmentExpression)Statement for(varForBindingofAssignmentExpression)Statement for(ForDeclarationofAssignmentExpression)Statement CaseBlock:{}
  1. Return false.
IfStatement:if(Expression)StatementelseStatement
  1. Let has be HasProductionInTailPosition of the first Statement with argument nonterminal.
  2. If has is true, return true.
  3. Return HasProductionInTailPosition of the second Statement with argument nonterminal.
IfStatement:if(Expression)Statement IterationStatement:doStatementwhile(Expression); while(Expression)Statement for(Expressionopt;Expressionopt;Expressionopt)Statement for(varVariableDeclarationList;Expressionopt;Expressionopt)Statement for(LexicalDeclarationExpressionopt;Expressionopt)Statement WithStatement:with(Expression)Statement
  1. Return HasProductionInTailPosition of Statement with argument nonterminal.
LabelledStatement:LabelIdentifier:LabelledItem
  1. Return HasProductionInTailPosition of LabelledItem with argument nonterminal.
ReturnStatement:returnExpression;
  1. Return HasProductionInTailPosition of Expression with argument nonterminal.
SwitchStatement:switch(Expression)CaseBlock
  1. Return HasProductionInTailPosition of CaseBlock with argument nonterminal.
CaseBlock:{CaseClausesoptDefaultClauseCaseClausesopt}
  1. Let has be false.
  2. If the first CaseClauses is present, let has be HasProductionInTailPosition of the first CaseClauses with argument nonterminal.
  3. If has is true, return true.
  4. Let has be HasProductionInTailPosition of the DefaultClause with argument nonterminal.
  5. If has is true, return true.
  6. If the second CaseClauses is present, let has be HasProductionInTailPosition of the second CaseClauses with argument nonterminal.
  7. Return has.
CaseClauses:CaseClausesCaseClause
  1. Let has be HasProductionInTailPosition of CaseClauses with argument nonterminal.
  2. If has is true, return true.
  3. Return HasProductionInTailPosition of CaseClause with argument nonterminal.
CaseClause:caseExpression:StatementListopt DefaultClause:default:StatementListopt
  1. If StatementList is present, return HasProductionInTailPosition of StatementList with argument nonterminal.
  2. Return false.
TryStatement:tryBlockCatch
  1. Return HasProductionInTailPosition of Catch with argument nonterminal.
TryStatement:tryBlockFinally TryStatement:tryBlockCatchFinally
  1. Return HasProductionInTailPosition of Finally with argument nonterminal.
Catch:catch(CatchParameter)Block
  1. Return HasProductionInTailPosition of Block with argument nonterminal.

14.6.2.2Expression Rules#

Note

A potential tail position call that is immediately followed by return GetValue of the call result is also a possible tail position call. Function calls cannot return reference values, so such a GetValue operation will always returns the same value as the actual function call result.

AssignmentExpression:YieldExpression ArrowFunction LeftHandSideExpression=AssignmentExpression LeftHandSideExpressionAssignmentOperatorAssignmentExpression 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 RelationalExpressioninstanceofShiftExpression RelationalExpressioninShiftExpression ShiftExpression:ShiftExpression<<AdditiveExpression ShiftExpression>>AdditiveExpression ShiftExpression>>>AdditiveExpression AdditiveExpression:AdditiveExpression+MultiplicativeExpression AdditiveExpression-MultiplicativeExpression MultiplicativeExpression:MultiplicativeExpressionMultiplicativeOperatorExponentiationExpression ExponentiationExpression:UpdateExpression**ExponentiationExpression UpdateExpression:LeftHandSideExpression++ LeftHandSideExpression-- ++UnaryExpression --UnaryExpression UnaryExpression:deleteUnaryExpression voidUnaryExpression typeofUnaryExpression +UnaryExpression -UnaryExpression ~UnaryExpression !UnaryExpression CallExpression:SuperCall CallExpression[Expression] CallExpression.IdentifierName NewExpression:newNewExpression MemberExpression:MemberExpression[Expression] MemberExpression.IdentifierName SuperProperty MetaProperty newMemberExpressionArguments PrimaryExpression:this IdentifierReference Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression RegularExpressionLiteral TemplateLiteral
  1. Return false.
Expression:AssignmentExpression Expression,AssignmentExpression
  1. Return HasProductionInTailPosition of AssignmentExpression with argument nonterminal.
ConditionalExpression:LogicalORExpression?AssignmentExpression:AssignmentExpression
  1. Let has be HasProductionInTailPosition of the first AssignmentExpression with argument nonterminal.
  2. If has is true, return true.
  3. Return HasProductionInTailPosition of the second AssignmentExpression with argument nonterminal.
LogicalANDExpression:LogicalANDExpression&&BitwiseORExpression
  1. Return HasProductionInTailPosition of BitwiseORExpression with argument nonterminal.
LogicalORExpression:LogicalORExpression||LogicalANDExpression
  1. Return HasProductionInTailPosition of LogicalANDExpression with argument nonterminal.
CallExpression:MemberExpressionArguments CallExpressionArguments CallExpressionTemplateLiteral
  1. If this CallExpression is nonterminal, return true.
  2. Return false.
MemberExpression:MemberExpressionTemplateLiteral
  1. If this MemberExpression is nonterminal, return true.
  2. Return false.
PrimaryExpression:CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return HasProductionInTailPosition of expr with argument nonterminal.
ParenthesizedExpression:(Expression)
  1. Return HasProductionInTailPosition of Expression with argument nonterminal.

14.6.3Runtime Semantics: PrepareForTailCall ( )#

The abstract operation PrepareForTailCall performs the following steps:

  1. Let leafContext be the running execution context.
  2. Suspend leafContext.
  3. Pop leafContext from the execution context stack. The execution context now on the top of the stack becomes the running execution context.
  4. Assert: leafContext has no further use. It will never be activated as the running execution context.

A tail position call must either release any transient internal resources associated with the currently executing function execution context before invoking the target function or reuse those resources in support of the target function.

尾部位置调用必须在调用目标函数之前释放与当前正在执行的函数执行上下文相关联的任何瞬态内部资源,或者重用那些支持目标函数的资源。

Note

For example, a tail position call should only grow an implementation's activation record stack by the amount that the size of the target function's activation record exceeds the size of the calling function's activation record. If the target function's activation record is smaller, then the total size of the stack should decrease.

例如,一个尾部位置调用应该只增加一个实现的激活记录堆栈,其大小为目标函数激活记录的大小超过调用函数激活记录的大小。 如果目标函数的激活记录较小,那么堆栈的总大小应该减小。

15ECMAScript Language: Scripts and Modules(ECMAScript语言:脚本和模块)#

15.1Scripts#

Syntax

Script:ScriptBodyopt ScriptBody:StatementList

15.1.1Static Semantics: Early Errors#

Script:ScriptBody
  • It is a Syntax Error if the LexicallyDeclaredNames of ScriptBody contains any duplicate entries.

    如果ScriptBody的词法声明名称包含任何重复的条目,则这是一个语法错误。

    let和const不能重复

    let a = 5; let a = 8; Uncaught SyntaxError: Identifier 'a' has already been declared
  • It is a Syntax Error if any element of the LexicallyDeclaredNames of ScriptBody also occurs in the VarDeclaredNames of ScriptBody.

    如果ScriptBody的LexicallyDeclaredNames的任何元素也出现在ScriptBody的VarDeclaredNames中,则它是一个语法错误。

    var声明的变量名和在let或const声明的变量名重复,则报语法错误

    var testDec = 10; let testDec = 8; Uncaught SyntaxError: Identifier 'testDec' has already been declared
ScriptBody:StatementList
  • It is a Syntax Error if StatementList Contains super unless the source code containing super is eval code that is being processed by a direct eval that is contained in function code that is not the function code of an ArrowFunction.
  • 它是一个语法错误,如果语句列表包含super,除非包含super的源代码是正在由包含在不是一个箭头函数的函数代码的直接eval处理的eval代码。
  • It is a Syntax Error if StatementList Contains NewTarget unless the source code containing NewTarget is eval code that is being processed by a direct eval that is contained in function code that is not the function code of an ArrowFunction.
  • 如果语句列表包含NewTarget,则为语法错误,除非包含NewTarget的源代码是由包含在不是箭头函数的函数代码中的直接eval处理的eval代码。
  • It is a Syntax Error if ContainsDuplicateLabels of StatementList with argument « » is true.
  • 如果带有参数«»的语句列表的ContainsDuplicateLabels为true,那么它是一个语法错误。
  • It is a Syntax Error if ContainsUndefinedBreakTarget of StatementList with argument « » is true.
  • 如果带有参数«»的语句列表的ContainsUndefinedBreakTarget为true,则它是一个语法错误。
  • It is a Syntax Error if ContainsUndefinedContinueTarget of StatementList with arguments « » and « » is true.
  • 如果带有参数«»和«»的语句列表的ContainsUndefinedContinueTarget为true,则它是一个语法错误。

15.1.2Static Semantics: IsStrict#

ScriptBody:StatementList
  1. If the Directive Prologue of StatementList contains a Use Strict Directive, return true; otherwise, return false.

如果语句列表的指令序言包含Use Strict指令,则返回true; 否则,返回false。

15.1.3Static Semantics: LexicallyDeclaredNames#

ScriptBody:StatementList
  1. Return TopLevelLexicallyDeclaredNames of StatementList.
Note

At the top level of a Script, function declarations are treated like var declarations rather than like lexical declarations.

在脚本的顶层,函数声明被视为var声明而不是像词法声明。意思是等价于var而不是let

15.1.4Static Semantics: LexicallyScopedDeclarations#

ScriptBody:StatementList
  1. Return TopLevelLexicallyScopedDeclarations of StatementList.

15.1.5Static Semantics: VarDeclaredNames#

ScriptBody:StatementList
  1. Return TopLevelVarDeclaredNames of StatementList.

15.1.6Static Semantics: VarScopedDeclarations#

ScriptBody:StatementList
  1. Return TopLevelVarScopedDeclarations of StatementList.

15.1.7Runtime Semantics: Evaluation#

Script:[empty]
  1. Return NormalCompletion(undefined).

15.1.8Script Records(脚本记录)#

脚本记录封装了有关正在执行的脚本的信息。 每个脚本记录都包含表36中列出的字段。

表36: 脚本记录字段
字段名 值类型 意义
[[Realm]] Realm Record | undefined The realm within which this script was created. undefined if not yet assigned.

脚本创建的realm。 如果尚未分配则为未定义。

[[Environment]] Lexical Environment | undefined The Lexical Environment containing the top level bindings for this script. This field is set when the script is instantiated.

包含此脚本的顶级绑定的词法环境。 该字段在脚本实例化时设置。

[[ECMAScriptCode]] a parse result The result of parsing the source text of this module using Script as the goal symbol.

使用Script作为目标符号解析此模块的源文本的结果。

[[HostDefined]] Any, default value is undefined. Field reserved for use by host environments that need to associate additional information with a script.

保留字段供需要将附加信息与脚本关联的主机环境使用。

15.1.9ParseScript ( sourceText, realm, hostDefined )#

The abstract operation ParseScript with arguments sourceText, realm, and hostDefined creates a Script Record based upon the result of parsing sourceText as a Script. ParseScript performs the following steps:

  1. Assert: sourceText is an ECMAScript source text (see clause 10).
  2. Parse sourceText using Script as the goal symbol and analyze the parse result for any Early Error conditions. If the parse was successful and no early errors were found, let body be the resulting parse tree. Otherwise, let body be a List of one or more SyntaxError or ReferenceError objects representing the parsing errors and/or early errors. Parsing and early error detection may be interweaved in an implementation dependent manner. If more than one parsing error or early error is present, the number and ordering of error objects in the list is implementation dependent, but at least one must be present.
  3. If body is a List of errors, then return body.
  4. Return Script Record {[[Realm]]: realm, [[Environment]]: undefined, [[ECMAScriptCode]]: body, [[HostDefined]]: hostDefined}.
Note

An implementation may parse script source text and analyze it for Early Error conditions prior to evaluation of ParseScript for that script source text. However, the reporting of any errors must be deferred until the point where this specification actually performs ParseScript upon that source text.

一个实现可以解析脚本源文本,并在执行该脚本源文本的ParseScript之前对它进行早期错误条件分析。 但是,任何错误的报告必须推迟到本规范实际上在该源文本上执行ParseScript的时候。

15.1.10ScriptEvaluation ( scriptRecord )#

  1. Let globalEnv be scriptRecord.[[Realm]].[[GlobalEnv]].
  2. Let scriptCxt be a new ECMAScript code execution context.
  3. Set the Function of scriptCxt to null.
  4. Set the Realm of scriptCxt to scriptRecord.[[Realm]].
  5. Set the ScriptOrModule of scriptCxt to scriptRecord.
  6. Set the VariableEnvironment of scriptCxt to globalEnv.
  7. Set the LexicalEnvironment of scriptCxt to globalEnv.
  8. Suspend the currently running execution context.
  9. Push scriptCxt on to the execution context stack; scriptCxt is now the running execution context.
  10. Let result be GlobalDeclarationInstantiation(ScriptBody, globalEnv).
  11. If result.[[Type]] is normal, then
    1. Let result be the result of evaluating ScriptBody.
  12. If result.[[Type]] is normal and result.[[Value]] is empty, then
    1. Let result be NormalCompletion(undefined).
  13. Suspend scriptCxt and remove it from the execution context stack.
  14. Assert: the execution context stack is not empty.
  15. Resume the context that is now on the top of the execution context stack as the running execution context.
  16. Return Completion(result).
  1. globalEnv作为scriptRecord.[[Realm]].[[GlobalEnv]]。
  2. scriptCxt作为新的ECMAScript代码执行上下文。
  3. 将scriptCxt的函数设置为null。
  4. 将scriptCxt的realm设置为scriptRecord.[[Realm]]。
  5. 将scriptCxt的ScriptOrModule设置为scriptRecord。
  6. 将scriptCxt的VariableEnvironment设置为globalEnv。
  7. 将scriptCxt的LexicalEnvironment设置为globalEnv。
  8. 暂停当前正在运行的执行上下文。
  9. 将脚本文件推入执行上下文堆栈; scriptCxt现在是正在运行的执行上下文。
  10. result是GlobalDeclarationInstantiation(ScriptBody, globalEnv)的执行结果。
  11. 如果result.[[Type]]是normal,那么
  12. 让result成为执行ScriptBody的结果。
  13. 如果result.[[Type]]是normal,result.[[Value]]是空的,那么
  14. result为NormalCompletion(undefined)。
  15. 挂起scriptCxt并将其从执行上下文堆栈中删除。
  16. 断言:执行上下文堆栈不是空的。
  17. 将当前位于执行上下文堆栈顶部的上下文恢复为正在运行的执行上下文。
  18. Return Completion(result).

15.1.11Runtime Semantics: GlobalDeclarationInstantiation (script, env)(全局声明实例化)#

Note 1

When an execution context is established for evaluating scripts, declarations are instantiated in the current global environment. Each global binding declared in the code is instantiated.

当建立执行上下文用于执行脚本时,声明在当前的全局环境中被实例化。 代码中声明的每个全局绑定都是实例化的。

GlobalDeclarationInstantiation is performed as follows using arguments script and env. script is the ScriptBody for which the execution context is being established. env is the global lexical environment in which bindings are to be created.

GlobalDeclarationInstantiation使用参数script和env执行过程如下。 script是正在建立执行上下文的ScriptBody。 env是要创建绑定的全局词法环境。

  1. Let envRec be env's EnvironmentRecord.
  2. Assert: envRec is a global Environment Record.
  3. Let lexNames be the LexicallyDeclaredNames of script.
  4. Let varNames be the VarDeclaredNames of script.
  5. For each name in lexNames, do
    1. If envRec.HasVarDeclaration(name) is true, throw a SyntaxError exception.
    2. If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
    3. Let hasRestrictedGlobal be ? envRec.HasRestrictedGlobalProperty(name).
    4. If hasRestrictedGlobal is true, throw a SyntaxError exception.
  6. For each name in varNames, do
    1. If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
  7. Let varDeclarations be the VarScopedDeclarations of script.
  8. Let functionsToInitialize be a new empty List.
  9. Let declaredFunctionNames be a new empty List.
  10. For each d in varDeclarations, in reverse list order do
    1. If d is neither a VariableDeclaration or a ForBinding, then
      1. Assert: d is either a FunctionDeclaration or a GeneratorDeclaration.
      2. NOTE If there are multiple FunctionDeclarations for the same name, the last declaration is used.
      3. Let fn be the sole element of the BoundNames of d.
      4. If fn is not an element of declaredFunctionNames, then
        1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(fn).
        2. If fnDefinable is false, throw a TypeError exception.
        3. Append fn to declaredFunctionNames.
        4. Insert d as the first element of functionsToInitialize.
  11. Let declaredVarNames be a new empty List.
  12. For each d in varDeclarations, do
    1. If d is a VariableDeclaration or a ForBinding, then
      1. For each String vn in the BoundNames of d, do
        1. If vn is not an element of declaredFunctionNames, then
          1. Let vnDefinable be ? envRec.CanDeclareGlobalVar(vn).
          2. If vnDefinable is false, throw a TypeError exception.
          3. If vn is not an element of declaredVarNames, then
            1. Append vn to declaredVarNames.
  13. NOTE: No abnormal terminations occur after this algorithm step if the global object is an ordinary object. However, if the global object is a Proxy exotic object it may exhibit behaviours that cause abnormal terminations in some of the following steps.
  14. NOTE: Annex B.3.3.2 adds additional steps at this point.
  15. Let lexDeclarations be the LexicallyScopedDeclarations of script.
  16. For each element d in lexDeclarations do
    1. NOTE Lexically declared names are only instantiated here but not initialized.
    2. For each element dn of the BoundNames of d do
      1. If IsConstantDeclaration of d is true, then
        1. Perform ? envRec.CreateImmutableBinding(dn, true).
      2. Else,
        1. Perform ? envRec.CreateMutableBinding(dn, false).
  17. For each production f in functionsToInitialize, do
    1. Let fn be the sole element of the BoundNames of f.
    2. Let fo be the result of performing InstantiateFunctionObject for f with argument env.
    3. Perform ? envRec.CreateGlobalFunctionBinding(fn, fo, false).
  18. For each String vn in declaredVarNames, in list order do
    1. Perform ? envRec.CreateGlobalVarBinding(vn, false).
  19. Return NormalCompletion(empty).
  1. 让envRec成为env的EnvironmentRecord。
  2. 断言:envRec是全局环境记录。
  3. 让lexNames成为脚本的LexicalDeclaredNames。
  4. 让varNames是脚本的VarDeclaredNames。
  5. 对于lexNames中的每个name,执行
    1. 如果envRec.HasVarDeclaration(name)为true,则抛出一个SyntaxError异常。
    2. 如果envRec.HasLexicalDeclaration(name)为true,则抛出一个SyntaxError异常。
    3. 让hasRestrictedGlobal作为 envRec.HasRestrictedGlobalProperty(name)的执行结果。
    4. 如果hasRestrictedGlobal为true,则抛出一个SyntaxError异常。
  6. 对于varNames中的每个name,请执行
    1. 如果envRec.HasLexicalDeclaration(name)为true,则抛出一个SyntaxError异常。
  7. 让varDeclarations是脚本的VarScopedDeclarations。
  8. 让functionToInitialize成为一个新的空列表。
  9. 让declaredFunctionNames是一个新的空List。
  10. 对于varDeclarations中的每个d,按反向列表顺序执行
    1. 如果d既不是一个VariableDeclaration也不是一个ForBinding,那么
      1. 断言:d是FunctionDeclaration或GeneratorDeclaration。
      2. 注意如果有多个同名的FunctionDeclarations,则使用最后一个声明。
      3. 让fn成为d的BoundNames的唯一元素。
      4. 如果fn不是declaredFunctionNames的元素,那么
        1. 让fnDefinable作为envRec.CanDeclareGlobalFunction(FN)的结果。
        2. 如果fnDefinable为false,则引发TypeError异常。
        3. 将fn附加到declaredFunctionNames。
        4. 将d作为functionsToInitialize的第一个元素插入。
  11. 让declaredVarNames是一个新的空列表。
  12. 对于varDeclarations中的每个d,执行
    1. 如果d是一个VariableDeclaration或者一个ForBinding,那么
      1. 对于d的BoundNames中的每个String vn,执行
        1. 如果vn不是declaredFunctionNames的元素,那么
          1. 让vnDefinable作为 envRec.CanDeclareGlobalVar(VN)的结果。
          2. 如果vnDefinable为false,则引发TypeError异常。
          3. 如果vn不是declaredVarNames的元素,那么
            1. 将vn附加到declaredVarNames。
  13. 注意:如果全局对象是普通对象,则在此算法步骤之后不会发生异常终止。但是,如果全局对象是代理非普通对象,则可能会显示在以下某些步骤中导致异常终止的行为。
  14. 注:附件B.3.3.2在这一点上增加了额外的步骤。
  15. 让lexDeclarations成为脚本的LexicalScopedDeclarations。
  16. 对于lexDeclarations中的每个元素d来说
    1. 注释词法声明的名称只在这里实例化,但未初始化。
    2. 对于d的BoundNames的每个元素dn
      1. 如果d的IsConstantDeclaration是true,那么
        1. 执行 envRec.CreateImmutableBinding(dn,true)。
      2. 否则
        1. 执行 envRec.CreateMutableBinding(dn,false)。
  17. 对于函数ToInitialize中的每个生产函数,都这样做
    1. 让fn成为f的BoundNames的唯一元素。
    2. 假设是使用参数env为f执行InstantiateFunctionObject的结果。
    3. 执行envRec.CreateGlobalFunctionBinding(fn,fo,false)。
  18. 对于declaredVarNames中的每个String vn,按列表顺序执行
    1. 执行envRec.CreateGlobalVarBinding(vn,false)。
  19. 返回NormalCompletion(empty)。
Note 2

Early errors specified in 15.1.1 prevent name conflicts between function/var declarations and let/const/class declarations as well as redeclaration of let/const/class bindings for declaration contained within a single Script. However, such conflicts and redeclarations that span more than one Script are detected as runtime errors during GlobalDeclarationInstantiation. If any such errors are detected, no bindings are instantiated for the script. However, if the global object is defined using Proxy exotic objects then the runtime tests for conflicting declarations may be unreliable resulting in an abrupt completion and some global declarations not being instantiated. If this occurs, the code for the Script is not evaluated.

在15.1.1中指定的早期错误可以防止函数/var声明和let/const/class声明之间的名称冲突,以及为单个脚本中包含的声明重新声明let / const / class绑定。 但是,GlobalDeclarationInstantiation期间,跨越多个脚本的冲突和重新声明被检测为运行时错误。 如果检测到任何此类错误,则不会为该脚本实例化绑定。 但是,如果使用代理非普通对象定义全局对象,那么运行时测试冲突声明可能是不可靠的,可能导致突然完成,并且一些全局声明没有被实例化。 如果发生这种情况,则不执行脚本的代码。

Unlike explicit var or function declarations, properties that are directly created on the global object result in global bindings that may be shadowed by let/const/class declarations.

与显式的var或函数声明不同,在全局绑定中,全局对象上直接创建的属性可能被let / const / class声明隐藏

window.glo1 = 7; let glo1 = 8; console.log(glo1); 8

15.1.12Runtime Semantics: ScriptEvaluationJob ( sourceText, hostDefined )#

The job ScriptEvaluationJob with parameters sourceText and hostDefined parses, validates, and evaluates sourceText as a Script.

具有参数sourceText和hostDefined的ScriptEvaluationJob作业,验证和执行sourceText作为脚本。

  1. Assert: sourceText is an ECMAScript source text (see clause 10).
  2. Let realm be the current Realm Record.
  3. Let s be ParseScript(sourceText, realm, hostDefined).
  4. If s is a List of errors, then
    1. Perform HostReportErrors(s).
    2. NextJob NormalCompletion(undefined).
  5. Let status be ScriptEvaluation(s).
  6. NextJob Completion(status).

15.2Modules(模块)#

Syntax(语法)

Module:ModuleBodyopt ModuleBody:ModuleItemList ModuleItemList:ModuleItem ModuleItemListModuleItem ModuleItem:ImportDeclaration ExportDeclaration StatementListItem

15.2.1Module Semantics(模块语义)#

15.2.1.1Static Semantics: Early Errors#

ModuleBody:ModuleItemList
  • It is a Syntax Error if the LexicallyDeclaredNames of ModuleItemList contains any duplicate entries.
  • It is a Syntax Error if any element of the LexicallyDeclaredNames of ModuleItemList also occurs in the VarDeclaredNames of ModuleItemList.
  • It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries.
  • It is a Syntax Error if any element of the ExportedBindings of ModuleItemList does not also occur in either the VarDeclaredNames of ModuleItemList, or the LexicallyDeclaredNames of ModuleItemList.
  • It is a Syntax Error if ModuleItemList contains super.
  • It is a Syntax Error if ModuleItemList contains NewTarget.
  • It is a Syntax Error if ContainsDuplicateLabels of ModuleItemList with argument « » is true.
  • It is a Syntax Error if ContainsUndefinedBreakTarget of ModuleItemList with argument « » is true.
  • It is a Syntax Error if ContainsUndefinedContinueTarget of ModuleItemList with arguments « » and « » is true.
  • 如果ModuleItemList的LexicallyDeclaredNames包含任何重复的条目,则它是一个语法错误。
  • 如果ModuleItemList的LexicallyDeclaredNames的任何元素也出现在ModuleItemList的VarDeclaredNames中,那么这是一个语法错误。
  • 如果ModuleItemList的ExportedNames包含任何重复的条目,则它是一个语法错误。
  • 如果ModuleItemList的ExportedBindings的任何元素都不出现在ModuleItemList的VarDeclaredNames或ModuleItemList的LexicallyDeclaredNames中,则这是一个语法错误。
  • 如果ModuleItemList包含super,则它是一个语法错误。
  • 如果ModuleItemList包含NewTarget,则它是一个语法错误。
  • 如果带有参数«»的ModuleItemList的ContainsDuplicateLabels为真,则它是一个语法错误。
  • 如果带有参数«»的ModuleItemList的ContainsUndefinedBreakTarget为true,那么它是一个语法错误。
  • 如果带有参数«»和«»的ModuleItemList的ContainsUndefinedContinueTarget为true,那么这是一个语法错误。
Note

The duplicate ExportedNames rule implies that multiple export default ExportDeclaration items within a ModuleBody is a Syntax Error. Additional error conditions relating to conflicting or duplicate declarations are checked during module linking prior to evaluation of a Module. If any such errors are detected the Module is not evaluated.

重复的ExportedNames规则意味着ModuleBody中的多个导出默认ExportDeclaration项是一个语法错误。 在模块执行之前的模块链接期间,会检查与冲突或重复声明有关的其他错误条件。 如果检测到这样的错误,模块将不被执行。

15.2.1.2Static Semantics: ContainsDuplicateLabels#

With argument labelSet.

ModuleItemList:ModuleItemListModuleItem
  1. Let hasDuplicates be ContainsDuplicateLabels of ModuleItemList with argument labelSet.
  2. If hasDuplicates is true, return true.
  3. Return ContainsDuplicateLabels of ModuleItem with argument labelSet.
ModuleItem:ImportDeclaration ExportDeclaration
  1. Return false.

15.2.1.3Static Semantics: ContainsUndefinedBreakTarget#

With argument labelSet.

ModuleItemList:ModuleItemListModuleItem
  1. Let hasUndefinedLabels be ContainsUndefinedBreakTarget of ModuleItemList with argument labelSet.
  2. If hasUndefinedLabels is true, return true.
  3. Return ContainsUndefinedBreakTarget of ModuleItem with argument labelSet.
ModuleItem:ImportDeclaration ExportDeclaration
  1. Return false.

15.2.1.4Static Semantics: ContainsUndefinedContinueTarget#

With arguments iterationSet and labelSet.

ModuleItemList:ModuleItemListModuleItem
  1. Let hasUndefinedLabels be ContainsUndefinedContinueTarget of ModuleItemList with arguments iterationSet and « ».
  2. If hasUndefinedLabels is true, return true.
  3. Return ContainsUndefinedContinueTarget of ModuleItem with arguments iterationSet and « ».
ModuleItem:ImportDeclaration ExportDeclaration
  1. Return false.

15.2.1.5Static Semantics: ExportedBindings#

Note

ExportedBindings are the locally bound names that are explicitly associated with a Module's ExportedNames.

ExportedBindings是与模块的ExportedNames显式关联的本地绑定名称。

ModuleItemList:ModuleItemListModuleItem
  1. Let names be ExportedBindings of ModuleItemList.
  2. Append to names the elements of the ExportedBindings of ModuleItem.
  3. Return names.
ModuleItem:ImportDeclaration StatementListItem
  1. Return a new empty List.

15.2.1.6Static Semantics: ExportedNames#

Note

ExportedNames are the externally visible names that a Module explicitly maps to one of its local name bindings.

ExportedNames是Module明确映射到其本地名称绑定之一的外部可见名称。

ModuleItemList:ModuleItemListModuleItem
  1. Let names be ExportedNames of ModuleItemList.
  2. Append to names the elements of the ExportedNames of ModuleItem.
  3. Return names.
ModuleItem:ExportDeclaration
  1. Return the ExportedNames of ExportDeclaration.
ModuleItem:ImportDeclaration StatementListItem
  1. Return a new empty List.

15.2.1.7Static Semantics: ExportEntries#

Module:[empty]
  1. Return a new empty List.
ModuleItemList:ModuleItemListModuleItem
  1. Let entries be ExportEntries of ModuleItemList.
  2. Append to entries the elements of the ExportEntries of ModuleItem.
  3. Return entries.
ModuleItem:ImportDeclaration StatementListItem
  1. Return a new empty List.

15.2.1.8Static Semantics: ImportEntries#

Module:[empty]
  1. Return a new empty List.
ModuleItemList:ModuleItemListModuleItem
  1. Let entries be ImportEntries of ModuleItemList.
  2. Append to entries the elements of the ImportEntries of ModuleItem.
  3. Return entries.
ModuleItem:ExportDeclaration StatementListItem
  1. Return a new empty List.

15.2.1.9Static Semantics: ImportedLocalNames ( importEntries )#

The abstract operation ImportedLocalNames with argument importEntries creates a List of all of the local name bindings defined by a List of ImportEntry Records (see Table 40). ImportedLocalNames performs the following steps:

  1. Let localNames be a new empty List.
  2. For each ImportEntry Record i in importEntries, do
    1. Append i.[[LocalName]] to localNames.
  3. Return localNames.

15.2.1.10Static Semantics: ModuleRequests#

Module:[empty]
  1. Return a new empty List.
ModuleItemList:ModuleItem
  1. Return ModuleRequests of ModuleItem.
ModuleItemList:ModuleItemListModuleItem
  1. Let moduleNames be ModuleRequests of ModuleItemList.
  2. Let additionalNames be ModuleRequests of ModuleItem.
  3. Append to moduleNames each element of additionalNames that is not already an element of moduleNames.
  4. Return moduleNames.
ModuleItem:StatementListItem
  1. Return a new empty List.

15.2.1.11Static Semantics: LexicallyDeclaredNames#

Note 1

The LexicallyDeclaredNames of a Module includes the names of all of its imported bindings.

ModuleItemList:ModuleItemListModuleItem
  1. Let names be LexicallyDeclaredNames of ModuleItemList.
  2. Append to names the elements of the LexicallyDeclaredNames of ModuleItem.
  3. Return names.
ModuleItem:ImportDeclaration
  1. Return the BoundNames of ImportDeclaration.
ModuleItem:ExportDeclaration
  1. If ExportDeclaration is export VariableStatement, return a new empty List.
  2. Return the BoundNames of ExportDeclaration.
ModuleItem:StatementListItem
  1. Return LexicallyDeclaredNames of StatementListItem.
Note 2

At the top level of a Module, function declarations are treated like lexical declarations rather than like var declarations.

15.2.1.12Static Semantics: LexicallyScopedDeclarations#

Module:[empty]
  1. Return a new empty List.
ModuleItemList:ModuleItemListModuleItem
  1. Let declarations be LexicallyScopedDeclarations of ModuleItemList.
  2. Append to declarations the elements of the LexicallyScopedDeclarations of ModuleItem.
  3. Return declarations.
ModuleItem:ImportDeclaration
  1. Return a new empty List.

15.2.1.13Static Semantics: VarDeclaredNames#

Module:[empty]
  1. Return a new empty List.
ModuleItemList:ModuleItemListModuleItem
  1. Let names be VarDeclaredNames of ModuleItemList.
  2. Append to names the elements of the VarDeclaredNames of ModuleItem.
  3. Return names.
ModuleItem:ImportDeclaration
  1. Return a new empty List.
ModuleItem:ExportDeclaration
  1. If ExportDeclaration is export VariableStatement, return BoundNames of ExportDeclaration.
  2. Return a new empty List.

15.2.1.14Static Semantics: VarScopedDeclarations#

Module:[empty]
  1. Return a new empty List.
ModuleItemList:ModuleItemListModuleItem
  1. Let declarations be VarScopedDeclarations of ModuleItemList.
  2. Append to declarations the elements of the VarScopedDeclarations of ModuleItem.
  3. Return declarations.
ModuleItem:ImportDeclaration
  1. Return a new empty List.
ModuleItem:ExportDeclaration
  1. If ExportDeclaration is export VariableStatement, return VarScopedDeclarations of VariableStatement.
  2. Return a new empty List.

15.2.1.15Abstract Module Records(抽象模块记录)#

A Module Record encapsulates structural information about the imports and exports of a single module. This information is used to link the imports and exports of sets of connected modules. A Module Record includes four fields that are only used when evaluating a module.

For specification purposes Module Record values are values of the Record specification type and can be thought of as existing in a simple object-oriented hierarchy where Module Record is an abstract class with concrete subclasses. This specification only defines a single Module Record concrete subclass named Source Text Module Record. Other specifications and implementations may define additional Module Record subclasses corresponding to alternative module definition facilities that they defined.

Module Record defines the fields listed in Table 37. All Module Definition subclasses include at least those fields. Module Record also defines the abstract method list in Table 38. All Module definition subclasses must provide concrete implementations of these abstract methods.

模块记录封装有关单个模块的导入和导出的结构信息。此信息用于链接已连接模块集的导入和导出。模块记录包括仅在执行模块时使用的四个字段。
出于规范目的,模块记录值是记录规范类型的值,可以认为是存在于简单的面向对象的层次结构中,其中模块记录是具有具体子类的抽象类。此规范仅定义了名为Source Text Module Record的单个Module Record具体子类。其他规范和实现可以定义与它们定义的替代模块定义工具相对应的附加模块记录子类。
模块记录定义表37中列出的字段。所有模块定义子类至少包括那些字段。模块记录还定义了表38中的抽象方法列表。所有模块定义子类必须提供这些抽象方法的具体实现。

Table 37: Module Record Fields
Field Name Value Type Meaning
[[Realm]] Realm Record | undefined The Realm within which this module was created. undefined if not yet assigned.
创建此模块的领域。 如果尚未分配,则为undefined。
[[Environment]] Lexical Environment | undefined The Lexical Environment containing the top level bindings for this module. This field is set when the module is instantiated.
Lexical Environment包含此模块的顶级绑定。 在实例化模块时设置此字段。
[[Namespace]] Object | undefined The Module Namespace Object (26.3) if one has been created for this module. Otherwise undefined.
模块命名空间对象(26.3)(如果已为此模块创建了一个)。 否则为undefined。
[[Evaluated]] Boolean Initially false, true if evaluation of this module has started. Remains true when evaluation completes, even if it is an abrupt completion.
最初为false,如果已开始执行模块,则为true。 执行完成时仍然为true,即使它是突然完成。
[[HostDefined]] Any, default value is undefined. Field reserved for use by host environments that need to associate additional information with a module.
用于需要将附加信息与模块相关联的host环境使用的保留字段。
Table 38: Abstract Methods of Module Records(模块记录的抽象方法)
Method Purpose
GetExportedNames(exportStarSet) Return a list of all names that are either directly or indirectly exported from this module.
返回直接或间接从此模块导出的所有名称的列表。
ResolveExport(exportName, resolveSet, exportStarSet) Return the binding of a name exported by this module. Bindings are represented by a Record of the form {[[Module]]: Module Record, [[BindingName]]: String}
返回此模块导出的名称的绑定。 绑定是一条记录形如:{[[Module]]: Module Record, [[BindingName]]: String}
ModuleDeclarationInstantiation() Transitively resolve all module dependencies and create a module Environment Record for the module.
传递性地解析所有模块依赖关系并为模块创建模块环境记录。
ModuleEvaluation()

Do nothing if this module has already been evaluated. Otherwise, transitively evaluate all module dependences of this module and then evaluate this module.

ModuleDeclarationInstantiation must be completed prior to invoking this method.


如果此模块已经执行,则不执行任何操作。 否则,传递性地评执行模块的所有模块依赖性,然后执行该模块。必须在调用此方法之前完成ModuleDeclarationInstantiation。

15.2.1.16Source Text Module Records(源文本模块记录)#

A Source Text Module Record is used to represent information about a module that was defined from ECMAScript source text (10) that was parsed using the goal symbol Module. Its fields contain digested information about the names that are imported by the module and its concrete methods use this digest to link, instantiate, and evaluate the module.

In addition to the fields, defined in Table 37, Source Text Module Records have the additional fields listed in Table 39. Each of these fields initially has the value undefined.

源文本模块记录用于表示有关使用目标符号模块解析的ECMAScript源文本(10)中定义的模块的信息。 其字段包含有关模块导入的名称的消化信息,其具体方法使用此摘要链接,实例化和执行模块。除了表37中定义的字段外,源文本模块记录还具有表39中列出的其他字段。每个字段最初值都是undefined。

Table 39: Additional Fields of Source Text Module Records(源文本模块记录的其他字段)
Field Name Value Type Meaning
[[ECMAScriptCode]] a parse result The result of parsing the source text of this module using Module as the goal symbol.
使用Module作为目标符号解析此模块的源文本的结果。
[[RequestedModules]] List of String A List of all the ModuleSpecifier strings used by the module represented by this record to request the importation of a module. The List is source code occurrence ordered.
此记录表示模块使用的所有ModuleSpecifier字符串的列表,用于请求导入模块。 List是已排序的源代码。
[[ImportEntries]] List of ImportEntry Records A List of ImportEntry records derived from the code of this module.
从此模块的代码派生的ImportEntry记录的列表。
[[LocalExportEntries]] List of ExportEntry Records A List of ExportEntry records derived from the code of this module that correspond to declarations that occur within the module.
从此模块的代码派生的ExportEntry记录列表,对应于模块中发生的声明。
[[IndirectExportEntries]] List of ExportEntry Records A List of ExportEntry records derived from the code of this module that correspond to reexported imports that occur within the module.
从此模块的代码派生的ExportEntry记录列表,对应于模块中出现的重新导出的导入。
[[StarExportEntries]] List of ExportEntry Records A List of ExportEntry records derived from the code of this module that correspond to export * declarations that occur within the module.
从此模块的代码派生的ExportEntry记录列表,对应于模块中出现的export *声明。

An ImportEntry Record is a Record that digests information about a single declarative import. Each ImportEntry Record has the fields defined in Table 40:

ImportEntry Record是一个记录,用于摘要有关单个声明性导入的信息。 每个ImportEntry Record都有表40中定义的字段:

Table 40: ImportEntry Record Fields(ImportEntry记录字段)
Field Name Value Type Meaning
[[ModuleRequest]] String String value of the ModuleSpecifier of the ImportDeclaration.
导入声明的ModuleSpecifier的字符串值。
[[ImportName]] String The name under which the desired binding is exported by the module identified by [[ModuleRequest]]. The value "*" indicates that the import request is for the target module's namespace object.
由[[ModuleRequest]]标识的模块导出所需绑定的名称。 值“*”表示导入请求是针对目标模块的命名空间对象的。
[[LocalName]] String The name that is used to locally access the imported value from within the importing module.
本地访问导入模块导入值的名称。
Note 1

Table 41 gives examples of ImportEntry records fields used to represent the syntactic import forms:

表41给出了用于表示语法import格式的ImportEntry记录字段的示例:

Table 41 (Informative): Import Forms Mappings to ImportEntry Records
Import Statement Form
import语句格式
[[ModuleRequest]] [[ImportName]] [[LocalName]]
import v from "mod"; "mod" "default" "v"
import * as ns from "mod"; "mod" "*" "ns"
import {x} from "mod"; "mod" "x" "x"
import {x as v} from "mod"; "mod" "x" "v"
import "mod"; An ImportEntry Record is not created.
未创建ImportEntry记录。

An ExportEntry Record is a Record that digests information about a single declarative export. Each ExportEntry Record has the fields defined in Table 42:

ExportEntry Record是一个记录,用于摘要有关单个声明性导出的信息。 每个ExportEntry Record都有表42中定义的字段:

Table 42: ExportEntry Record Fields
Field Name Value Type Meaning
[[ExportName]] String The name used to export this binding by this module.
用于通过此模块导出此绑定的名称。
[[ModuleRequest]] String | null The String value of the ModuleSpecifier of the ExportDeclaration. null if the ExportDeclaration does not have a ModuleSpecifier.
ExportDeclaration的ModuleSpecifier的String值。 如果ExportDeclaration没有ModuleSpecifier,则返回null。
[[ImportName]] String | null The name under which the desired binding is exported by the module identified by [[ModuleRequest]]. null if the ExportDeclaration does not have a ModuleSpecifier. "*" indicates that the export request is for all exported bindings.
由[[ModuleRequest]]标识的模块导出所需绑定的名称。 如果ExportDeclaration没有ModuleSpecifier,则返回null。 “*”表示导出请求适用于所有导出的绑定。
[[LocalName]] String | null The name that is used to locally access the exported value from within the importing module. null if the exported value is not locally accessible from within the module.
用于从导入模块中本地访问导出值的名称。 如果无法从模块中本地访问导出的值,则返回null。
Note 2

Table 43 gives examples of the ExportEntry record fields used to represent the syntactic export forms:

表43给出了用于表示export语法格式的ExportEntry记录字段的示例:

Table 43 (Informative): Export Forms Mappings to ExportEntry Records(export格式映射到ExportEntry记录)
Export Statement Form
export语句格式
[[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" "*" null

The following definitions specify the required concrete methods and other abstract operations for Source Text Module Records

以下定义指定源文本模块记录所需的具体方法和其他抽象操作

15.2.1.16.1ParseModule ( sourceText, realm, hostDefined )#

The abstract operation ParseModule with arguments sourceText, realm, and hostDefined creates a Source Text Module Record based upon the result of parsing sourceText as a Module. ParseModule performs the following steps:

具有参数sourceText,realm和hostDefined的抽象操作ParseModule基于将sourceText解析为模块的结果创建源文本模块记录。 ParseModule执行以下步骤:

  1. Assert: sourceText is an ECMAScript source text (see clause 10).
  2. Parse sourceText using Module as the goal symbol and analyze the parse result for any Early Error conditions. If the parse was successful and no early errors were found, let body be the resulting parse tree. Otherwise, let body be a List of one or more SyntaxError or ReferenceError objects representing the parsing errors and/or early errors. Parsing and early error detection may be interweaved in an implementation dependent manner. If more than one parsing error or early error is present, the number and ordering of error objects in the list is implementation dependent, but at least one must be present.
  3. If body is a List of errors, then return body.
  4. Let requestedModules be the ModuleRequests of body.
  5. Let importEntries be ImportEntries of body.
  6. Let importedBoundNames be ImportedLocalNames(importEntries).
  7. Let indirectExportEntries be a new empty List.
  8. Let localExportEntries be a new empty List.
  9. Let starExportEntries be a new empty List.
  10. Let exportEntries be ExportEntries of body.
  11. For each record ee in exportEntries, do
    1. If ee.[[ModuleRequest]] is null, then
      1. If ee.[[LocalName]] is not an element of importedBoundNames, then
        1. Append ee to localExportEntries.
      2. Else,
        1. Let ie be the element of importEntries whose [[LocalName]] is the same as ee.[[LocalName]].
        2. If ie.[[ImportName]] is "*", then
          1. Assert: this is a re-export of an imported module namespace object.
          2. Append ee to localExportEntries.
        3. Else, this is a re-export of a single name
          1. Append to indirectExportEntries the Record {[[ModuleRequest]]: ie.[[ModuleRequest]], [[ImportName]]: ie.[[ImportName]], [[LocalName]]: null, [[ExportName]]: ee.[[ExportName]] }.
    2. Else, if ee.[[ImportName]] is "*", then
      1. Append ee to starExportEntries.
    3. Else,
      1. Append ee to indirectExportEntries.
  12. Return Source Text Module Record {[[Realm]]: realm, [[Environment]]: undefined, [[HostDefined]]: hostDefined, [[Namespace]]: undefined, [[Evaluated]]: false, [[ECMAScriptCode]]: body, [[RequestedModules]]: requestedModules, [[ImportEntries]]: importEntries, [[LocalExportEntries]]: localExportEntries, [[StarExportEntries]]: starExportEntries, [[IndirectExportEntries]]: indirectExportEntries}.
Note

An implementation may parse module source text and analyze it for Early Error conditions prior to the evaluation of ParseModule for that module source text. However, the reporting of any errors must be deferred until the point where this specification actually performs ParseModule upon that source text.

在执行该模块源文本的ParseModule之前,可以解析模块源文本并对其进行早期错误条件分析。 但是,必须推迟报告任何错误,直到该规范实际对该源文本执行ParseModule。

15.2.1.16.2GetExportedNames( exportStarSet ) Concrete Method(GetExportedNames具体方法)#

The GetExportedNames concrete method of a Source Text Module Record with argument exportStarSet performs the following steps:

具有参数exportStarSet的源文本模块记录的GetExportedNames具体方法执行以下步骤:

  1. Let module be this Source Text Module Record.
  2. If exportStarSet contains module, then
    1. Assert: We've reached the starting point of an import * circularity.
    2. Return a new empty List.
  3. Append module to exportStarSet.
  4. Let exportedNames be a new empty List.
  5. For each ExportEntry Record e in module.[[LocalExportEntries]], do
    1. Assert: module provides the direct binding for this export.
    2. Append e.[[ExportName]] to exportedNames.
  6. For each ExportEntry Record e in module.[[IndirectExportEntries]], do
    1. Assert: module imports a specific binding for this export.
    2. Append e.[[ExportName]] to exportedNames.
  7. For each ExportEntry Record e in module.[[StarExportEntries]], do
    1. Let requestedModule be ? HostResolveImportedModule(module, e.[[ModuleRequest]]).
    2. Let starNames be ? requestedModule.GetExportedNames(exportStarSet).
    3. For each element n of starNames, do
      1. If SameValue(n, "default") is false, then
        1. If n is not an element of exportedNames, then
          1. Append n to exportedNames.
  8. Return exportedNames.
Note

GetExportedNames does not filter out or throw an exception for names that have ambiguous star export bindings.

对于具有不明确的*导出绑定的名称,GetExportedNames不会过滤掉或抛出异常。

15.2.1.16.3ResolveExport( exportName, resolveSet, exportStarSet ) Concrete Method#

The ResolveExport concrete method of a Source Text Module Record with arguments exportName, resolveSet, and exportStarSet performs the following steps:

  1. Let module be this Source Text Module Record.
  2. For each Record {[[Module]], [[ExportName]]} r in resolveSet, do:
    1. If module and r.[[Module]] are the same Module Record and SameValue(exportName, r.[[ExportName]]) is true, then
      1. Assert: this is a circular import request.
      2. Return null.
  3. Append the Record {[[Module]]: module, [[ExportName]]: exportName} to resolveSet.
  4. For each ExportEntry Record e in module.[[LocalExportEntries]], do
    1. If SameValue(exportName, e.[[ExportName]]) is true, then
      1. Assert: module provides the direct binding for this export.
      2. Return Record{[[Module]]: module, [[BindingName]]: e.[[LocalName]]}.
  5. For each ExportEntry Record e in module.[[IndirectExportEntries]], do
    1. If SameValue(exportName, e.[[ExportName]]) is true, then
      1. Assert: module imports a specific binding for this export.
      2. Let importedModule be ? HostResolveImportedModule(module, e.[[ModuleRequest]]).
      3. Let indirectResolution be ? importedModule.ResolveExport(e.[[ImportName]], resolveSet, exportStarSet).
      4. If indirectResolution is not null, return indirectResolution.
  6. If SameValue(exportName, "default") is true, then
    1. Assert: A default export was not explicitly defined by this module.
    2. Throw a SyntaxError exception.
    3. NOTE A default export cannot be provided by an export *.
  7. If exportStarSet contains module, return null.
  8. Append module to exportStarSet.
  9. Let starResolution be null.
  10. For each ExportEntry Record e in module.[[StarExportEntries]], do
    1. Let importedModule be ? HostResolveImportedModule(module, e.[[ModuleRequest]]).
    2. Let resolution be ? importedModule.ResolveExport(exportName, resolveSet, exportStarSet).
    3. If resolution is "ambiguous", return "ambiguous".
    4. If resolution is not null, then
      1. If starResolution is null, let starResolution be resolution.
      2. Else,
        1. Assert: there is more than one * import that includes the requested name.
        2. If resolution.[[Module]] and starResolution.[[Module]] are not the same Module Record or SameValue(resolution.[[BindingName]], starResolution.[[BindingName]]) is false, return "ambiguous".
  11. Return starResolution.
Note

ResolveExport attempts to resolve an imported binding to the actual defining module and local binding name. The defining module may be the module represented by the Module Record this method was invoked on or some other module that is imported by that module. The parameter resolveSet is use to detect unresolved circular import/export paths. If a pair consisting of specific Module Record and exportName is reached that is already in resolveSet, an import circularity has been encountered. Before recursively calling ResolveExport, a pair consisting of module and exportName is added to resolveSet.

If a defining module is found a Record {[[Module]], [[BindingName]]} is returned. This record identifies the resolved binding of the originally requested export. If no definition was found or the request is found to be circular, null is returned. If the request is found to be ambiguous, the string "ambiguous" is returned.

ResolveExport尝试解析导入的绑定到实际的定义模块和本地绑定名称。 定义模块可以是由调用此方法的模块记录表示的模块或由该模块导入的某个其他模块。 参数resolveSet用于检测未解析的循环导入/导出路径。 如果到达已包含在resolveSet中的特定Module Record和exportName的对,则遇到导入循环。 在递归调用ResolveExport之前,会将一个由module和exportName组成的对添加到resolveSet。
如果找到定义模块,则返回Record {[[Module]],[[BindingName]]}。 此记录标识最初请求的导出的已解析绑定。 如果未找到定义或发现请求为循环,则返回null。 如果发现请求不明确,则返回字符串“ambiguous”。

15.2.1.16.4ModuleDeclarationInstantiation( ) Concrete Method#

The ModuleDeclarationInstantiation concrete method of a Source Text Module Record performs the following steps:

  1. Let module be this Source Text Module Record.
  2. Let realm be module.[[Realm]].
  3. Assert: realm is not undefined.
  4. Let code be module.[[ECMAScriptCode]].
  5. If module.[[Environment]] is not undefined, return NormalCompletion(empty).
  6. Let env be NewModuleEnvironment(realm.[[GlobalEnv]]).
  7. Set module.[[Environment]] to env.
  8. For each String required that is an element of module.[[RequestedModules]] do,
    1. NOTE: Before instantiating a module, all of the modules it requested must be available. An implementation may perform this test at any time prior to this point.
    2. Let requiredModule be ? HostResolveImportedModule(module, required).
    3. Perform ? requiredModule.ModuleDeclarationInstantiation().
  9. For each ExportEntry Record e in module.[[IndirectExportEntries]], do
    1. Let resolution be ? module.ResolveExport(e.[[ExportName]], « », « »).
    2. If resolution is null or resolution is "ambiguous", throw a SyntaxError exception.
  10. Assert: all named exports from module are resolvable.
  11. Let envRec be env's EnvironmentRecord.
  12. For each ImportEntry Record in in module.[[ImportEntries]], do
    1. Let importedModule be ? HostResolveImportedModule(module, in.[[ModuleRequest]]).
    2. If in.[[ImportName]] is "*", then
      1. Let namespace be ? GetModuleNamespace(importedModule).
      2. Perform ! envRec.CreateImmutableBinding(in.[[LocalName]], true).
      3. Call envRec.InitializeBinding(in.[[LocalName]], namespace).
    3. Else,
      1. Let resolution be ? importedModule.ResolveExport(in.[[ImportName]], « », « »).
      2. If resolution is null or resolution is "ambiguous", throw a SyntaxError exception.
      3. Call envRec.CreateImportBinding(in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]).
  13. Let varDeclarations be the VarScopedDeclarations of code.
  14. Let declaredVarNames be a new empty List.
  15. For each element d in varDeclarations do
    1. For each element dn of the BoundNames of d do
      1. If dn is not an element of declaredVarNames, then
        1. Perform ! envRec.CreateMutableBinding(dn, false).
        2. Call envRec.InitializeBinding(dn, undefined).
        3. Append dn to declaredVarNames.
  16. Let lexDeclarations be the LexicallyScopedDeclarations of code.
  17. For each element d in lexDeclarations do
    1. For each element dn of the BoundNames of d do
      1. If IsConstantDeclaration of d is true, then
        1. Perform ! envRec.CreateImmutableBinding(dn, true).
      2. Else,
        1. Perform ! envRec.CreateMutableBinding(dn, false).
      3. If d is a GeneratorDeclaration production or a FunctionDeclaration production, then
        1. Let fo be the result of performing InstantiateFunctionObject for d with argument env.
        2. Call envRec.InitializeBinding(dn, fo).
  18. Return NormalCompletion(empty).

15.2.1.16.5ModuleEvaluation() Concrete Method#

The ModuleEvaluation concrete method of a Source Text Module Record performs the following steps:

  1. Let module be this Source Text Module Record.
  2. Assert: ModuleDeclarationInstantiation has already been invoked on module and successfully completed.
  3. Assert: module.[[Realm]] is not undefined.
  4. If module.[[Evaluated]] is true, return undefined.
  5. Set module.[[Evaluated]] to true.
  6. For each String required that is an element of module.[[RequestedModules]] do,
    1. Let requiredModule be ? HostResolveImportedModule(module, required).
    2. Perform ? requiredModule.ModuleEvaluation().
  7. Let moduleCxt be a new ECMAScript code execution context.
  8. Set the Function of moduleCxt to null.
  9. Set the Realm of moduleCxt to module.[[Realm]].
  10. Set the ScriptOrModule of moduleCxt to module.
  11. Assert: module has been linked and declarations in its module environment have been instantiated.
  12. Set the VariableEnvironment of moduleCxt to module.[[Environment]].
  13. Set the LexicalEnvironment of moduleCxt to module.[[Environment]].
  14. Suspend the currently running execution context.
  15. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
  16. Let result be the result of evaluating module.[[ECMAScriptCode]].
  17. Suspend moduleCxt and remove it from the execution context stack.
  18. Resume the context that is now on the top of the execution context stack as the running execution context.
  19. Return Completion(result).

15.2.1.17Runtime Semantics: HostResolveImportedModule (referencingModule, specifier )#

HostResolveImportedModule is an implementation defined abstract operation that provides the concrete Module Record subclass instance that corresponds to the ModuleSpecifier String, specifier, occurring within the context of the module represented by the Module Record referencingModule.

The implementation of HostResolveImportedModule must conform to the following requirements:

  • The normal return value must be an instance of a concrete subclass of Module Record.
  • If a Module Record corresponding to the pair referencingModule, specifier does not exist or cannot be created, an exception must be thrown.
  • This operation must be idempotent if it completes normally. Each time it is called with a specific referencingModule, specifier pair as arguments it must return the same Module Record instance.

Multiple different referencingModule, specifier pairs may map to the same Module Record instance. The actual mapping semantic is implementation defined but typically a normalization process is applied to specifier as part of the mapping process. A typical normalization process would include actions such as alphabetic case folding and expansion of relative and abbreviated path specifiers.

15.2.1.18Runtime Semantics: GetModuleNamespace( module )#

The abstract operation GetModuleNamespace called with argument module performs the following steps:

  1. Assert: module is an instance of a concrete subclass of Module Record.
  2. Let namespace be module.[[Namespace]].
  3. If namespace is undefined, then
    1. Let exportedNames be ? module.GetExportedNames(« »).
    2. Let unambiguousNames be a new empty List.
    3. For each name that is an element of exportedNames,
      1. Let resolution be ? module.ResolveExport(name, « », « »).
      2. If resolution is null, throw a SyntaxError exception.
      3. If resolution is not "ambiguous", append name to unambiguousNames.
    4. Let namespace be ModuleNamespaceCreate(module, unambiguousNames).
  4. Return namespace.

15.2.1.19Runtime Semantics: TopLevelModuleEvaluationJob ( sourceText, hostDefined )#

A TopLevelModuleEvaluationJob with parameters sourceText and hostDefined is a job that parses, validates, and evaluates sourceText as a Module.

  1. Assert: sourceText is an ECMAScript source text (see clause 10).
  2. Let realm be the current Realm Record.
  3. Let m be ParseModule(sourceText, realm, hostDefined).
  4. If m is a List of errors, then
    1. Perform HostReportErrors(m).
    2. NextJob NormalCompletion(undefined).
  5. Let status be m.ModuleDeclarationInstantiation().
  6. If status is not an abrupt completion, then
    1. Assert: all dependencies of m have been transitively resolved and m is ready for evaluation.
    2. Let status be m.ModuleEvaluation().
  7. NextJob Completion(status).
Note

An implementation may parse a sourceText as a Module, analyze it for Early Error conditions, and instantiate it prior to the execution of the TopLevelModuleEvaluationJob for that sourceText. An implementation may also resolve, pre-parse and pre-analyze, and pre-instantiate module dependencies of sourceText. However, the reporting of any errors detected by these actions must be deferred until the TopLevelModuleEvaluationJob is actually executed.

15.2.1.20Runtime Semantics: Evaluation#

Module:[empty]
  1. Return NormalCompletion(undefined).
ModuleBody:ModuleItemList
  1. Let result be the result of evaluating ModuleItemList.
  2. If result.[[Type]] is normal and result.[[Value]] is empty, then
    1. Return NormalCompletion(undefined).
  3. Return Completion(result).
ModuleItemList:ModuleItemListModuleItem
  1. Let sl be the result of evaluating ModuleItemList.
  2. ReturnIfAbrupt(sl).
  3. Let s be the result of evaluating ModuleItem.
  4. Return Completion(UpdateEmpty(s, sl.[[Value]])).
Note

The value of a ModuleItemList is the value of the last value producing item in the ModuleItemList.

ModuleItem:ImportDeclaration
  1. Return NormalCompletion(empty).

15.2.2Imports#

Syntax

ImportDeclaration:importImportClauseFromClause; importModuleSpecifier; ImportClause:ImportedDefaultBinding NameSpaceImport NamedImports ImportedDefaultBinding,NameSpaceImport ImportedDefaultBinding,NamedImports ImportedDefaultBinding:ImportedBinding NameSpaceImport:*asImportedBinding NamedImports:{} {ImportsList} {ImportsList,} FromClause:fromModuleSpecifier ImportsList:ImportSpecifier ImportsList,ImportSpecifier ImportSpecifier:ImportedBinding IdentifierNameasImportedBinding ModuleSpecifier:StringLiteral ImportedBinding:BindingIdentifier

15.2.2.1Static Semantics: Early Errors#

ModuleItem:ImportDeclaration
  • It is a Syntax Error if the BoundNames of ImportDeclaration contains any duplicate entries.

15.2.2.2Static Semantics: BoundNames#

ImportDeclaration:importImportClauseFromClause;
  1. Return the BoundNames of ImportClause.
ImportDeclaration:importModuleSpecifier;
  1. Return a new empty List.
ImportClause:ImportedDefaultBinding,NameSpaceImport
  1. Let names be the BoundNames of ImportedDefaultBinding.
  2. Append to names the elements of the BoundNames of NameSpaceImport.
  3. Return names.
ImportClause:ImportedDefaultBinding,NamedImports
  1. Let names be the BoundNames of ImportedDefaultBinding.
  2. Append to names the elements of the BoundNames of NamedImports.
  3. Return names.
NamedImports:{}
  1. Return a new empty List.
ImportsList:ImportsList,ImportSpecifier
  1. Let names be the BoundNames of ImportsList.
  2. Append to names the elements of the BoundNames of ImportSpecifier.
  3. Return names.
ImportSpecifier:IdentifierNameasImportedBinding
  1. Return the BoundNames of ImportedBinding.

15.2.2.3Static Semantics: ImportEntries#

ImportDeclaration:importImportClauseFromClause;
  1. Let module be the sole element of ModuleRequests of FromClause.
  2. Return ImportEntriesForModule of ImportClause with argument module.
ImportDeclaration:importModuleSpecifier;
  1. Return a new empty List.

15.2.2.4Static Semantics: ImportEntriesForModule#

With parameter module.

ImportClause:ImportedDefaultBinding,NameSpaceImport
  1. Let entries be ImportEntriesForModule of ImportedDefaultBinding with argument module.
  2. Append to entries the elements of the ImportEntriesForModule of NameSpaceImport with argument module.
  3. Return entries.
ImportClause:ImportedDefaultBinding,NamedImports
  1. Let entries be ImportEntriesForModule of ImportedDefaultBinding with argument module.
  2. Append to entries the elements of the ImportEntriesForModule of NamedImports with argument module.
  3. Return entries.
ImportedDefaultBinding:ImportedBinding
  1. Let localName be the sole element of BoundNames of ImportedBinding.
  2. Let defaultEntry be the Record {[[ModuleRequest]]: module, [[ImportName]]: "default", [[LocalName]]: localName }.
  3. Return a new List containing defaultEntry.
NameSpaceImport:*asImportedBinding
  1. Let localName be the StringValue of ImportedBinding.
  2. Let entry be the Record {[[ModuleRequest]]: module, [[ImportName]]: "*", [[LocalName]]: localName }.
  3. Return a new List containing entry.
NamedImports:{}
  1. Return a new empty List.
ImportsList:ImportsList,ImportSpecifier
  1. Let specs be the ImportEntriesForModule of ImportsList with argument module.
  2. Append to specs the elements of the ImportEntriesForModule of ImportSpecifier with argument module.
  3. Return specs.
ImportSpecifier:ImportedBinding
  1. Let localName be the sole element of BoundNames of ImportedBinding.
  2. Let entry be the Record {[[ModuleRequest]]: module, [[ImportName]]: localName, [[LocalName]]: localName }.
  3. Return a new List containing entry.
ImportSpecifier:IdentifierNameasImportedBinding
  1. Let importName be the StringValue of IdentifierName.
  2. Let localName be the StringValue of ImportedBinding.
  3. Let entry be the Record {[[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName }.
  4. Return a new List containing entry.

15.2.2.5Static Semantics: ModuleRequests#

ImportDeclaration:importImportClauseFromClause;
  1. Return ModuleRequests of FromClause.
ModuleSpecifier:StringLiteral
  1. Return a List containing the StringValue of StringLiteral.

15.2.3Exports#

Syntax

ExportDeclaration:export*FromClause; exportExportClauseFromClause; exportExportClause; exportVariableStatement exportDeclaration exportdefaultHoistableDeclaration[Default] exportdefaultClassDeclaration[Default] exportdefault[lookahead ∉ { function, class }]AssignmentExpression[In]; ExportClause:{} {ExportsList} {ExportsList,} ExportsList:ExportSpecifier ExportsList,ExportSpecifier ExportSpecifier:IdentifierName IdentifierNameasIdentifierName

15.2.3.1Static Semantics: Early Errors#

ExportDeclaration:exportExportClause;
  • For each IdentifierName n in ReferencedBindings of ExportClause: It is a Syntax Error if StringValue of n is a ReservedWord or if the StringValue of n is one of: "implements", "interface", "let", "package", "private", "protected", "public", or "static".
Note

The above rule means that each ReferencedBindings of ExportClause is treated as an IdentifierReference.

15.2.3.2Static Semantics: BoundNames#

ExportDeclaration:export*FromClause; exportExportClauseFromClause; exportExportClause;
  1. Return a new empty List.
ExportDeclaration:exportVariableStatement
  1. Return the BoundNames of VariableStatement.
ExportDeclaration:exportDeclaration
  1. Return the BoundNames of Declaration.
ExportDeclaration:exportdefaultHoistableDeclaration
  1. Let declarationNames be the BoundNames of HoistableDeclaration.
  2. If declarationNames does not include the element "*default*", append "*default*" to declarationNames.
  3. Return declarationNames.
ExportDeclaration:exportdefaultClassDeclaration
  1. Let declarationNames be the BoundNames of ClassDeclaration.
  2. If declarationNames does not include the element "*default*", append "*default*" to declarationNames.
  3. Return declarationNames.
ExportDeclaration:exportdefaultAssignmentExpression;
  1. Return « "*default*" ».

15.2.3.3Static Semantics: ExportedBindings#

ExportDeclaration:exportExportClauseFromClause; export*FromClause;
  1. Return a new empty List.
ExportDeclaration:exportExportClause;
  1. Return the ExportedBindings of ExportClause.
ExportDeclaration:exportVariableStatement
  1. Return the BoundNames of VariableStatement.
ExportDeclaration:exportDeclaration
  1. Return the BoundNames of Declaration.
ExportDeclaration:exportdefaultHoistableDeclaration ExportDeclaration:exportdefaultClassDeclaration ExportDeclaration:exportdefaultAssignmentExpression;
  1. Return the BoundNames of this ExportDeclaration.
ExportClause:{}
  1. Return a new empty List.
ExportsList:ExportsList,ExportSpecifier
  1. Let names be the ExportedBindings of ExportsList.
  2. Append to names the elements of the ExportedBindings of ExportSpecifier.
  3. Return names.
ExportSpecifier:IdentifierName
  1. Return a List containing the StringValue of IdentifierName.
ExportSpecifier:IdentifierNameasIdentifierName
  1. Return a List containing the StringValue of the first IdentifierName.

15.2.3.4Static Semantics: ExportedNames#

ExportDeclaration:export*FromClause;
  1. Return a new empty List.
ExportDeclaration:exportExportClauseFromClause; exportExportClause;
  1. Return the ExportedNames of ExportClause.
ExportDeclaration:exportVariableStatement
  1. Return the BoundNames of VariableStatement.
ExportDeclaration:exportDeclaration
  1. Return the BoundNames of Declaration.
ExportDeclaration:exportdefaultHoistableDeclaration ExportDeclaration:exportdefaultClassDeclaration ExportDeclaration:exportdefaultAssignmentExpression;
  1. Return « "default" ».
ExportClause:{}
  1. Return a new empty List.
ExportsList:ExportsList,ExportSpecifier
  1. Let names be the ExportedNames of ExportsList.
  2. Append to names the elements of the ExportedNames of ExportSpecifier.
  3. Return names.
ExportSpecifier:IdentifierName
  1. Return a List containing the StringValue of IdentifierName.
ExportSpecifier:IdentifierNameasIdentifierName
  1. Return a List containing the StringValue of the second IdentifierName.

15.2.3.5Static Semantics: ExportEntries#

ExportDeclaration:export*FromClause;
  1. Let module be the sole element of ModuleRequests of FromClause.
  2. Let entry be the Record {[[ModuleRequest]]: module, [[ImportName]]: "*", [[LocalName]]: null, [[ExportName]]: null }.
  3. Return a new List containing entry.
ExportDeclaration:exportExportClauseFromClause;
  1. Let module be the sole element of ModuleRequests of FromClause.
  2. Return ExportEntriesForModule of ExportClause with argument module.
ExportDeclaration:exportExportClause;
  1. Return ExportEntriesForModule of ExportClause with argument null.
ExportDeclaration:exportVariableStatement
  1. Let entries be a new empty List.
  2. Let names be the BoundNames of VariableStatement.
  3. Repeat for each name in names,
    1. Append to entries the Record {[[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name }.
  4. Return entries.
ExportDeclaration:exportDeclaration
  1. Let entries be a new empty List.
  2. Let names be the BoundNames of Declaration.
  3. Repeat for each name in names,
    1. Append to entries the Record {[[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name }.
  4. Return entries.
ExportDeclaration:exportdefaultHoistableDeclaration
  1. Let names be BoundNames of HoistableDeclaration.
  2. Let localName be the sole element of names.
  3. Return a new List containing the Record {[[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default"}.
ExportDeclaration:exportdefaultClassDeclaration
  1. Let names be BoundNames of ClassDeclaration.
  2. Let localName be the sole element of names.
  3. Return a new List containing the Record {[[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default"}.
ExportDeclaration:exportdefaultAssignmentExpression;
  1. Let entry be the Record {[[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: "*default*", [[ExportName]]: "default"}.
  2. Return a new List containing entry.
Note

"*default*" is used within this specification as a synthetic name for anonymous default export values.

15.2.3.6Static Semantics: ExportEntriesForModule#

With parameter module.

ExportClause:{}
  1. Return a new empty List.
ExportsList:ExportsList,ExportSpecifier
  1. Let specs be the ExportEntriesForModule of ExportsList with argument module.
  2. Append to specs the elements of the ExportEntriesForModule of ExportSpecifier with argument module.
  3. Return specs.
ExportSpecifier:IdentifierName
  1. Let sourceName be the StringValue of IdentifierName.
  2. If module is null, then
    1. Let localName be sourceName.
    2. Let importName be null.
  3. Else,
    1. Let localName be null.
    2. Let importName be sourceName.
  4. Return a new List containing the Record {[[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: sourceName }.
ExportSpecifier:IdentifierNameasIdentifierName
  1. Let sourceName be the StringValue of the first IdentifierName.
  2. Let exportName be the StringValue of the second IdentifierName.
  3. If module is null, then
    1. Let localName be sourceName.
    2. Let importName be null.
  4. Else,
    1. Let localName be null.
    2. Let importName be sourceName.
  5. Return a new List containing the Record {[[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: exportName }.

15.2.3.7Static Semantics: IsConstantDeclaration#

ExportDeclaration:export*FromClause; exportExportClauseFromClause; exportExportClause; exportdefaultAssignmentExpression;
  1. Return false.
Note

It is not necessary to treat export default AssignmentExpression as a constant declaration because there is no syntax that permits assignment to the internal bound name used to reference a module's default object.

15.2.3.8Static Semantics: LexicallyScopedDeclarations#

ExportDeclaration:export*FromClause; exportExportClauseFromClause; exportExportClause; exportVariableStatement
  1. Return a new empty List.
ExportDeclaration:exportDeclaration
  1. Return a new List containing DeclarationPart of Declaration.
ExportDeclaration:exportdefaultHoistableDeclaration
  1. Return a new List containing DeclarationPart of HoistableDeclaration.
ExportDeclaration:exportdefaultClassDeclaration
  1. Return a new List containing ClassDeclaration.
ExportDeclaration:exportdefaultAssignmentExpression;
  1. Return a new List containing this ExportDeclaration.

15.2.3.9Static Semantics: ModuleRequests#

ExportDeclaration:export*FromClause; ExportDeclaration:exportExportClauseFromClause;
  1. Return the ModuleRequests of FromClause.
ExportDeclaration:exportExportClause; exportVariableStatement exportDeclaration exportdefaultHoistableDeclaration exportdefaultClassDeclaration exportdefaultAssignmentExpression;
  1. Return a new empty List.

15.2.3.10Static Semantics: ReferencedBindings#

ExportClause:{}
  1. Return a new empty List.
ExportsList:ExportsList,ExportSpecifier
  1. Let names be the ReferencedBindings of ExportsList.
  2. Append to names the elements of the ReferencedBindings of ExportSpecifier.
  3. Return names.
ExportSpecifier:IdentifierName
  1. Return a List containing the IdentifierName.
ExportSpecifier:IdentifierNameasIdentifierName
  1. Return a List containing the first IdentifierName.

15.2.3.11Runtime Semantics: Evaluation#

ExportDeclaration:export*FromClause; exportExportClauseFromClause; exportExportClause;
  1. Return NormalCompletion(empty).
ExportDeclaration:exportVariableStatement
  1. Return the result of evaluating VariableStatement.
ExportDeclaration:exportDeclaration
  1. Return the result of evaluating Declaration.
ExportDeclaration:exportdefaultHoistableDeclaration
  1. Return the result of evaluating HoistableDeclaration.
ExportDeclaration:exportdefaultClassDeclaration
  1. Let value be the result of BindingClassDeclarationEvaluation of ClassDeclaration.
  2. ReturnIfAbrupt(value).
  3. Let className be the sole element of BoundNames of ClassDeclaration.
  4. If className is "*default*", then
    1. Let hasNameProperty be ? HasOwnProperty(value, "name").
    2. If hasNameProperty is false, perform SetFunctionName(value, "default").
    3. Let env be the running execution context's LexicalEnvironment.
    4. Perform ? InitializeBoundName("*default*", value, env).
  5. Return NormalCompletion(empty).
ExportDeclaration:exportdefaultAssignmentExpression;
  1. Let rhs be the result of evaluating AssignmentExpression.
  2. Let value be ? GetValue(rhs).
  3. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
    1. Let hasNameProperty be ? HasOwnProperty(value, "name").
    2. If hasNameProperty is false, perform SetFunctionName(value, "default").
  4. Let env be the running execution context's LexicalEnvironment.
  5. Perform ? InitializeBoundName("*default*", value, env).
  6. Return NormalCompletion(empty).

16Error Handling and Language Extensions#

An implementation must report most errors at the time the relevant ECMAScript language construct is evaluated. An early error is an error that can be detected and reported prior to the evaluation of any construct in the Script containing the error. The presence of an early error prevents the evaluation of the construct. An implementation must report early errors in a Script as part of parsing that Script in ParseScript. Early errors in a Module are reported at the point when the Module would be evaluated and the Module is never initialized. Early errors in eval code are reported at the time eval is called and prevent evaluation of the eval code. All errors that are not early errors are runtime errors.

An implementation must report as an early error any occurrence of a condition that is listed in a “Static Semantics: Early Errors” subclause of this specification.

An implementation shall not treat other kinds of errors as early errors even if the compiler can prove that a construct cannot execute without error under any circumstances. An implementation may issue an early warning in such a case, but it should not report the error until the relevant construct is actually executed.

An implementation shall report all errors as specified, except for the following:

An implementation may define behaviour other than throwing RangeError for toFixed, toExponential, and toPrecision when the fractionDigits or precision argument is outside the specified range.

16.1HostReportErrors ( errorList )#

HostReportErrors is an implementation-defined abstract operation that allows host environments to report parsing errors, early errors, and runtime errors.

An implementation of HostReportErrors must complete normally in all cases. The default implementation of HostReportErrors is to do nothing.

Note

errorList will be a List of ECMAScript language values. If the errors are parsing errors or early errors, these will always be SyntaxError or ReferenceError objects. Runtime errors, however, can be any ECMAScript value.

16.2Forbidden Extensions#

An implementation must not extend this specification in the following ways:

17ECMAScript Standard Built-in Objects#

There are certain built-in objects available whenever an ECMAScript Script or Module begins execution. One, the global object, is part of the lexical environment of the executing program. Others are accessible as initial properties of the global object or indirectly as properties of accessible built-in objects.

Unless specified otherwise, a built-in object that is callable as a function is a built-in Function object with the characteristics described in 9.3. Unless specified otherwise, the [[Extensible]] internal slot of a built-in object initially has the value true. Every built-in Function object has a [[Realm]] internal slot whose value is the Realm Record of the realm for which the object was initially created.

Many built-in objects are functions: they can be invoked with arguments. Some of them furthermore are constructors: they are functions intended for use with the new operator. For each built-in function, this specification describes the arguments required by that function and the properties of that function object. For each built-in constructor, this specification furthermore describes properties of the prototype object of that constructor and properties of specific object instances returned by a new expression that invokes that constructor.

Unless otherwise specified in the description of a particular function, if a built-in function or constructor is given fewer arguments than the function is specified to require, the function or constructor shall behave exactly as if it had been given sufficient additional arguments, each such argument being the undefined value. Such missing arguments are considered to be “not present” and may be identified in that manner by specification algorithms. In the description of a particular function, the terms “this value” and “NewTarget” have the meanings given in 9.3.

Unless otherwise specified in the description of a particular function, if a built-in function or constructor described is given more arguments than the function is specified to allow, the extra arguments are evaluated by the call and then ignored by the function. However, an implementation may define implementation specific behaviour relating to such arguments as long as the behaviour is not the throwing of a TypeError exception that is predicated simply on the presence of an extra argument.

Note 1

Implementations that add additional capabilities to the set of built-in functions are encouraged to do so by adding new functions rather than adding new parameters to existing functions.

Unless otherwise specified every built-in function and every built-in constructor has the Function prototype object, which is the initial value of the expression Function.prototype (19.2.3), as the value of its [[Prototype]] internal slot.

Unless otherwise specified every built-in prototype object has the Object prototype object, which is the initial value of the expression Object.prototype (19.1.3), as the value of its [[Prototype]] internal slot, except the Object prototype object itself.

Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function.

Unless otherwise specified, each built-in function defined in this specification is created as if by calling the CreateBuiltinFunction abstract operation (9.3.3).

Every built-in Function object, including constructors, has a length property whose value is an integer. Unless otherwise specified, this value is equal to the largest number of named arguments shown in the subclause headings for the function description. Optional parameters (which are indicated with brackets: [ ]) or rest parameters (which are shown using the form «...name») are not included in the default argument count.

Note 2

For example, the function object that is the initial value of the map property of the Array prototype object is described under the subclause heading «Array.prototype.map (callbackFn [ , thisArg])» which shows the two named arguments callbackFn and thisArg, the latter being optional; therefore the value of the length property of that Function object is 1.

Unless otherwise specified, the length property of a built-in Function object has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Every built-in Function object, including constructors, that is not identified as an anonymous function has a name property whose value is a String. Unless otherwise specified, this value is the name that is given to the function in this specification. For functions that are specified as properties of objects, the name value is the property name string used to access the function. Functions that are specified as get or set accessor functions of built-in properties have "get " or "set " prepended to the property name string. The value of the name property is explicitly specified for each built-in functions whose property key is a Symbol value.

Unless otherwise specified, the name property of a built-in Function object, if it exists, has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Every other data property described in clauses 18 through 26 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified.

Every accessor property described in clauses 18 through 26 and in Annex B.2 has the attributes { [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. If only a get accessor function is described, the set accessor function is the default value, undefined. If only a set accessor is described the get accessor is the default value, undefined.

18The Global Object#

The unique global object is created before control enters any execution context.

The global object does not have a [[Construct]] internal method; it is not possible to use the global object as a constructor with the new operator.

The global object does not have a [[Call]] internal method; it is not possible to invoke the global object as a function.

The value of the [[Prototype]] internal slot of the global object is implementation-dependent.

In addition to the properties defined in this specification the global object may have additional host defined properties. This may include a property whose value is the global object itself; for example, in the HTML document object model the window property of the global object is the global object itself.

18.1Value Properties of the Global Object#

18.1.1Infinity#

The value of Infinity is +∞ (see 6.1.6). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

18.1.2NaN#

The value of NaN is NaN (see 6.1.6). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

18.1.3undefined#

The value of undefined is undefined (see 6.1.1). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

18.2Function Properties of the Global Object#

18.2.1eval (x)#

The eval function is the %eval% intrinsic object. When the eval function is called with one argument x, the following steps are taken:

  1. Let evalRealm be the value of the active function object's [[Realm]] internal slot.
  2. Let strictCaller be false.
  3. Let directEval be false.
  4. Return ? PerformEval(x, evalRealm, strictCaller, directEval).

18.2.1.1Runtime Semantics: PerformEval( x, evalRealm, strictCaller, direct)#

The abstract operation PerformEval with arguments x, evalRealm, strictCaller, and direct performs the following steps:

  1. Assert: If direct is false, then strictCaller is also false.
  2. If Type(x) is not String, return x.
  3. Let script be the ECMAScript code that is the result of parsing x, interpreted as UTF-16 encoded Unicode text as described in 6.1.4, for the goal symbol Script. If the parse fails, throw a SyntaxError exception. If any early errors are detected, throw a SyntaxError or a ReferenceError exception, depending on the type of the error (but see also clause 16). Parsing and early error detection may be interweaved in an implementation dependent manner.
  4. If script Contains ScriptBody is false, return undefined.
  5. Let body be the ScriptBody of script.
  6. If strictCaller is true, let strictEval be true.
  7. Else, let strictEval be IsStrict of script.
  8. Let ctx be the running execution context. If direct is true, ctx will be the execution context that performed the direct eval. If direct is false, ctx will be the execution context for the invocation of the eval function.
  9. If direct is true, then
    1. Let lexEnv be NewDeclarativeEnvironment(ctx's LexicalEnvironment).
    2. Let varEnv be ctx's VariableEnvironment.
  10. Else,
    1. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]).
    2. Let varEnv be evalRealm.[[GlobalEnv]].
  11. If strictEval is true, let varEnv be lexEnv.
  12. If ctx is not already suspended, suspend ctx.
  13. Let evalCxt be a new ECMAScript code execution context.
  14. Set the evalCxt's Function to null.
  15. Set the evalCxt's Realm to evalRealm.
  16. Set the evalCxt's ScriptOrModule to ctx's ScriptOrModule.
  17. Set the evalCxt's VariableEnvironment to varEnv.
  18. Set the evalCxt's LexicalEnvironment to lexEnv.
  19. Push evalCxt on to the execution context stack; evalCxt is now the running execution context.
  20. Let result be EvalDeclarationInstantiation(body, varEnv, lexEnv, strictEval).
  21. If result.[[Type]] is normal, then
    1. Let result be the result of evaluating body.
  22. If result.[[Type]] is normal and result.[[Value]] is empty, then
    1. Let result be NormalCompletion(undefined).
  23. Suspend evalCxt and remove it from the execution context stack.
  24. Resume the context that is now on the top of the execution context stack as the running execution context.
  25. Return Completion(result).
Note

The eval code cannot instantiate variable or function bindings in the variable environment of the calling context that invoked the eval if the calling context is evaluating formal parameter initializers or if either the code of the calling context or the eval code is strict code. Instead such bindings are instantiated in a new VariableEnvironment that is only accessible to the eval code. Bindings introduced by let, const, or class declarations are always instantiated in a new LexicalEnvironment.

18.2.1.2Runtime Semantics: EvalDeclarationInstantiation( body, varEnv, lexEnv, strict)#

When the abstract operation EvalDeclarationInstantiation is called with arguments body, varEnv, lexEnv, and strict, the following steps are taken:

  1. Let varNames be the VarDeclaredNames of body.
  2. Let varDeclarations be the VarScopedDeclarations of body.
  3. Let lexEnvRec be lexEnv's EnvironmentRecord.
  4. Let varEnvRec be varEnv's EnvironmentRecord.
  5. If strict is false, then
    1. If varEnvRec is a global Environment Record, then
      1. For each name in varNames, do
        1. If varEnvRec.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
        2. NOTE: eval will not create a global var declaration that would be shadowed by a global lexical declaration.
    2. Let thisLex be lexEnv.
    3. Assert: the following loop will terminate.
    4. Repeat while thisLex is not the same as varEnv,
      1. Let thisEnvRec be thisLex's EnvironmentRecord.
      2. If thisEnvRec is not an object Environment Record, then
        1. NOTE: The environment of with statements cannot contain any lexical declaration so it doesn't need to be checked for var/let hoisting conflicts.
        2. For each name in varNames, do
          1. If thisEnvRec.HasBinding(name) is true, then
            1. Throw a SyntaxError exception.
          2. NOTE: A direct eval will not hoist var declaration over a like-named lexical declaration.
      3. Let thisLex be thisLex's outer environment reference.
  6. Let functionsToInitialize be a new empty List.
  7. Let declaredFunctionNames be a new empty List.
  8. For each d in varDeclarations, in reverse list order do
    1. If d is neither a VariableDeclaration or a ForBinding, then
      1. Assert: d is either a FunctionDeclaration or a GeneratorDeclaration.
      2. NOTE If there are multiple FunctionDeclarations for the same name, the last declaration is used.
      3. Let fn be the sole element of the BoundNames of d.
      4. If fn is not an element of declaredFunctionNames, then
        1. If varEnvRec is a global Environment Record, then
          1. Let fnDefinable be ? varEnvRec.CanDeclareGlobalFunction(fn).
          2. If fnDefinable is false, throw a TypeError exception.
        2. Append fn to declaredFunctionNames.
        3. Insert d as the first element of functionsToInitialize.
  9. NOTE: Annex B.3.3.3 adds additional steps at this point.
  10. Let declaredVarNames be a new empty List.
  11. For each d in varDeclarations, do
    1. If d is a VariableDeclaration or a ForBinding, then
      1. For each String vn in the BoundNames of d, do
        1. If vn is not an element of declaredFunctionNames, then
          1. If varEnvRec is a global Environment Record, then
            1. Let vnDefinable be ? varEnvRec.CanDeclareGlobalVar(vn).
            2. If vnDefinable is false, throw a TypeError exception.
          2. If vn is not an element of declaredVarNames, then
            1. Append vn to declaredVarNames.
  12. NOTE: No abnormal terminations occur after this algorithm step unless varEnvRec is a global Environment Record and the global object is a Proxy exotic object.
  13. Let lexDeclarations be the LexicallyScopedDeclarations of body.
  14. For each element d in lexDeclarations do
    1. NOTE Lexically declared names are only instantiated here but not initialized.
    2. For each element dn of the BoundNames of d do
      1. If IsConstantDeclaration of d is true, then
        1. Perform ? lexEnvRec.CreateImmutableBinding(dn, true).
      2. Else,
        1. Perform ? lexEnvRec.CreateMutableBinding(dn, false).
  15. For each production f in functionsToInitialize, do
    1. Let fn be the sole element of the BoundNames of f.
    2. Let fo be the result of performing InstantiateFunctionObject for f with argument lexEnv.
    3. If varEnvRec is a global Environment Record, then
      1. Perform ? varEnvRec.CreateGlobalFunctionBinding(fn, fo, true).
    4. Else,
      1. Let bindingExists be varEnvRec.HasBinding(fn).
      2. If bindingExists is false, then
        1. Let status be ! varEnvRec.CreateMutableBinding(fn, true).
        2. Assert: status is not an abrupt completion because of validation preceding step 12.
        3. Perform ! varEnvRec.InitializeBinding(fn, fo).
      3. Else,
        1. Perform ! varEnvRec.SetMutableBinding(fn, fo, false).
  16. For each String vn in declaredVarNames, in list order do
    1. If varEnvRec is a global Environment Record, then
      1. Perform ? varEnvRec.CreateGlobalVarBinding(vn, true).
    2. Else,
      1. Let bindingExists be varEnvRec.HasBinding(vn).
      2. If bindingExists is false, then
        1. Let status be ! varEnvRec.CreateMutableBinding(vn, true).
        2. Assert: status is not an abrupt completion because of validation preceding step 12.
        3. Perform ! varEnvRec.InitializeBinding(vn, undefined).
  17. Return NormalCompletion(empty).
Note

An alternative version of this algorithm is described in B.3.5.

18.2.2isFinite (number)#

The isFinite function is the %isFinite% intrinsic object. When the isFinite function is called with one argument number, the following steps are taken:

  1. Let num be ? ToNumber(number).
  2. If num is NaN, +∞, or -∞, return false.
  3. Otherwise, return true.

18.2.3isNaN (number)#

The isNaN function is the %isNaN% intrinsic object. When the isNaN function is called with one argument number, the following steps are taken:

  1. Let num be ? ToNumber(number).
  2. If num is NaN, return true.
  3. Otherwise, return false.
Note

A reliable way for ECMAScript code to test if a value X is a NaN is an expression of the form X !== X. The result will be true if and only if X is a NaN.

18.2.4parseFloat (string)#

The parseFloat function produces a Number value dictated by interpretation of the contents of the string argument as a decimal literal.

The parseFloat function is the %parseFloat% intrinsic object. When the parseFloat function is called with one argument string, the following steps are taken:

  1. Let inputString be ? ToString(string).
  2. Let trimmedString be a substring of inputString consisting of the leftmost code unit that is not a StrWhiteSpaceChar and all code units to the right of that code unit. (In other words, remove leading white space.) If inputString does not contain any such code units, let trimmedString be the empty string.
  3. If neither trimmedString nor any prefix of trimmedString satisfies the syntax of a StrDecimalLiteral (see 7.1.3.1), return NaN.
  4. Let numberString be the longest prefix of trimmedString, which might be trimmedString itself, that satisfies the syntax of a StrDecimalLiteral.
  5. Let mathFloat be MV of numberString.
  6. If mathFloat=0, then
    1. If the first code unit of trimmedString is "-", return -0.
    2. Return +0.
  7. Return the Number value for mathFloat.
Note

parseFloat may interpret only a leading portion of string as a Number value; it ignores any code units that cannot be interpreted as part of the notation of an decimal literal, and no indication is given that any such code units were ignored.

18.2.5parseInt (string, radix)#

The parseInt function produces an integer value dictated by interpretation of the contents of the string argument according to the specified radix. Leading white space in string is ignored. If radix is undefined or 0, it is assumed to be 10 except when the number begins with the code unit pairs 0x or 0X, in which case a radix of 16 is assumed. If radix is 16, the number may also optionally begin with the code unit pairs 0x or 0X.

The parseInt function is the %parseInt% intrinsic object. When the parseInt function is called, the following steps are taken:

  1. Let inputString be ? ToString(string).
  2. Let S be a newly created substring of inputString consisting of the first code unit that is not a StrWhiteSpaceChar and all code units following that code unit. (In other words, remove leading white space.) If inputString does not contain any such code unit, let S be the empty string.
  3. Let sign be 1.
  4. If S is not empty and the first code unit of S is 0x002D (HYPHEN-MINUS), let sign be -1.
  5. If S is not empty and the first code unit of S is 0x002B (PLUS SIGN) or 0x002D (HYPHEN-MINUS), remove the first code unit from S.
  6. Let R be ? ToInt32(radix).
  7. Let stripPrefix be true.
  8. If R ≠ 0, then
    1. If R < 2 or R > 36, return NaN.
    2. If R ≠ 16, let stripPrefix be false.
  9. Else R = 0,
    1. Let R be 10.
  10. If stripPrefix is true, then
    1. If the length of S is at least 2 and the first two code units of S are either "0x" or "0X", remove the first two code units from S and let R be 16.
  11. If S contains a code unit that is not a radix-R digit, let Z be the substring of S consisting of all code units before the first such code unit; otherwise, let Z be S.
  12. If Z is empty, return NaN.
  13. Let mathInt be the mathematical integer value that is represented by Z in radix-R notation, using the letters A-Z and a-z for digits with values 10 through 35. (However, if R is 10 and Z contains more than 20 significant digits, every significant digit after the 20th may be replaced by a 0 digit, at the option of the implementation; and if R is not 2, 4, 8, 10, 16, or 32, then mathInt may be an implementation-dependent approximation to the mathematical integer value that is represented by Z in radix-R notation.)
  14. If mathInt = 0, then
    1. If sign = -1, return -0.
    2. Return +0.
  15. Let number be the Number value for mathInt.
  16. Return sign × number.
Note

parseInt may interpret only a leading portion of string as an integer value; it ignores any code units that cannot be interpreted as part of the notation of an integer, and no indication is given that any such code units were ignored.

18.2.6URI Handling Functions#

Uniform Resource Identifiers, or URIs, are Strings that identify resources (e.g. web pages or files) and transport protocols by which to access them (e.g. HTTP or FTP) on the Internet. The ECMAScript language itself does not provide any support for using URIs except for functions that encode and decode URIs as described in 18.2.6.2, 18.2.6.3, 18.2.6.4 and 18.2.6.5

Note

Many implementations of ECMAScript provide additional functions and methods that manipulate web pages; these functions are beyond the scope of this standard.

18.2.6.1URI Syntax and Semantics#

A URI is composed of a sequence of components separated by component separators. The general form is:

Scheme : First / Second ; Third ? Fourth

where the italicized names represent components and “:”, “/”, “;” and “?” are reserved for use as separators. The encodeURI and decodeURI functions are intended to work with complete URIs; they assume that any reserved code units in the URI are intended to have special meaning and so are not encoded. The encodeURIComponent and decodeURIComponent functions are intended to work with the individual component parts of a URI; they assume that any reserved code units represent text and so must be encoded so that they are not interpreted as reserved code units when the component is part of a complete URI.

The following lexical grammar specifies the form of encoded URIs.

Syntax

uri:::uriCharactersopt uriCharacters:::uriCharacteruriCharactersopt uriCharacter:::uriReserved uriUnescaped uriEscaped uriReserved:::one of;/?:@&=+$, uriUnescaped:::uriAlpha DecimalDigit uriMark uriEscaped:::%HexDigitHexDigit uriAlpha:::one ofabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ uriMark:::one of-_.!~*'() Note

The above syntax is based upon RFC 2396 and does not reflect changes introduced by the more recent RFC 3986.

Runtime Semantics

When a code unit to be included in a URI is not listed above or is not intended to have the special meaning sometimes given to the reserved code units, that code unit must be encoded. The code unit is transformed into its UTF-8 encoding, with surrogate pairs first converted from UTF-16 to the corresponding code point value. (Note that for code units in the range [0,127] this results in a single octet with the same value.) The resulting sequence of octets is then transformed into a String with each octet represented by an escape sequence of the form "%xx".

18.2.6.1.1Runtime Semantics: Encode ( string, unescapedSet )#

The encoding and escaping process is described by the abstract operation Encode taking two String arguments string and unescapedSet.

  1. Let strLen be the number of code units in string.
  2. Let R be the empty String.
  3. Let k be 0.
  4. Repeat
    1. If k equals strLen, return R.
    2. Let C be the code unit at index k within string.
    3. If C is in unescapedSet, then
      1. Let S be a String containing only the code unit C.
      2. Let R be a new String value computed by concatenating the previous value of R and S.
    4. Else C is not in unescapedSet,
      1. If the code unit value of C is not less than 0xDC00 and not greater than 0xDFFF, throw a URIError exception.
      2. If the code unit value of C is less than 0xD800 or greater than 0xDBFF, then
        1. Let V be the code unit value of C.
      3. Else,
        1. Increase k by 1.
        2. If k equals strLen, throw a URIError exception.
        3. Let kChar be the code unit value of the code unit at index k within string.
        4. If kChar is less than 0xDC00 or greater than 0xDFFF, throw a URIError exception.
        5. Let V be UTF16Decode(C, kChar).
      4. Let Octets be the array of octets resulting by applying the UTF-8 transformation to V, and let L be the array size.
      5. Let j be 0.
      6. Repeat, while j < L
        1. Let jOctet be the value at index j within Octets.
        2. Let S be a String containing three code units "%XY" where XY are two uppercase hexadecimal digits encoding the value of jOctet.
        3. Let R be a new String value computed by concatenating the previous value of R and S.
        4. Increase j by 1.
    5. Increase k by 1.

18.2.6.1.2Runtime Semantics: Decode ( string, reservedSet )#

The unescaping and decoding process is described by the abstract operation Decode taking two String arguments string and reservedSet.

  1. Let strLen be the number of code units in string.
  2. Let R be the empty String.
  3. Let k be 0.
  4. Repeat
    1. If k equals strLen, return R.
    2. Let C be the code unit at index k within string.
    3. If C is not "%", then
      1. Let S be the String containing only the code unit C.
    4. Else C is "%",
      1. Let start be k.
      2. If k + 2 is greater than or equal to strLen, throw a URIError exception.
      3. If the code units at index (k + 1) and (k + 2) within string do not represent hexadecimal digits, throw a URIError exception.
      4. Let B be the 8-bit value represented by the two hexadecimal digits at index (k + 1) and (k + 2).
      5. Increment k by 2.
      6. If the most significant bit in B is 0, then
        1. Let C be the code unit with code unit value B.
        2. If C is not in reservedSet, then
          1. Let S be the String containing only the code unit C.
        3. Else C is in reservedSet,
          1. Let S be the substring of string from index start to index k inclusive.
      7. Else the most significant bit in B is 1,
        1. Let n be the smallest nonnegative integer such that (B << n) & 0x80 is equal to 0.
        2. If n equals 1 or n is greater than 4, throw a URIError exception.
        3. Let Octets be an array of 8-bit integers of size n.
        4. Put B into Octets at index 0.
        5. If k + (3 × (n - 1)) is greater than or equal to strLen, throw a URIError exception.
        6. Let j be 1.
        7. Repeat, while j < n
          1. Increment k by 1.
          2. If the code unit at index k within string is not "%", throw a URIError exception.
          3. If the code units at index (k + 1) and (k + 2) within string do not represent hexadecimal digits, throw a URIError exception.
          4. Let B be the 8-bit value represented by the two hexadecimal digits at index (k + 1) and (k + 2).
          5. If the two most significant bits in B are not 10, throw a URIError exception.
          6. Increment k by 2.
          7. Put B into Octets at index j.
          8. Increment j by 1.
        8. Let V be the value obtained by applying the UTF-8 transformation to Octets, that is, from an array of octets into a 21-bit value. If Octets does not contain a valid UTF-8 encoding of a Unicode code point, throw a URIError exception.
        9. If V < 0x10000, then
          1. Let C be the code unit V.
          2. If C is not in reservedSet, then
            1. Let S be the String containing only the code unit C.
          3. Else C is in reservedSet,
            1. Let S be the substring of string from index start to index k inclusive.
        10. Else V ≥ 0x10000,
          1. Let L be (((V - 0x10000) & 0x3FF) + 0xDC00).
          2. Let H be ((((V - 0x10000) >> 10) & 0x3FF) + 0xD800).
          3. Let S be the String containing the two code units H and L.
    5. Let R be a new String value computed by concatenating the previous value of R and S.
    6. Increase k by 1.
Note

This syntax of Uniform Resource Identifiers is based upon RFC 2396 and does not reflect the more recent RFC 3986 which replaces RFC 2396. A formal description and implementation of UTF-8 is given in RFC 3629.

In UTF-8, characters are encoded using sequences of 1 to 6 octets. The only octet of a sequence of one has the higher-order bit set to 0, the remaining 7 bits being used to encode the character value. In a sequence of n octets, n>1, the initial octet has the n higher-order bits set to 1, followed by a bit set to 0. The remaining bits of that octet contain bits from the value of the character to be encoded. The following octets all have the higher-order bit set to 1 and the following bit set to 0, leaving 6 bits in each to contain bits from the character to be encoded. The possible UTF-8 encodings of ECMAScript characters are specified in Table 44.

Table 44 (Informative): UTF-8 Encodings
Code Unit Value Representation 1st Octet 2nd Octet 3rd Octet 4th Octet
0x0000 - 0x007F 00000000 0zzzzzzz 0zzzzzzz
0x0080 - 0x07FF 00000yyy yyzzzzzz 110yyyyy 10zzzzzz
0x0800 - 0xD7FF xxxxyyyy yyzzzzzz 1110xxxx 10yyyyyy 10zzzzzz
0xD800 - 0xDBFF
followed by
0xDC00 - 0xDFFF
110110vv vvwwwwxx
followed by
110111yy yyzzzzzz
11110uuu 10uuwwww 10xxyyyy 10zzzzzz
0xD800 - 0xDBFF
not followed by
0xDC00 - 0xDFFF
causes URIError
0xDC00 - 0xDFFF causes URIError
0xE000 - 0xFFFF xxxxyyyy yyzzzzzz 1110xxxx 10yyyyyy 10zzzzzz

Where
uuuuu = vvvv + 1
to account for the addition of 0x10000 as in Surrogates, section 3.8, of the Unicode Standard.

The range of code unit values 0xD800-0xDFFF is used to encode surrogate pairs; the above transformation combines a UTF-16 surrogate pair into a UTF-32 representation and encodes the resulting 21-bit value in UTF-8. Decoding reconstructs the surrogate pair.

RFC 3629 prohibits the decoding of invalid UTF-8 octet sequences. For example, the invalid sequence C0 80 must not decode into the code unit 0x0000. Implementations of the Decode algorithm are required to throw a URIError when encountering such invalid sequences.

18.2.6.2decodeURI (encodedURI)#

The decodeURI function computes a new version of a URI in which each escape sequence and UTF-8 encoding of the sort that might be introduced by the encodeURI function is replaced with the UTF-16 encoding of the code points that it represents. Escape sequences that could not have been introduced by encodeURI are not replaced.

The decodeURI function is the %decodeURI% intrinsic object. When the decodeURI function is called with one argument encodedURI, the following steps are taken:

  1. Let uriString be ? ToString(encodedURI).
  2. Let reservedURISet be a String containing one instance of each code unit valid in uriReserved plus "#".
  3. Return ? Decode(uriString, reservedURISet).
Note

The code point "#" is not decoded from escape sequences even though it is not a reserved URI code point.

18.2.6.3decodeURIComponent (encodedURIComponent)#

The decodeURIComponent function computes a new version of a URI in which each escape sequence and UTF-8 encoding of the sort that might be introduced by the encodeURIComponent function is replaced with the UTF-16 encoding of the code points that it represents.

The decodeURIComponent function is the %decodeURIComponent% intrinsic object. When the decodeURIComponent function is called with one argument encodedURIComponent, the following steps are taken:

  1. Let componentString be ? ToString(encodedURIComponent).
  2. Let reservedURIComponentSet be the empty String.
  3. Return ? Decode(componentString, reservedURIComponentSet).

18.2.6.4encodeURI (uri)#

The encodeURI function computes a new version of a UTF-16 encoded (6.1.4) URI in which each instance of certain code points is replaced by one, two, three, or four escape sequences representing the UTF-8 encoding of the code points.

The encodeURI function is the %encodeURI% intrinsic object. When the encodeURI function is called with one argument uri, the following steps are taken:

  1. Let uriString be ? ToString(uri).
  2. Let unescapedURISet be a String containing one instance of each code unit valid in uriReserved and uriUnescaped plus "#".
  3. Return ? Encode(uriString, unescapedURISet).
Note

The code unit "#" is not encoded to an escape sequence even though it is not a reserved or unescaped URI code point.

18.2.6.5encodeURIComponent (uriComponent)#

The encodeURIComponent function computes a new version of a UTF-16 encoded (6.1.4) URI in which each instance of certain code points is replaced by one, two, three, or four escape sequences representing the UTF-8 encoding of the code point.

The encodeURIComponent function is the %encodeURIComponent% intrinsic object. When the encodeURIComponent function is called with one argument uriComponent, the following steps are taken:

  1. Let componentString be ? ToString(uriComponent).
  2. Let unescapedURIComponentSet be a String containing one instance of each code unit valid in uriUnescaped.
  3. Return ? Encode(componentString, unescapedURIComponentSet).

18.3Constructor Properties of the Global Object#

18.3.1Array ( . . . )#

See 22.1.1.

18.3.2ArrayBuffer ( . . . )#

See 24.1.2.

18.3.3Boolean ( . . . )#

See 19.3.1.

18.3.4DataView ( . . . )#

See 24.2.2.

18.3.5Date ( . . . )#

See 20.3.2.

18.3.6Error ( . . . )#

See 19.5.1.

18.3.7EvalError ( . . . )#

See 19.5.5.1.

18.3.8Float32Array ( . . . )#

See 22.2.4.

18.3.9Float64Array ( . . . )#

See 22.2.4.

18.3.10Function ( . . . )#

See 19.2.1.

18.3.11Int8Array ( . . . )#

See 22.2.4.

18.3.12Int16Array ( . . . )#

See 22.2.4.

18.3.13Int32Array ( . . . )#

See 22.2.4.

18.3.14Map ( . . . )#

See 23.1.1.

18.3.15Number ( . . . )#

See 20.1.1.

18.3.16Object ( . . . )#

See 19.1.1.

18.3.17Proxy ( . . . )#

See 26.2.1.

18.3.18Promise ( . . . )#

See 25.4.3.

18.3.19RangeError ( . . . )#

See 19.5.5.2.

18.3.20ReferenceError ( . . . )#

See 19.5.5.3.

18.3.21RegExp ( . . . )#

See 21.2.3.

18.3.22Set ( . . . )#

See 23.2.1.

18.3.23String ( . . . )#

See 21.1.1.

18.3.24Symbol ( . . . )#

See 19.4.1.

18.3.25SyntaxError ( . . . )#

See 19.5.5.4.

18.3.26TypeError ( . . . )#

See 19.5.5.5.

18.3.27Uint8Array ( . . . )#

See 22.2.4.

18.3.28Uint8ClampedArray ( . . . )#

See 22.2.4.

18.3.29Uint16Array ( . . . )#

See 22.2.4.

18.3.30Uint32Array ( . . . )#

See 22.2.4.

18.3.31URIError ( . . . )#

See 19.5.5.6.

18.3.32WeakMap ( . . . )#

See 23.3.1.

18.3.33WeakSet ( . . . )#

See 23.4.

18.4Other Properties of the Global Object#

18.4.1JSON#

See 24.3.

18.4.2Math#

See 20.2.

18.4.3Reflect#

See 26.1.

19Fundamental Objects#

19.1Object Objects#

19.1.1The Object Constructor#

The Object constructor is the %Object% intrinsic object and the initial value of the Object property of the global object. When called as a constructor it creates a new ordinary object. When Object is called as a function rather than as a constructor, it performs a type conversion.

The Object constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition.

19.1.1.1Object ( [ value ] )#

When Object function is called with optional argument value, the following steps are taken:

  1. If NewTarget is neither undefined nor the active function, then
    1. Return ? OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%").
  2. If value is null, undefined or not supplied, return ObjectCreate(%ObjectPrototype%).
  3. Return ToObject(value).

The length property of the Object constructor function is 1.

19.1.2Properties of the Object Constructor#

The value of the [[Prototype]] internal slot of the Object constructor is the intrinsic object %FunctionPrototype%.

Besides the length property, the Object constructor has the following properties:

19.1.2.1Object.assign ( target, ...sources )#

The assign function is used to copy the values of all of the enumerable own properties from one or more source objects to a target object. When the assign function is called, the following steps are taken:

  1. Let to be ? ToObject(target).
  2. If only one argument was passed, return to.
  3. Let sources be the List of argument values starting with the second argument.
  4. For each element nextSource of sources, in ascending index order,
    1. If nextSource is undefined or null, let keys be a new empty List.
    2. Else,
      1. Let from be ToObject(nextSource).
      2. Let keys be ? from.[[OwnPropertyKeys]]().
    3. Repeat for each element nextKey of keys in List order,
      1. Let desc be ? from.[[GetOwnProperty]](nextKey).
      2. If desc is not undefined and desc.[[Enumerable]] is true, then
        1. Let propValue be ? Get(from, nextKey).
        2. Perform ? Set(to, nextKey, propValue, true).
  5. Return to.

The length property of the assign method is 2.

19.1.2.2Object.create ( O, Properties )#

The create function creates a new object with a specified prototype. When the create function is called, the following steps are taken:

  1. If Type(O) is neither Object nor Null, throw a TypeError exception.
  2. Let obj be ObjectCreate(O).
  3. If Properties is not undefined, then
    1. Return ? ObjectDefineProperties(obj, Properties).
  4. Return obj.

19.1.2.3Object.defineProperties ( O, Properties )#

The defineProperties function is used to add own properties and/or update the attributes of existing own properties of an object. When the defineProperties function is called, the following steps are taken:

  1. Return ? ObjectDefineProperties(O, Properties).

19.1.2.3.1Runtime Semantics: ObjectDefineProperties ( O, Properties )#

The abstract operation ObjectDefineProperties with arguments O and Properties performs the following steps:

  1. If Type(O) is not Object, throw a TypeError exception.
  2. Let props be ? ToObject(Properties).
  3. Let keys be ? props.[[OwnPropertyKeys]]().
  4. Let descriptors be a new empty List.
  5. Repeat for each element nextKey of keys in List order,
    1. Let propDesc be ? props.[[GetOwnProperty]](nextKey).
    2. If propDesc is not undefined and propDesc.[[Enumerable]] is true, then
      1. Let descObj be ? Get(props, nextKey).
      2. Let desc be ? ToPropertyDescriptor(descObj).
      3. Append the pair (a two element List) consisting of nextKey and desc to the end of descriptors.
  6. For each pair from descriptors in list order,
    1. Let P be the first element of pair.
    2. Let desc be the second element of pair.
    3. Perform ? DefinePropertyOrThrow(O, P, desc).
  7. Return O.

19.1.2.4Object.defineProperty ( O, P, Attributes )#

The defineProperty function is used to add an own property and/or update the attributes of an existing own property of an object. When the defineProperty function is called, the following steps are taken:

  1. If Type(O) is not Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(P).
  3. Let desc be ? ToPropertyDescriptor(Attributes).
  4. Perform ? DefinePropertyOrThrow(O, key, desc).
  5. Return O.

19.1.2.5Object.freeze ( O )#

When the freeze function is called, the following steps are taken:

  1. If Type(O) is not Object, return O.
  2. Let status be ? SetIntegrityLevel(O, "frozen").
  3. If status is false, throw a TypeError exception.
  4. Return O.

19.1.2.6Object.getOwnPropertyDescriptor ( O, P )#

When the getOwnPropertyDescriptor function is called, the following steps are taken:

  1. Let obj be ? ToObject(O).
  2. Let key be ? ToPropertyKey(P).
  3. Let desc be ? obj.[[GetOwnProperty]](key).
  4. Return FromPropertyDescriptor(desc).

19.1.2.7Object.getOwnPropertyNames ( O )#

When the getOwnPropertyNames function is called, the following steps are taken:

  1. Return ? GetOwnPropertyKeys(O, String).

19.1.2.8Object.getOwnPropertySymbols ( O )#

When the getOwnPropertySymbols function is called with argument O, the following steps are taken:

  1. Return ? GetOwnPropertyKeys(O, Symbol).

19.1.2.8.1Runtime Semantics: GetOwnPropertyKeys ( O, Type )#

The abstract operation GetOwnPropertyKeys is called with arguments O and Type where O is an Object and Type is one of the ECMAScript specification types String or Symbol. The following steps are taken:

  1. Let obj be ? ToObject(O).
  2. Let keys be ? obj.[[OwnPropertyKeys]]().
  3. Let nameList be a new empty List.
  4. Repeat for each element nextKey of keys in List order,
    1. If Type(nextKey) is Type, then
      1. Append nextKey as the last element of nameList.
  5. Return CreateArrayFromList(nameList).

19.1.2.9Object.getPrototypeOf ( O )#

When the getPrototypeOf function is called with argument O, the following steps are taken:

  1. Let obj be ? ToObject(O).
  2. Return ? obj.[[GetPrototypeOf]]().

19.1.2.10Object.is ( value1, value2 )#

When the is function is called with arguments value1 and value2, the following steps are taken:

  1. Return SameValue(value1, value2).

19.1.2.11Object.isExtensible ( O )#

When the isExtensible function is called with argument O, the following steps are taken:

  1. If Type(O) is not Object, return false.
  2. Return ? IsExtensible(O).

19.1.2.12Object.isFrozen ( O )#

When the isFrozen function is called with argument O, the following steps are taken:

  1. If Type(O) is not Object, return true.
  2. Return ? TestIntegrityLevel(O, "frozen").

19.1.2.13Object.isSealed ( O )#

When the isSealed function is called with argument O, the following steps are taken:

  1. If Type(O) is not Object, return true.
  2. Return ? TestIntegrityLevel(O, "sealed").

19.1.2.14Object.keys ( O )#

When the keys function is called with argument O, the following steps are taken:

  1. Let obj be ? ToObject(O).
  2. Let nameList be ? EnumerableOwnNames(obj).
  3. Return CreateArrayFromList(nameList).

If an implementation defines a specific order of enumeration for the for-in statement, the same order must be used for the elements of the array returned in step 3.

19.1.2.15Object.preventExtensions ( O )#

When the preventExtensions function is called, the following steps are taken:

  1. If Type(O) is not Object, return O.
  2. Let status be ? O.[[PreventExtensions]]().
  3. If status is false, throw a TypeError exception.
  4. Return O.

19.1.2.16Object.prototype#

The initial value of Object.prototype is the intrinsic object %ObjectPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.1.2.17Object.seal ( O )#

When the seal function is called, the following steps are taken:

  1. If Type(O) is not Object, return O.
  2. Let status be ? SetIntegrityLevel(O, "sealed").
  3. If status is false, throw a TypeError exception.
  4. Return O.

19.1.2.18Object.setPrototypeOf ( O, proto )#

When the setPrototypeOf function is called with arguments O and proto, the following steps are taken:

  1. Let O be ? RequireObjectCoercible(O).
  2. If Type(proto) is neither Object nor Null, throw a TypeError exception.
  3. If Type(O) is not Object, return O.
  4. Let status be ? O.[[SetPrototypeOf]](proto).
  5. If status is false, throw a TypeError exception.
  6. Return O.

19.1.3Properties of the Object Prototype Object#

The Object prototype object is the intrinsic object %ObjectPrototype%. The Object prototype object is an immutable prototype exotic object.

The value of the [[Prototype]] internal slot of the Object prototype object is null and the initial value of the [[Extensible]] internal slot is true.

19.1.3.1Object.prototype.constructor#

The initial value of Object.prototype.constructor is the intrinsic object %Object%.

19.1.3.2Object.prototype.hasOwnProperty ( V )#

When the hasOwnProperty method is called with argument V, the following steps are taken:

  1. Let P be ? ToPropertyKey(V).
  2. Let O be ? ToObject(this value).
  3. Return ? HasOwnProperty(O, P).
Note

The ordering of steps 1 and 2 is chosen to ensure that any exception that would have been thrown by step 1 in previous editions of this specification will continue to be thrown even if the this value is undefined or null.

19.1.3.3Object.prototype.isPrototypeOf ( V )#

When the isPrototypeOf method is called with argument V, the following steps are taken:

  1. If Type(V) is not Object, return false.
  2. Let O be ? ToObject(this value).
  3. Repeat
    1. Let V be ? V.[[GetPrototypeOf]]().
    2. If V is null, return false.
    3. If SameValue(O, V) is true, return true.
Note

The ordering of steps 1 and 2 preserves the behaviour specified by previous editions of this specification for the case where V is not an object and the this value is undefined or null.

19.1.3.4Object.prototype.propertyIsEnumerable ( V )#

When the propertyIsEnumerable method is called with argument V, the following steps are taken:

  1. Let P be ? ToPropertyKey(V).
  2. Let O be ? ToObject(this value).
  3. Let desc be ? O.[[GetOwnProperty]](P).
  4. If desc is undefined, return false.
  5. Return the value of desc.[[Enumerable]].
Note 1

This method does not consider objects in the prototype chain.

Note 2

The ordering of steps 1 and 2 is chosen to ensure that any exception that would have been thrown by step 1 in previous editions of this specification will continue to be thrown even if the this value is undefined or null.

19.1.3.5Object.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )#

When the toLocaleString method is called, the following steps are taken:

  1. Let O be the this value.
  2. Return ? Invoke(O, "toString").

The optional parameters to this function are not used but are intended to correspond to the parameter pattern used by ECMA-402 toLocalString functions. Implementations that do not include ECMA-402 support must not use those parameter positions for other purposes.

Note 1

This function provides a generic toLocaleString implementation for objects that have no locale-specific toString behaviour. Array, Number, Date, and Typed Arrays provide their own locale-sensitive toLocaleString methods.

Note 2

ECMA-402 intentionally does not provide an alternative to this default implementation.

19.1.3.6Object.prototype.toString ( )#

When the toString method is called, the following steps are taken:

  1. If the this value is undefined, return "[object Undefined]".
  2. If the this value is null, return "[object Null]".
  3. Let O be ToObject(this value).
  4. Let isArray be ? IsArray(O).
  5. If isArray is true, let builtinTag be "Array".
  6. Else, if O is an exotic String object, let builtinTag be "String".
  7. Else, if O has an [[ParameterMap]] internal slot, let builtinTag be "Arguments".
  8. Else, if O has a [[Call]] internal method, let builtinTag be "Function".
  9. Else, if O has an [[ErrorData]] internal slot, let builtinTag be "Error".
  10. Else, if O has a [[BooleanData]] internal slot, let builtinTag be "Boolean".
  11. Else, if O has a [[NumberData]] internal slot, let builtinTag be "Number".
  12. Else, if O has a [[DateValue]] internal slot, let builtinTag be "Date".
  13. Else, if O has a [[RegExpMatcher]] internal slot, let builtinTag be "RegExp".
  14. Else, let builtinTag be "Object".
  15. Let tag be ? Get(O, @@toStringTag).
  16. If Type(tag) is not String, let tag be builtinTag.
  17. Return the String that is the result of concatenating "[object ", tag, and "]".

This function is the %ObjProto_toString% intrinsic object.

Note

Historically, this function was occasionally used to access the String value of the [[Class]] internal slot that was used in previous editions of this specification as a nominal type tag for various built-in objects. The above definition of toString preserves compatibility for legacy code that uses toString as a test for those specific kinds of built-in objects. It does not provide a reliable type testing mechanism for other kinds of built-in or program defined objects. In addition, programs can use @@toStringTag in ways that will invalidate the reliability of such legacy type tests.

19.1.3.7Object.prototype.valueOf ( )#

When the valueOf method is called, the following steps are taken:

  1. Return ? ToObject(this value).

This function is the %ObjProto_valueOf% intrinsic object.

19.1.4Properties of Object Instances#

Object instances have no special properties beyond those inherited from the Object prototype object.

19.2Function Objects#

19.2.1The Function Constructor#

The Function constructor is the %Function% intrinsic object and the initial value of the Function property of the global object. When Function is called as a function rather than as a constructor, it creates and initializes a new Function object. Thus the function call Function(…) is equivalent to the object creation expression new Function(…) with the same arguments.

The Function constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Function behaviour must include a super call to the Function constructor to create and initialize a subclass instances with the internal slots necessary for built-in function behaviour. All ECMAScript syntactic forms for defining function objects create instances of Function. There is no syntactic means to create instances of Function subclasses except for the built-in Generator Function subclass.

19.2.1.1Function ( p1, p2, … , pn, body )#

The last argument specifies the body (executable code) of a function; any preceding arguments specify formal parameters.

When the Function function is called with some arguments p1, p2, … , pn, body (where n might be 0, that is, there are no “p” arguments, and where body might also not be provided), the following steps are taken:

  1. Let C be the active function object.
  2. Let args be the argumentsList that was passed to this function by [[Call]] or [[Construct]].
  3. Return ? CreateDynamicFunction(C, NewTarget, "normal", args).
Note

It is permissible but not necessary to have one argument for each formal parameter to be specified. For example, all three of the following expressions produce the same result:


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")
          

19.2.1.1.1Runtime Semantics: CreateDynamicFunction(constructor, newTarget, kind, args)#

The abstract operation CreateDynamicFunction is called with arguments constructor, newTarget, kind, and args. constructor is the constructor function that is performing this action, newTarget is the constructor that new was initially applied to, kind is either "normal" or "generator", and args is a List containing the actual argument values that were passed to constructor. The following steps are taken:

  1. If newTarget is undefined, let newTarget be constructor.
  2. If kind is "normal", then
    1. Let goal be the grammar symbol FunctionBody.
    2. Let parameterGoal be the grammar symbol FormalParameters.
    3. Let fallbackProto be "%FunctionPrototype%".
  3. Else,
    1. Let goal be the grammar symbol GeneratorBody.
    2. Let parameterGoal be the grammar symbol FormalParameters[Yield].
    3. Let fallbackProto be "%Generator%".
  4. Let argCount be the number of elements in args.
  5. Let P be the empty String.
  6. If argCount = 0, let bodyText be the empty String.
  7. Else if argCount = 1, let bodyText be args[0].
  8. Else argCount > 1,
    1. Let firstArg be args[0].
    2. Let P be ? ToString(firstArg).
    3. Let k be 1.
    4. Repeat, while k < argCount-1
      1. Let nextArg be args[k].
      2. Let nextArgString be ? ToString(nextArg).
      3. Let P be the result of concatenating the previous value of P, the String "," (a comma), and nextArgString.
      4. Increase k by 1.
    5. Let bodyText be args[k].
  9. Let bodyText be ? ToString(bodyText).
  10. Let parameters be the result of parsing P, interpreted as UTF-16 encoded Unicode text as described in 6.1.4, using parameterGoal as the goal symbol. Throw a SyntaxError exception if the parse fails.
  11. Let body be the result of parsing bodyText, interpreted as UTF-16 encoded Unicode text as described in 6.1.4, using goal as the goal symbol. Throw a SyntaxError exception if the parse fails.
  12. If bodyText is strict mode code, then let strict be true, else let strict be false.
  13. If any static semantics errors are detected for parameters or body, throw a SyntaxError or a ReferenceError exception, depending on the type of the error. If strict is true, the Early Error rules for StrictFormalParameters:FormalParameters are applied. Parsing and early error detection may be interweaved in an implementation dependent manner.
  14. If ContainsUseStrict of body is true and IsSimpleParameterList of parameters is false, throw a SyntaxError exception.
  15. If any element of the BoundNames of parameters also occurs in the LexicallyDeclaredNames of body, throw a SyntaxError exception.
  16. If body Contains SuperCall is true, throw a SyntaxError exception.
  17. If parameters Contains SuperCall is true, throw a SyntaxError exception.
  18. If body Contains SuperProperty is true, throw a SyntaxError exception.
  19. If parameters Contains SuperProperty is true, throw a SyntaxError exception.
  20. If kind is "generator", then
    1. If parameters Contains YieldExpression is true, throw a SyntaxError exception.
  21. If strict is true, then
    1. If BoundNames of parameters contains any duplicate elements, throw a SyntaxError exception.
  22. Let proto be ? GetPrototypeFromConstructor(newTarget, fallbackProto).
  23. Let F be FunctionAllocate(proto, strict, kind).
  24. Let realmF be the value of F's [[Realm]] internal slot.
  25. Let scope be realmF.[[GlobalEnv]].
  26. Perform FunctionInitialize(F, Normal, parameters, body, scope).
  27. If kind is "generator", then
    1. Let prototype be ObjectCreate(%GeneratorPrototype%).
    2. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  28. Else, perform MakeConstructor(F).
  29. Perform SetFunctionName(F, "anonymous").
  30. Return F.
Note

A prototype property is automatically created for every function created using CreateDynamicFunction, to provide for the possibility that the function will be used as a constructor.

19.2.2Properties of the Function Constructor#

The Function constructor is itself a built-in function object. The value of the [[Prototype]] internal slot of the Function constructor is the intrinsic object %FunctionPrototype%.

The value of the [[Extensible]] internal slot of the Function constructor is true.

The Function constructor has the following properties:

19.2.2.1Function.length#

This is a data property with a value of 1. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

19.2.2.2Function.prototype#

The value of Function.prototype is %FunctionPrototype%, the intrinsic Function prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.2.3Properties of the Function Prototype Object#

The Function prototype object is the intrinsic object %FunctionPrototype%. The Function prototype object is itself a built-in function object. When invoked, it accepts any arguments and returns undefined. It does not have a [[Construct]] internal method so it is not a constructor.

Note

The Function prototype object is specified to be a function object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.

The value of the [[Prototype]] internal slot of the Function prototype object is the intrinsic object %ObjectPrototype%. The initial value of the [[Extensible]] internal slot of the Function prototype object is true.

The Function prototype object does not have a prototype property.

The value of the length property of the Function prototype object is 0.

The value of the name property of the Function prototype object is the empty String.

19.2.3.1Function.prototype.apply ( thisArg, argArray )#

When the apply method is called on an object func with arguments thisArg and argArray, the following steps are taken:

  1. If IsCallable(func) is false, throw a TypeError exception.
  2. If argArray is null or undefined, then
    1. Perform PrepareForTailCall().
    2. Return ? Call(func, thisArg).
  3. Let argList be ? CreateListFromArrayLike(argArray).
  4. Perform PrepareForTailCall().
  5. Return ? Call(func, thisArg, argList).
Note 1

The thisArg value is passed without modification as the this value. This is a change from Edition 3, where an undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value. Even though the thisArg is passed without modification, non-strict functions still perform these transformations upon entry to the function.

Note 2

If func is an arrow function or a bound function then the thisArg will be ignored by the function [[Call]] in step 5.

19.2.3.2Function.prototype.bind ( thisArg, ...args)#

When the bind method is called with argument thisArg and zero or more args, it performs the following steps:

  1. Let Target be the this value.
  2. If IsCallable(Target) is false, throw a TypeError exception.
  3. Let args be a new (possibly empty) List consisting of all of the argument values provided after thisArg in order.
  4. Let F be ? BoundFunctionCreate(Target, thisArg, args).
  5. Let targetHasLength be ? HasOwnProperty(Target, "length").
  6. If targetHasLength is true, then
    1. Let targetLen be ? Get(Target, "length").
    2. If Type(targetLen) is not Number, let L be 0.
    3. Else,
      1. Let targetLen be ToInteger(targetLen).
      2. Let L be the larger of 0 and the result of targetLen minus the number of elements of args.
  7. Else let L be 0.
  8. Perform ! DefinePropertyOrThrow(F, "length", PropertyDescriptor {[[Value]]: L, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}).
  9. Let targetName be ? Get(Target, "name").
  10. If Type(targetName) is not String, let targetName be the empty string.
  11. Perform SetFunctionName(F, targetName, "bound").
  12. Return F.
Note 1

Function objects created using Function.prototype.bind are exotic objects. They also do not have a prototype property.

Note 2

If Target is an arrow function or a bound function then the thisArg passed to this method will not be used by subsequent calls to F.

19.2.3.3Function.prototype.call (thisArg, ...args)#

When the call method is called on an object func with argument, thisArg and zero or more args, the following steps are taken:

  1. If IsCallable(func) is false, throw a TypeError exception.
  2. Let argList be a new empty List.
  3. If this method was called with more than one argument, then in left to right order, starting with the second argument, append each argument as the last element of argList.
  4. Perform PrepareForTailCall().
  5. Return ? Call(func, thisArg, argList).
Note 1

The thisArg value is passed without modification as the this value. This is a change from Edition 3, where an undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value. Even though the thisArg is passed without modification, non-strict functions still perform these transformations upon entry to the function.

Note 2

If func is an arrow function or a bound function then the thisArg will be ignored by the function [[Call]] in step 5.

19.2.3.4Function.prototype.constructor#

The initial value of Function.prototype.constructor is the intrinsic object %Function%.

19.2.3.5Function.prototype.toString ( )#

When the toString method is called on an object func, the following steps are taken:

  1. If func is a Bound Function exotic object, then
    1. Return an implementation-dependent String source code representation of func. The representation must conform to the rules below. It is implementation dependent whether the representation includes bound function information or information about the target function.
  2. If Type(func) is Object and is either a built-in function object or has an [[ECMAScriptCode]] internal slot, then
    1. Return an implementation-dependent String source code representation of func. The representation must conform to the rules below.
  3. Throw a TypeError exception.

toString Representation Requirements:

  • The string representation must have the syntax of a FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, ClassDeclaration, ClassExpression, ArrowFunction, MethodDefinition, or GeneratorMethod depending upon the actual characteristics of the object.
  • The use and placement of white space, line terminators, and semicolons within the representation String is implementation-dependent.
  • If the object was defined using ECMAScript code and the returned string representation is not in the form of a MethodDefinition or GeneratorMethod then the representation must be such that if the string is evaluated, using eval in a lexical context that is equivalent to the lexical context used to create the original object, it will result in a new functionally equivalent object. In that case the returned source code must not mention freely any variables that were not mentioned freely by the original function's source code, even if these “extra” names were originally in scope.
  • If the implementation cannot produce a source code string that meets these criteria then it must return a string for which eval will throw a SyntaxError exception.

19.2.3.6Function.prototype [ @@hasInstance ] ( V )#

When the @@hasInstance method of an object F is called with value V, the following steps are taken:

  1. Let F be the this value.
  2. Return ? OrdinaryHasInstance(F, V).

The value of the name property of this function is "[Symbol.hasInstance]".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

This is the default implementation of @@hasInstance that most functions inherit. @@hasInstance is called by the instanceof operator to determine whether a value is an instance of a specific constructor. An expression such as


            v instanceof F
          

evaluates as


            F[@@hasInstance](v)
          

A constructor function can control which objects are recognized as its instances by instanceof by exposing a different @@hasInstance method on the function.

This property is non-writable and non-configurable to prevent tampering that could be used to globally expose the target function of a bound function.

19.2.4Function Instances#

Every function instance is an ECMAScript function object and has the internal slots listed in Table 27. Function instances created using the Function.prototype.bind method (19.2.3.2) have the internal slots listed in Table 28.

The Function instances have the following properties:

19.2.4.1length#

The value of the length property is an integer that indicates the typical number of arguments expected by the function. However, the language permits the function to be invoked with some other number of arguments. The behaviour of a function when invoked on a number of arguments other than the number specified by its length property depends on the function. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

19.2.4.2name#

The value of the name property is an String that is descriptive of the function. The name has no semantic significance but is typically a variable or property name that is used to refer to the function at its point of definition in ECMAScript code. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Anonymous functions objects that do not have a contextual name associated with them by this specification do not have a name own property but inherit the name property of %FunctionPrototype%.

19.2.4.3prototype#

Function instances that can be used as a constructor have a prototype property. Whenever such a function instance is created another ordinary object is also created and is the initial value of the function's prototype property. Unless otherwise specified, the value of the prototype property is used to initialize the [[Prototype]] internal slot of the object created when that function is invoked as a constructor.

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Note

Function objects created using Function.prototype.bind, or by evaluating a MethodDefinition (that are not a GeneratorMethod) or an ArrowFunction grammar production do not have a prototype property.

19.3Boolean Objects#

19.3.1The Boolean Constructor#

The Boolean constructor is the %Boolean% intrinsic object and the initial value of the Boolean property of the global object. When called as a constructor it creates and initializes a new Boolean object. When Boolean is called as a function rather than as a constructor, it performs a type conversion.

The Boolean constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Boolean behaviour must include a super call to the Boolean constructor to create and initialize the subclass instance with a [[BooleanData]] internal slot.

19.3.1.1Boolean ( value )#

When Boolean is called with argument value, the following steps are taken:

  1. Let b be ToBoolean(value).
  2. If NewTarget is undefined, return b.
  3. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%BooleanPrototype%", « [[BooleanData]] »).
  4. Set the value of O's [[BooleanData]] internal slot to b.
  5. Return O.

19.3.2Properties of the Boolean Constructor#

The value of the [[Prototype]] internal slot of the Boolean constructor is the intrinsic object %FunctionPrototype%.

The Boolean constructor has the following properties:

19.3.2.1Boolean.prototype#

The initial value of Boolean.prototype is the intrinsic object %BooleanPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.3.3Properties of the Boolean Prototype Object#

The Boolean prototype object is the intrinsic object %BooleanPrototype%. The Boolean prototype object is an ordinary object. The Boolean prototype is itself a Boolean object; it has a [[BooleanData]] internal slot with the value false.

The value of the [[Prototype]] internal slot of the Boolean prototype object is the intrinsic object %ObjectPrototype%.

19.3.3.1thisBooleanValue ( value )#

The abstract operation thisBooleanValue(value) performs the following steps:

  1. If Type(value) is Boolean, return value.
  2. If Type(value) is Object and value has a [[BooleanData]] internal slot, then
    1. Assert: value's [[BooleanData]] internal slot is a Boolean value.
    2. Return the value of value's [[BooleanData]] internal slot.
  3. Throw a TypeError exception.

19.3.3.2Boolean.prototype.constructor#

The initial value of Boolean.prototype.constructor is the intrinsic object %Boolean%.

19.3.3.3Boolean.prototype.toString ( )#

The following steps are taken:

  1. Let b be ? thisBooleanValue(this value).
  2. If b is true, return "true"; else return "false".

19.3.3.4Boolean.prototype.valueOf ( )#

The following steps are taken:

  1. Return ? thisBooleanValue(this value).

19.3.4Properties of Boolean Instances#

Boolean instances are ordinary objects that inherit properties from the Boolean prototype object. Boolean instances have a [[BooleanData]] internal slot. The [[BooleanData]] internal slot is the Boolean value represented by this Boolean object.

19.4Symbol Objects#

19.4.1The Symbol Constructor#

The Symbol constructor is the %Symbol% intrinsic object and the initial value of the Symbol property of the global object. When Symbol is called as a function, it returns a new Symbol value.

The Symbol constructor is not intended to be used with the new operator or to be subclassed. It may be used as the value of an extends clause of a class definition but a super call to the Symbol constructor will cause an exception.

19.4.1.1Symbol ( [ description ] )#

When Symbol is called with optional argument description, the following steps are taken:

  1. If NewTarget is not undefined, throw a TypeError exception.
  2. If description is undefined, let descString be undefined.
  3. Else, let descString be ? ToString(description).
  4. Return a new unique Symbol value whose [[Description]] value is descString.

19.4.2Properties of the Symbol Constructor#

The value of the [[Prototype]] internal slot of the Symbol constructor is the intrinsic object %FunctionPrototype%.

The Symbol constructor has the following properties:

19.4.2.1Symbol.for ( key )#

When Symbol.for is called with argument key it performs the following steps:

  1. Let stringKey be ? ToString(key).
  2. For each element e of the GlobalSymbolRegistry List,
    1. If SameValue(e.[[Key]], stringKey) is true, return e.[[Symbol]].
  3. Assert: GlobalSymbolRegistry does not currently contain an entry for stringKey.
  4. Let newSymbol be a new unique Symbol value whose [[Description]] value is stringKey.
  5. Append the Record { [[Key]]: stringKey, [[Symbol]]: newSymbol } to the GlobalSymbolRegistry List.
  6. Return newSymbol.

The GlobalSymbolRegistry is a List that is globally available. It is shared by all realms. Prior to the evaluation of any ECMAScript code it is initialized as a new empty List. Elements of the GlobalSymbolRegistry are Records with the structure defined in Table 45.

Table 45: GlobalSymbolRegistry Record Fields
Field Name Value Usage
[[Key]] A String A string key used to globally identify a Symbol.
[[Symbol]] A Symbol A symbol that can be retrieved from any realm.

19.4.2.2Symbol.hasInstance#

The initial value of Symbol.hasInstance is the well known symbol @@hasInstance (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.4.2.3Symbol.isConcatSpreadable#

The initial value of Symbol.isConcatSpreadable is the well known symbol @@isConcatSpreadable (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.4.2.4Symbol.iterator#

The initial value of Symbol.iterator is the well known symbol @@iterator (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.4.2.5Symbol.keyFor ( sym )#

When Symbol.keyFor is called with argument sym it performs the following steps:

  1. If Type(sym) is not Symbol, throw a TypeError exception.
  2. For each element e of the GlobalSymbolRegistry List (see 19.4.2.1),
    1. If SameValue(e.[[Symbol]], sym) is true, return e.[[Key]].
  3. Assert: GlobalSymbolRegistry does not currently contain an entry for sym.
  4. Return undefined.

19.4.2.6Symbol.match#

The initial value of Symbol.match is the well known symbol @@match (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.4.2.7Symbol.prototype#

The initial value of Symbol.prototype is the intrinsic object %SymbolPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.4.2.8Symbol.replace#

The initial value of Symbol.replace is the well known symbol @@replace (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.4.2.9Symbol.search#

The initial value of Symbol.search is the well known symbol @@search (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.4.2.10Symbol.species#

The initial value of Symbol.species is the well known symbol @@species (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.4.2.11Symbol.split#

The initial value of Symbol.split is the well known symbol @@split (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.4.2.12Symbol.toPrimitive#

The initial value of Symbol.toPrimitive is the well known symbol @@toPrimitive (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.4.2.13Symbol.toStringTag#

The initial value of Symbol.toStringTag is the well known symbol @@toStringTag (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.4.2.14Symbol.unscopables#

The initial value of Symbol.unscopables is the well known symbol @@unscopables (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.4.3Properties of the Symbol Prototype Object#

The Symbol prototype object is the intrinsic object %SymbolPrototype%. The Symbol prototype object is an ordinary object. It is not a Symbol instance and does not have a [[SymbolData]] internal slot.

The value of the [[Prototype]] internal slot of the Symbol prototype object is the intrinsic object %ObjectPrototype%.

19.4.3.1Symbol.prototype.constructor#

The initial value of Symbol.prototype.constructor is the intrinsic object %Symbol%.

19.4.3.2Symbol.prototype.toString ( )#

The following steps are taken:

  1. Let s be the this value.
  2. If Type(s) is Symbol, let sym be s.
  3. Else,
    1. If Type(s) is not Object, throw a TypeError exception.
    2. If s does not have a [[SymbolData]] internal slot, throw a TypeError exception.
    3. Let sym be the value of s's [[SymbolData]] internal slot.
  4. Return SymbolDescriptiveString(sym).

19.4.3.2.1Runtime Semantics: SymbolDescriptiveString ( sym )#

When the abstract operation SymbolDescriptiveString is called with argument sym, the following steps are taken:

  1. Assert: Type(sym) is Symbol.
  2. Let desc be sym's [[Description]] value.
  3. If desc is undefined, let desc be the empty string.
  4. Assert: Type(desc) is String.
  5. Return the result of concatenating the strings "Symbol(", desc, and ")".

19.4.3.3Symbol.prototype.valueOf ( )#

The following steps are taken:

  1. Let s be the this value.
  2. If Type(s) is Symbol, return s.
  3. If Type(s) is not Object, throw a TypeError exception.
  4. If s does not have a [[SymbolData]] internal slot, throw a TypeError exception.
  5. Return the value of s's [[SymbolData]] internal slot.

19.4.3.4Symbol.prototype [ @@toPrimitive ] ( hint )#

This function is called by ECMAScript language operators to convert a Symbol object to a primitive value. The allowed values for hint are "default", "number", and "string".

When the @@toPrimitive method is called with argument hint, the following steps are taken:

  1. Let s be the this value.
  2. If Type(s) is Symbol, return s.
  3. If Type(s) is not Object, throw a TypeError exception.
  4. If s does not have a [[SymbolData]] internal slot, throw a TypeError exception.
  5. Return the value of s's [[SymbolData]] internal slot.

The value of the name property of this function is "[Symbol.toPrimitive]".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

19.4.3.5Symbol.prototype [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "Symbol".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

19.4.4Properties of Symbol Instances#

Symbol instances are ordinary objects that inherit properties from the Symbol prototype object. Symbol instances have a [[SymbolData]] internal slot. The [[SymbolData]] internal slot is the Symbol value represented by this Symbol object.

19.5Error Objects#

Instances of Error objects are thrown as exceptions when runtime errors occur. The Error objects may also serve as base objects for user-defined exception classes.

19.5.1The Error Constructor#

The Error constructor is the %Error% intrinsic object and the initial value of the Error property of the global object. When Error is called as a function rather than as a constructor, it creates and initializes a new Error object. Thus the function call Error(…) is equivalent to the object creation expression new Error(…) with the same arguments.

The Error constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Error behaviour must include a super call to the Error constructor to create and initialize subclass instances with a [[ErrorData]] internal slot.

19.5.1.1Error ( message )#

When the Error function is called with argument message, the following steps are taken:

  1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
  2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%ErrorPrototype%", « [[ErrorData]] »).
  3. If message is not undefined, then
    1. Let msg be ? ToString(message).
    2. Let msgDesc be the PropertyDescriptor{[[Value]]: msg, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}.
    3. Perform ! DefinePropertyOrThrow(O, "message", msgDesc).
  4. Return O.

19.5.2Properties of the Error Constructor#

The value of the [[Prototype]] internal slot of the Error constructor is the intrinsic object %FunctionPrototype%.

The Error constructor has the following properties:

19.5.2.1Error.prototype#

The initial value of Error.prototype is the intrinsic object %ErrorPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.5.3Properties of the Error Prototype Object#

The Error prototype object is the intrinsic object %ErrorPrototype%. The Error prototype object is an ordinary object. It is not an Error instance and does not have an [[ErrorData]] internal slot.

The value of the [[Prototype]] internal slot of the Error prototype object is the intrinsic object %ObjectPrototype%.

19.5.3.1Error.prototype.constructor#

The initial value of Error.prototype.constructor is the intrinsic object %Error%.

19.5.3.2Error.prototype.message#

The initial value of Error.prototype.message is the empty String.

19.5.3.3Error.prototype.name#

The initial value of Error.prototype.name is "Error".

19.5.3.4Error.prototype.toString ( )#

The following steps are taken:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. Let name be ? Get(O, "name").
  4. If name is undefined, let name be "Error"; otherwise let name be ? ToString(name).
  5. Let msg be ? Get(O, "message").
  6. If msg is undefined, let msg be the empty String; otherwise let msg be ? ToString(msg).
  7. If name is the empty String, return msg.
  8. If msg is the empty String, return name.
  9. Return the result of concatenating name, the code unit 0x003A (COLON), the code unit 0x0020 (SPACE), and msg.

19.5.4Properties of Error Instances#

Error instances are ordinary objects that inherit properties from the Error prototype object and have an [[ErrorData]] internal slot whose value is undefined. The only specified uses of [[ErrorData]] is to identify Error and NativeError instances as Error objects within Object.prototype.toString.

19.5.5Native Error Types Used in This Standard#

A new instance of one of the NativeError objects below is thrown when a runtime error is detected. All of these objects share the same structure, as described in 19.5.6.

19.5.5.1EvalError#

This exception is not currently used within this specification. This object remains for compatibility with previous editions of this specification.

19.5.5.2RangeError#

Indicates a value that is not in the set or range of allowable values.

19.5.5.3ReferenceError#

Indicate that an invalid reference value has been detected.

19.5.5.4SyntaxError#

Indicates that a parsing error has occurred.

19.5.5.5TypeError#

TypeError is used to indicate an unsuccessful operation when none of the other NativeError objects are an appropriate indication of the failure cause.

19.5.5.6URIError#

Indicates that one of the global URI handling functions was used in a way that is incompatible with its definition.

19.5.6NativeError Object Structure#

When an ECMAScript implementation detects a runtime error, it throws a new instance of one of the NativeError objects defined in 19.5.5. Each of these objects has the structure described below, differing only in the name used as the constructor name instead of NativeError, in the name property of the prototype object, and in the implementation-defined message property of the prototype object.

For each error object, references to NativeError in the definition should be replaced with the appropriate error object name from 19.5.5.

19.5.6.1NativeError Constructors#

When a NativeError constructor is called as a function rather than as a constructor, it creates and initializes a new NativeError object. A call of the object as a function is equivalent to calling it as a constructor with the same arguments. Thus the function call NativeError(…) is equivalent to the object creation expression new NativeError(…) with the same arguments.

Each NativeError constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified NativeError behaviour must include a super call to the NativeError constructor to create and initialize subclass instances with a [[ErrorData]] internal slot.

19.5.6.1.1NativeError ( message )#

When a NativeError function is called with argument message, the following steps are taken:

  1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
  2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%NativeErrorPrototype%", « [[ErrorData]] »).
  3. If message is not undefined, then
    1. Let msg be ? ToString(message).
    2. Let msgDesc be the PropertyDescriptor{[[Value]]: msg, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}.
    3. Perform ! DefinePropertyOrThrow(O, "message", msgDesc).
  4. Return O.

The actual value of the string passed in step 2 is either "%EvalErrorPrototype%", "%RangeErrorPrototype%", "%ReferenceErrorPrototype%", "%SyntaxErrorPrototype%", "%TypeErrorPrototype%", or "%URIErrorPrototype%" corresponding to which NativeError constructor is being defined.

19.5.6.2Properties of the NativeError Constructors#

The value of the [[Prototype]] internal slot of a NativeError constructor is the intrinsic object %Error%.

Each NativeError constructor has a name property whose value is the String value `"NativeError"`.

Each NativeError constructor has the following properties:

19.5.6.2.1NativeError.prototype#

The initial value of NativeError.prototype is a NativeError prototype object (19.5.6.3). Each NativeError constructor has a distinct prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.5.6.3Properties of the NativeError Prototype Objects#

Each NativeError prototype object is an ordinary object. It is not an Error instance and does not have an [[ErrorData]] internal slot.

The value of the [[Prototype]] internal slot of each NativeError prototype object is the intrinsic object %ErrorPrototype%.

19.5.6.3.1NativeError.prototype.constructor#

The initial value of the constructor property of the prototype for a given NativeError constructor is the corresponding intrinsic object %NativeError% (19.5.6.1).

19.5.6.3.2NativeError.prototype.message#

The initial value of the message property of the prototype for a given NativeError constructor is the empty String.

19.5.6.3.3NativeError.prototype.name#

The initial value of the name property of the prototype for a given NativeError constructor is a string consisting of the name of the constructor (the name used instead of NativeError).

19.5.6.4Properties of NativeError Instances#

NativeError instances are ordinary objects that inherit properties from their NativeError prototype object and have an [[ErrorData]] internal slot whose value is undefined. The only specified use of [[ErrorData]] is by Object.prototype.toString (19.1.3.6) to identify Error or NativeError instances.

20Numbers and Dates#

20.1Number Objects#

20.1.1The Number Constructor#

The Number constructor is the %Number% intrinsic object and the initial value of the Number property of the global object. When called as a constructor, it creates and initializes a new Number object. When Number is called as a function rather than as a constructor, it performs a type conversion.

The Number constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Number behaviour must include a super call to the Number constructor to create and initialize the subclass instance with a [[NumberData]] internal slot.

20.1.1.1Number ( value )#

When Number is called with argument number, the following steps are taken:

  1. If no arguments were passed to this function invocation, let n be +0.
  2. Else, let n be ? ToNumber(value).
  3. If NewTarget is undefined, return n.
  4. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%NumberPrototype%", « [[NumberData]] »).
  5. Set the value of O's [[NumberData]] internal slot to n.
  6. Return O.

20.1.2Properties of the Number Constructor#

The value of the [[Prototype]] internal slot of the Number constructor is the intrinsic object %FunctionPrototype%.

The Number constructor has the following properties:

20.1.2.1Number.EPSILON#

The value of Number.EPSILON is the difference between 1 and the smallest value greater than 1 that is representable as a Number value, which is approximately 2.2204460492503130808472633361816 x 10-16.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.1.2.2Number.isFinite ( number )#

When the Number.isFinite is called with one argument number, the following steps are taken:

  1. If Type(number) is not Number, return false.
  2. If number is NaN, +∞, or -∞, return false.
  3. Otherwise, return true.

20.1.2.3Number.isInteger ( number )#

When the Number.isInteger is called with one argument number, the following steps are taken:

  1. If Type(number) is not Number, return false.
  2. If number is NaN, +∞, or -∞, return false.
  3. Let integer be ToInteger(number).
  4. If integer is not equal to number, return false.
  5. Otherwise, return true.

20.1.2.4Number.isNaN ( number )#

When the Number.isNaN is called with one argument number, the following steps are taken:

  1. If Type(number) is not Number, return false.
  2. If number is NaN, return true.
  3. Otherwise, return false.
Note

This function differs from the global isNaN function (18.2.3) in that it does not convert its argument to a Number before determining whether it is NaN.

20.1.2.5Number.isSafeInteger ( number )#

When the Number.isSafeInteger is called with one argument number, the following steps are taken:

  1. If Type(number) is not Number, return false.
  2. If number is NaN, +∞, or -∞, return false.
  3. Let integer be ToInteger(number).
  4. If integer is not equal to number, return false.
  5. If abs(integer) ≤ 253-1, return true.
  6. Otherwise, return false.

20.1.2.6Number.MAX_SAFE_INTEGER#

Note

The value of Number.MAX_SAFE_INTEGER is the largest integer n such that n and n + 1 are both exactly representable as a Number value.

The value of Number.MAX_SAFE_INTEGER is 9007199254740991 (253-1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.1.2.7Number.MAX_VALUE#

The value of Number.MAX_VALUE is the largest positive finite value of the Number type, which is approximately 1.7976931348623157 × 10308.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.1.2.8Number.MIN_SAFE_INTEGER#

Note

The value of Number.MIN_SAFE_INTEGER is the smallest integer n such that n and n - 1 are both exactly representable as a Number value.

The value of Number.MIN_SAFE_INTEGER is -9007199254740991 (-(253-1)).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.1.2.9Number.MIN_VALUE#

The value of Number.MIN_VALUE is the smallest positive value of the Number type, which is approximately 5 × 10-324.

In the IEEE 754-2008 double precision binary representation, the smallest possible value is a denormalized number. If an implementation does not support denormalized values, the value of Number.MIN_VALUE must be the smallest non-zero positive value that can actually be represented by the implementation.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.1.2.10Number.NaN#

The value of Number.NaN is NaN.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.1.2.11Number.NEGATIVE_INFINITY#

The value of Number.NEGATIVE_INFINITY is -∞.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.1.2.12Number.parseFloat ( string )#

The value of the Number.parseFloat data property is the same built-in function object that is the value of the parseFloat property of the global object defined in 18.2.4.

20.1.2.13Number.parseInt ( string, radix )#

The value of the Number.parseInt data property is the same built-in function object that is the value of the parseInt property of the global object defined in 18.2.5.

20.1.2.14Number.POSITIVE_INFINITY#

The value of Number.POSITIVE_INFINITY is +∞.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.1.2.15Number.prototype#

The initial value of Number.prototype is the intrinsic object %NumberPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.1.3Properties of the Number Prototype Object#

The Number prototype object is the intrinsic object %NumberPrototype%. The Number prototype object is an ordinary object. The Number prototype is itself a Number object; it has a [[NumberData]] internal slot with the value +0.

The value of the [[Prototype]] internal slot of the Number prototype object is the intrinsic object %ObjectPrototype%.

Unless explicitly stated otherwise, the methods of the Number prototype object defined below are not generic and the this value passed to them must be either a Number value or an object that has a [[NumberData]] internal slot that has been initialized to a Number value.

The abstract operation thisNumberValue(value) performs the following steps:

  1. If Type(value) is Number, return value.
  2. If Type(value) is Object and value has a [[NumberData]] internal slot, then
    1. Assert: value's [[NumberData]] internal slot is a Number value.
    2. Return the value of value's [[NumberData]] internal slot.
  3. Throw a TypeError exception.

The phrase “this Number value” within the specification of a method refers to the result returned by calling the abstract operation thisNumberValue with the this value of the method invocation passed as the argument.

20.1.3.1Number.prototype.constructor#

The initial value of Number.prototype.constructor is the intrinsic object %Number%.

20.1.3.2Number.prototype.toExponential ( fractionDigits )#

Return a String containing this Number value represented in decimal exponential notation with one digit before the significand's decimal point and fractionDigits digits after the significand's decimal point. If fractionDigits is undefined, include as many significand digits as necessary to uniquely specify the Number (just like in ToString except that in this case the Number is always output in exponential notation). Specifically, perform the following steps:

  1. Let x be ? thisNumberValue(this value).
  2. Let f be ? ToInteger(fractionDigits).
  3. Assert: f is 0, when fractionDigits is undefined.
  4. If x is NaN, return the String "NaN".
  5. Let s be the empty String.
  6. If x < 0, then
    1. Let s be "-".
    2. Let x be -x.
  7. If x = +∞, then
    1. Return the concatenation of the Strings s and "Infinity".
  8. If f < 0 or f > 20, throw a RangeError exception. However, an implementation is permitted to extend the behaviour of toExponential for values of f less than 0 or greater than 20. In this case toExponential would not necessarily throw RangeError for such values.
  9. If x = 0, then
    1. Let m be the String consisting of f+1 occurrences of the code unit 0x0030 (DIGIT ZERO).
    2. Let e be 0.
  10. Else x ≠ 0,
    1. If fractionDigits is not undefined, then
      1. Let e and n be integers such that 10fn < 10f+1 and for which the exact mathematical value of n × 10e-f - x is as close to zero as possible. If there are two such sets of e and n, pick the e and n for which n × 10e-f is larger.
    2. Else fractionDigits is undefined,
      1. Let e, n, and f be integers such that f ≥ 0, 10fn < 10f+1, the Number value for n × 10e-f is x, and f is as small as possible. Note that the decimal representation of n has f+1 digits, n is not divisible by 10, and the least significant digit of n is not necessarily uniquely determined by these criteria.
    3. Let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
  11. If f ≠ 0, then
    1. Let a be the first element of m, and let b be the remaining f elements of m.
    2. Let m be the concatenation of the three Strings a, ".", and b.
  12. If e = 0, then
    1. Let c be "+".
    2. Let d be "0".
  13. Else,
    1. If e > 0, let c be "+".
    2. Else e ≤ 0,
      1. Let c be "-".
      2. Let e be -e.
    3. Let d be the String consisting of the digits of the decimal representation of e (in order, with no leading zeroes).
  14. Let m be the concatenation of the four Strings m, "e", c, and d.
  15. Return the concatenation of the Strings s and m.

If the toExponential method is called with more than one argument, then the behaviour is undefined (see clause 17).

Note

For implementations that provide more accurate conversions than required by the rules above, it is recommended that the following alternative version of step 10.b.i be used as a guideline:

  1. Let e, n, and f be integers such that f ≥ 0, 10fn < 10f+1, the Number value for n × 10e-f is x, and f is as small as possible. If there are multiple possibilities for n, choose the value of n for which n × 10e-f is closest in value to x. If there are two such possible values of n, choose the one that is even.

20.1.3.3Number.prototype.toFixed ( fractionDigits )#

Note 1

toFixed returns a String containing this Number value represented in decimal fixed-point notation with fractionDigits digits after the decimal point. If fractionDigits is undefined, 0 is assumed.

The following steps are performed:

  1. Let x be ? thisNumberValue(this value).
  2. Let f be ? ToInteger(fractionDigits). (If fractionDigits is undefined, this step produces the value 0.)
  3. If f < 0 or f > 20, throw a RangeError exception. However, an implementation is permitted to extend the behaviour of toFixed for values of f less than 0 or greater than 20. In this case toFixed would not necessarily throw RangeError for such values.
  4. If x is NaN, return the String "NaN".
  5. Let s be the empty String.
  6. If x < 0, then
    1. Let s be "-".
    2. Let x be -x.
  7. If x ≥ 1021, then
    1. Let m be ! ToString(x).
  8. Else x < 1021,
    1. Let n be an integer for which the exact mathematical value of n ÷ 10f - x is as close to zero as possible. If there are two such n, pick the larger n.
    2. If n = 0, let m be the String "0". Otherwise, let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
    3. If f ≠ 0, then
      1. Let k be the number of elements in m.
      2. If kf, then
        1. Let z be the String consisting of f+1-k occurrences of the code unit 0x0030 (DIGIT ZERO).
        2. Let m be the concatenation of Strings z and m.
        3. Let k be f + 1.
      3. Let a be the first k-f elements of m, and let b be the remaining f elements of m.
      4. Let m be the concatenation of the three Strings a, ".", and b.
  9. Return the concatenation of the Strings s and m.

If the toFixed method is called with more than one argument, then the behaviour is undefined (see clause 17).

Note 2

The output of toFixed may be more precise than toString for some values because toString only prints enough significant digits to distinguish the number from adjacent number values. For example,

(1000000000000000128).toString() returns "1000000000000000100", while
(1000000000000000128).toFixed(0) returns "1000000000000000128".

20.1.3.4Number.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ])#

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the Number.prototype.toLocaleString method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the toLocaleString method is used.

Produces a String value that represents this Number value formatted according to the conventions of the host environment's current locale. This function is implementation-dependent, and it is permissible, but not encouraged, for it to return the same thing as toString.

The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

20.1.3.5Number.prototype.toPrecision ( precision )#

Return a String containing this Number value represented either in decimal exponential notation with one digit before the significand's decimal point and precision-1 digits after the significand's decimal point or in decimal fixed notation with precision significant digits. If precision is undefined, call ToString instead. Specifically, perform the following steps:

  1. Let x be ? thisNumberValue(this value).
  2. If precision is undefined, return ! ToString(x).
  3. Let p be ? ToInteger(precision).
  4. If x is NaN, return the String "NaN".
  5. Let s be the empty String.
  6. If x < 0, then
    1. Let s be code unit 0x002D (HYPHEN-MINUS).
    2. Let x be -x.
  7. If x = +∞, then
    1. Return the String that is the concatenation of s and "Infinity".
  8. If p < 1 or p > 21, throw a RangeError exception. However, an implementation is permitted to extend the behaviour of toPrecision for values of p less than 1 or greater than 21. In this case toPrecision would not necessarily throw RangeError for such values.
  9. If x = 0, then
    1. Let m be the String consisting of p occurrences of the code unit 0x0030 (DIGIT ZERO).
    2. Let e be 0.
  10. Else x ≠ 0,
    1. Let e and n be integers such that 10p-1n < 10p and for which the exact mathematical value of n × 10e-p+1 - x is as close to zero as possible. If there are two such sets of e and n, pick the e and n for which n × 10e-p+1 is larger.
    2. Let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
    3. If e < -6 or ep, then
      1. Assert: e ≠ 0.
      2. Let a be the first element of m, and let b be the remaining p-1 elements of m.
      3. Let m be the concatenation of a, ".", and b.
      4. If e > 0, then
        1. Let c be code unit 0x002B (PLUS SIGN).
      5. Else e < 0,
        1. Let c be code unit 0x002D (HYPHEN-MINUS).
        2. Let e be -e.
      6. Let d be the String consisting of the digits of the decimal representation of e (in order, with no leading zeroes).
      7. Return the concatenation of s, m, code unit 0x0065 (LATIN SMALL LETTER E), c, and d.
  11. If e = p-1, return the concatenation of the Strings s and m.
  12. If e ≥ 0, then
    1. Let m be the concatenation of the first e+1 elements of m, the code unit 0x002E (FULL STOP), and the remaining p- (e+1) elements of m.
  13. Else e < 0,
    1. Let m be the String formed by the concatenation of code unit 0x0030 (DIGIT ZERO), code unit 0x002E (FULL STOP), -(e+1) occurrences of code unit 0x0030 (DIGIT ZERO), and the String m.
  14. Return the String that is the concatenation of s and m.

If the toPrecision method is called with more than one argument, then the behaviour is undefined (see clause 17).

20.1.3.6Number.prototype.toString ( [ radix ] )#

Note

The optional radix should be an integer value in the inclusive range 2 to 36. If radix not present or is undefined the Number 10 is used as the value of radix.

The following steps are performed:

  1. Let x be ? thisNumberValue(this value).
  2. If radix is not present, let radixNumber be 10.
  3. Else if radix is undefined, let radixNumber be 10.
  4. Else let radixNumber be ? ToInteger(radix).
  5. If radixNumber < 2 or radixNumber > 36, throw a RangeError exception.
  6. If radixNumber = 10, return ! ToString(x).
  7. Return the String representation of this Number value using the radix specified by radixNumber. Letters a-z are used for digits with values 10 through 35. The precise algorithm is implementation-dependent, however the algorithm should be a generalization of that specified in 7.1.12.1.

The toString function is not generic; it throws a TypeError exception if its this value is not a Number or a Number object. Therefore, it cannot be transferred to other kinds of objects for use as a method.

The length property of the toString method is 1.

20.1.3.7Number.prototype.valueOf ( )#

  1. Return ? thisNumberValue(this value).

20.1.4Properties of Number Instances#

Number instances are ordinary objects that inherit properties from the Number prototype object. Number instances also have a [[NumberData]] internal slot. The [[NumberData]] internal slot is the Number value represented by this Number object.

20.2The Math Object#

The Math object is the %Math% intrinsic object and the initial value of the Math property of the global object. The Math object is a single ordinary object.

The value of the [[Prototype]] internal slot of the Math object is the intrinsic object %ObjectPrototype%.

The Math object is not a function object. It does not have a [[Construct]] internal method; it is not possible to use the Math object as a constructor with the new operator. The Math object also does not have a [[Call]] internal method; it is not possible to invoke the Math object as a function.

Note

In this specification, the phrase “the Number value for x” has a technical meaning defined in 6.1.6.

20.2.1Value Properties of the Math Object#

20.2.1.1Math.E#

The Number value for e, the base of the natural logarithms, which is approximately 2.7182818284590452354.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.2.1.2Math.LN10#

The Number value for the natural logarithm of 10, which is approximately 2.302585092994046.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.2.1.3Math.LN2#

The Number value for the natural logarithm of 2, which is approximately 0.6931471805599453.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.2.1.4Math.LOG10E#

The Number value for the base-10 logarithm of e, the base of the natural logarithms; this value is approximately 0.4342944819032518.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

The value of Math.LOG10E is approximately the reciprocal of the value of Math.LN10.

20.2.1.5Math.LOG2E#

The Number value for the base-2 logarithm of e, the base of the natural logarithms; this value is approximately 1.4426950408889634.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

The value of Math.LOG2E is approximately the reciprocal of the value of Math.LN2.

20.2.1.6Math.PI#

The Number value for π, the ratio of the circumference of a circle to its diameter, which is approximately 3.1415926535897932.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.2.1.7Math.SQRT1_2#

The Number value for the square root of ½, which is approximately 0.7071067811865476.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

The value of Math.SQRT1_2 is approximately the reciprocal of the value of Math.SQRT2.

20.2.1.8Math.SQRT2#

The Number value for the square root of 2, which is approximately 1.4142135623730951.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.2.1.9Math [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "Math".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

20.2.2Function Properties of the Math Object#

Each of the following Math object functions applies the ToNumber abstract operation to each of its arguments (in left-to-right order if there is more than one). If ToNumber returns an abrupt completion, that Completion Record is immediately returned. Otherwise, the function performs a computation on the resulting Number value(s). The value returned by each function is a Number.

In the function descriptions below, the symbols NaN, -0, +0, -∞ and +∞ refer to the Number values described in 6.1.6.

Note

The behaviour of the functions acos, acosh, asin, asinh, atan, atanh, atan2, cbrt, cos, cosh, exp, expm1, hypot, log,log1p, log2, log10, pow, random, sin, sinh, sqrt, tan, and tanh is not precisely specified here except to require specific results for certain argument values that represent boundary cases of interest. For other argument values, these functions are intended to compute approximations to the results of familiar mathematical functions, but some latitude is allowed in the choice of approximation algorithms. The general intent is that an implementer should be able to use the same mathematical library for ECMAScript on a given hardware platform that is available to C programmers on that platform.

Although the choice of algorithms is left to the implementation, it is recommended (but not specified by this standard) that implementations use the approximation algorithms for IEEE 754-2008 arithmetic contained in fdlibm, the freely distributable mathematical library from Sun Microsystems (http://www.netlib.org/fdlibm).

20.2.2.1Math.abs ( x )#

Returns the absolute value of x; the result has the same magnitude as x but has positive sign.

  • If x is NaN, the result is NaN.
  • If x is -0, the result is +0.
  • If x is -∞, the result is +∞.

20.2.2.2Math.acos ( x )#

Returns an implementation-dependent approximation to the arc cosine of x. The result is expressed in radians and ranges from +0 to +π.

  • If x is NaN, the result is NaN.
  • If x is greater than 1, the result is NaN.
  • If x is less than -1, the result is NaN.
  • If x is exactly 1, the result is +0.

20.2.2.3Math.acosh ( x )#

Returns an implementation-dependent approximation to the inverse hyperbolic cosine of x.

  • If x is NaN, the result is NaN.
  • If x is less than 1, the result is NaN.
  • If x is 1, the result is +0.
  • If x is +∞, the result is +∞.

20.2.2.4Math.asin ( x )#

Returns an implementation-dependent approximation to the arc sine of x. The result is expressed in radians and ranges from -π/2 to +π/2.

  • If x is NaN, the result is NaN.
  • If x is greater than 1, the result is NaN.
  • If x is less than -1, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.

20.2.2.5Math.asinh ( x )#

Returns an implementation-dependent approximation to the inverse hyperbolic sine of x.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞, the result is +∞.
  • If x is -∞, the result is -∞.

20.2.2.6Math.atan ( x )#

Returns an implementation-dependent approximation to the arc tangent of x. The result is expressed in radians and ranges from -π/2 to +π/2.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞, the result is an implementation-dependent approximation to +π/2.
  • If x is -∞, the result is an implementation-dependent approximation to -π/2.

20.2.2.7Math.atanh ( x )#

Returns an implementation-dependent approximation to the inverse hyperbolic tangent of x.

  • If x is NaN, the result is NaN.
  • If x is less than -1, the result is NaN.
  • If x is greater than 1, the result is NaN.
  • If x is -1, the result is -∞.
  • If x is +1, the result is +∞.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.

20.2.2.8Math.atan2 ( y, x )#

Returns an implementation-dependent approximation to the arc tangent of the quotient y/x of the arguments y and x, where the signs of y and x are used to determine the quadrant of the result. Note that it is intentional and traditional for the two-argument arc tangent function that the argument named y be first and the argument named x be second. The result is expressed in radians and ranges from -π to +π.

  • If either x or y is NaN, the result is NaN.
  • If y>0 and x is +0, the result is an implementation-dependent approximation to +π/2.
  • If y>0 and x is -0, the result is an implementation-dependent approximation to +π/2.
  • If y is +0 and x>0, the result is +0.
  • If y is +0 and x is +0, the result is +0.
  • If y is +0 and x is -0, the result is an implementation-dependent approximation to +π.
  • If y is +0 and x<0, the result is an implementation-dependent approximation to +π.
  • If y is -0 and x>0, the result is -0.
  • If y is -0 and x is +0, the result is -0.
  • If y is -0 and x is -0, the result is an implementation-dependent approximation to -π.
  • If y is -0 and x<0, the result is an implementation-dependent approximation to -π.
  • If y<0 and x is +0, the result is an implementation-dependent approximation to -π/2.
  • If y<0 and x is -0, the result is an implementation-dependent approximation to -π/2.
  • If y>0 and y is finite and x is +∞, the result is +0.
  • If y>0 and y is finite and x is -∞, the result is an implementation-dependent approximation to +π.
  • If y<0 and y is finite and x is +∞, the result is -0.
  • If y<0 and y is finite and x is -∞, the result is an implementation-dependent approximation to -π.
  • If y is +∞ and x is finite, the result is an implementation-dependent approximation to +π/2.
  • If y is -∞ and x is finite, the result is an implementation-dependent approximation to -π/2.
  • If y is +∞ and x is +∞, the result is an implementation-dependent approximation to +π/4.
  • If y is +∞ and x is -∞, the result is an implementation-dependent approximation to +3π/4.
  • If y is -∞ and x is +∞, the result is an implementation-dependent approximation to -π/4.
  • If y is -∞ and x is -∞, the result is an implementation-dependent approximation to -3π/4.

20.2.2.9Math.cbrt ( x )#

Returns an implementation-dependent approximation to the cube root of x.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞, the result is +∞.
  • If x is -∞, the result is -∞.

20.2.2.10Math.ceil ( x )#

Returns the smallest (closest to -∞) Number value that is not less than x and is equal to a mathematical integer. If x is already an integer, the result is x.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞, the result is +∞.
  • If x is -∞, the result is -∞.
  • If x is less than 0 but greater than -1, the result is -0.

The value of Math.ceil(x) is the same as the value of -Math.floor(-x).

20.2.2.11Math.clz32 ( x )#

When Math.clz32 is called with one argument x, the following steps are taken:

  1. Let n be ToUint32(x).
  2. Let p be the number of leading zero bits in the 32-bit binary representation of n.
  3. Return p.
Note

If n is 0, p will be 32. If the most significant bit of the 32-bit binary encoding of n is 1, p will be 0.

20.2.2.12Math.cos ( x )#

Returns an implementation-dependent approximation to the cosine of x. The argument is expressed in radians.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is 1.
  • If x is -0, the result is 1.
  • If x is +∞, the result is NaN.
  • If x is -∞, the result is NaN.

20.2.2.13Math.cosh ( x )#

Returns an implementation-dependent approximation to the hyperbolic cosine of x.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is 1.
  • If x is -0, the result is 1.
  • If x is +∞, the result is +∞.
  • If x is -∞, the result is +∞.
Note

The value of cosh(x) is the same as (exp(x) + exp(-x))/2.

20.2.2.14Math.exp ( x )#

Returns an implementation-dependent approximation to the exponential function of x (e raised to the power of x, where e is the base of the natural logarithms).

  • If x is NaN, the result is NaN.
  • If x is +0, the result is 1.
  • If x is -0, the result is 1.
  • If x is +∞, the result is +∞.
  • If x is -∞, the result is +0.

20.2.2.15Math.expm1 ( x )#

Returns an implementation-dependent approximation to subtracting 1 from the exponential function of x (e raised to the power of x, where e is the base of the natural logarithms). The result is computed in a way that is accurate even when the value of x is close 0.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞, the result is +∞.
  • If x is -∞, the result is -1.

20.2.2.16Math.floor ( x )#

Returns the greatest (closest to +∞) Number value that is not greater than x and is equal to a mathematical integer. If x is already an integer, the result is x.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞, the result is +∞.
  • If x is -∞, the result is -∞.
  • If x is greater than 0 but less than 1, the result is +0.
Note

The value of Math.floor(x) is the same as the value of -Math.ceil(-x).

20.2.2.17Math.fround ( x )#

When Math.fround is called with argument x, the following steps are taken:

  1. If x is NaN, return NaN.
  2. If x is one of +0, -0, +∞, -∞, return x.
  3. Let x32 be the result of converting x to a value in IEEE 754-2008 binary32 format using roundTiesToEven.
  4. Let x64 be the result of converting x32 to a value in IEEE 754-2008 binary64 format.
  5. Return the ECMAScript Number value corresponding to x64.

20.2.2.18Math.hypot ( value1, value2, ...values )#

Math.hypot returns an implementation-dependent approximation of the square root of the sum of squares of its arguments.

  • If no arguments are passed, the result is +0.
  • If any argument is +∞, the result is +∞.
  • If any argument is -∞, the result is +∞.
  • If no argument is +∞ or -∞, and any argument is NaN, the result is NaN.
  • If all arguments are either +0 or -0, the result is +0.
Note

Implementations should take care to avoid the loss of precision from overflows and underflows that are prone to occur in naive implementations when this function is called with two or more arguments.

20.2.2.19Math.imul ( x, y )#

When the Math.imul is called with arguments x and y, the following steps are taken:

  1. Let a be ToUint32(x).
  2. Let b be ToUint32(y).
  3. Let product be (a × b) modulo 232.
  4. If product ≥ 231, return product - 232; otherwise return product.

20.2.2.20Math.log ( x )#

Returns an implementation-dependent approximation to the natural logarithm of x.

  • If x is NaN, the result is NaN.
  • If x is less than 0, the result is NaN.
  • If x is +0 or -0, the result is -∞.
  • If x is 1, the result is +0.
  • If x is +∞, the result is +∞.

20.2.2.21Math.log1p ( x )#

Returns an implementation-dependent approximation to the natural logarithm of 1 + x. The result is computed in a way that is accurate even when the value of x is close to zero.

  • If x is NaN, the result is NaN.
  • If x is less than -1, the result is NaN.
  • If x is -1, the result is -∞.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞, the result is +∞.

20.2.2.22Math.log10 ( x )#

Returns an implementation-dependent approximation to the base 10 logarithm of x.

  • If x is NaN, the result is NaN.
  • If x is less than 0, the result is NaN.
  • If x is +0, the result is -∞.
  • If x is -0, the result is -∞.
  • If x is 1, the result is +0.
  • If x is +∞, the result is +∞.

20.2.2.23Math.log2 ( x )#

Returns an implementation-dependent approximation to the base 2 logarithm of x.

  • If x is NaN, the result is NaN.
  • If x is less than 0, the result is NaN.
  • If x is +0, the result is -∞.
  • If x is -0, the result is -∞.
  • If x is 1, the result is +0.
  • If x is +∞, the result is +∞.

20.2.2.24Math.max ( value1, value2, ...values )#

Given zero or more arguments, calls ToNumber on each of the arguments and returns the largest of the resulting values.

  • If no arguments are given, the result is -∞.
  • If any value is NaN, the result is NaN.
  • The comparison of values to determine the largest value is done using the Abstract Relational Comparison algorithm except that +0 is considered to be larger than -0.

20.2.2.25Math.min ( value1, value2, ...values )#

Given zero or more arguments, calls ToNumber on each of the arguments and returns the smallest of the resulting values.

  • If no arguments are given, the result is +∞.
  • If any value is NaN, the result is NaN.
  • The comparison of values to determine the smallest value is done using the Abstract Relational Comparison algorithm except that +0 is considered to be larger than -0.

20.2.2.26Math.pow ( base, exponent )#

  1. Return the result of Applying the ** operator with base and exponent as specified in 12.7.3.4.

20.2.2.27Math.random ( )#

Returns a Number value with positive sign, greater than or equal to 0 but less than 1, chosen randomly or pseudo randomly with approximately uniform distribution over that range, using an implementation-dependent algorithm or strategy. This function takes no arguments.

Each Math.random function created for distinct realms must produce a distinct sequence of values from successive calls.

20.2.2.28Math.round ( x )#

Returns the Number value that is closest to x and is equal to a mathematical integer. If two integer Number values are equally close to x, then the result is the Number value that is closer to +∞. If x is already an integer, the result is x.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞, the result is +∞.
  • If x is -∞, the result is -∞.
  • If x is greater than 0 but less than 0.5, the result is +0.
  • If x is less than 0 but greater than or equal to -0.5, the result is -0.
Note 1

Math.round(3.5) returns 4, but Math.round(-3.5) returns -3.

Note 2

The value of Math.round(x) is not always the same as the value of Math.floor(x+0.5). When x is -0 or is less than 0 but greater than or equal to -0.5, Math.round(x) returns -0, but Math.floor(x+0.5) returns +0. Math.round(x) may also differ from the value of Math.floor(x+0.5)because of internal rounding when computing x+0.5.

20.2.2.29Math.sign (x)#

Returns the sign of the x, indicating whether x is positive, negative or zero.

  • If x is NaN, the result is NaN.
  • If x is -0, the result is -0.
  • If x is +0, the result is +0.
  • If x is negative and not -0, the result is -1.
  • If x is positive and not +0, the result is +1.

20.2.2.30Math.sin ( x )#

Returns an implementation-dependent approximation to the sine of x. The argument is expressed in radians.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞ or -∞, the result is NaN.

20.2.2.31Math.sinh ( x )#

Returns an implementation-dependent approximation to the hyperbolic sine of x.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞, the result is +∞.
  • If x is -∞, the result is -∞.
Note

The value of sinh(x) is the same as (exp(x) - exp(-x))/2.

20.2.2.32Math.sqrt ( x )#

Returns an implementation-dependent approximation to the square root of x.

  • If x is NaN, the result is NaN.
  • If x is less than 0, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞, the result is +∞.

20.2.2.33Math.tan ( x )#

Returns an implementation-dependent approximation to the tangent of x. The argument is expressed in radians.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞ or -∞, the result is NaN.

20.2.2.34Math.tanh ( x )#

Returns an implementation-dependent approximation to the hyperbolic tangent of x.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is +0.
  • If x is -0, the result is -0.
  • If x is +∞, the result is +1.
  • If x is -∞, the result is -1.
Note

The value of tanh(x) is the same as (exp(x) - exp(-x))/(exp(x) + exp(-x)).

20.2.2.35Math.trunc ( x )#

Returns the integral part of the number x, removing any fractional digits. If x is already an integer, the result is x.

  • If x is NaN, the result is NaN.
  • If x is -0, the result is -0.
  • If x is +0, the result is +0.
  • If x is +∞, the result is +∞.
  • If x is -∞, the result is -∞.
  • If x is greater than 0 but less than 1, the result is +0.
  • If x is less than 0 but greater than -1, the result is -0.

20.3Date Objects#

20.3.1Overview of Date Objects and Definitions of Abstract Operations#

The following functions are abstract operations that operate on time values (defined in 20.3.1.1). Note that, in every case, if any argument to one of these functions is NaN, the result will be NaN.

20.3.1.1Time Values and Time Range#

A Date object contains a Number indicating a particular instant in time to within a millisecond. Such a Number is called a time value. A time value may also be NaN, indicating that the Date object does not represent a specific instant of time.

Time is measured in ECMAScript in milliseconds since 01 January, 1970 UTC. In time values leap seconds are ignored. It is assumed that there are exactly 86,400,000 milliseconds per day. ECMAScript Number values can represent all integers from -9,007,199,254,740,992 to 9,007,199,254,740,992; this range suffices to measure times to millisecond precision for any instant that is within approximately 285,616 years, either forward or backward, from 01 January, 1970 UTC.

The actual range of times supported by ECMAScript Date objects is slightly smaller: exactly -100,000,000 days to 100,000,000 days measured relative to midnight at the beginning of 01 January, 1970 UTC. This gives a range of 8,640,000,000,000,000 milliseconds to either side of 01 January, 1970 UTC.

The exact moment of midnight at the beginning of 01 January, 1970 UTC is represented by the value +0.

20.3.1.2Day Number and Time within Day#

A given time value t belongs to day number

Day(t) = floor(t / msPerDay)

where the number of milliseconds per day is

msPerDay = 86400000

The remainder is called the time within the day:

20.3.1.3Year Number#

ECMAScript uses an extrapolated Gregorian system to map a day number to a year number and to determine the month and date within that year. In this system, leap years are precisely those which are (divisible by 4) and ((not divisible by 100) or (divisible by 400)). The number of days in year number y is therefore defined by

= 365 if (y modulo 4) ≠ 0
= 366 if (y modulo 4) = 0 and (y modulo 100) ≠ 0
= 365 if (y modulo 100) = 0 and (y modulo 400) ≠ 0
= 366 if (y modulo 400) = 0

All non-leap years have 365 days with the usual number of days per month and leap years have an extra day in February. The day number of the first day of year y is given by:

DayFromYear(y) = 365 × (y-1970) + floor((y-1969)/4) - floor((y-1901)/100) + floor((y-1601)/400)

The time value of the start of a year is:

A time value determines a year by:

YearFromTime(t) = the largest integer y (closest to positive infinity) such that TimeFromYear(y) ≤ t

The leap-year function is 1 for a time within a leap year and otherwise is zero:

= 0 if DaysInYear(YearFromTime(t)) = 365
= 1 if DaysInYear(YearFromTime(t)) = 366

20.3.1.4Month Number#

Months are identified by an integer in the range 0 to 11, inclusive. The mapping MonthFromTime(t) from a time value t to a month number is defined by:

= 0 if 0 ≤ DayWithinYear(t) < 31
= 1 if 31 ≤ DayWithinYear(t) < 59+InLeapYear(t)
= 2 if 59+InLeapYear(t) ≤ DayWithinYear(t) < 90+InLeapYear(t)
= 3 if 90+InLeapYear(t) ≤ DayWithinYear(t) < 120+InLeapYear(t)
= 4 if 120+InLeapYear(t) ≤ DayWithinYear(t) < 151+InLeapYear(t)
= 5 if 151+InLeapYear(t) ≤ DayWithinYear(t) < 181+InLeapYear(t)
= 6 if 181+InLeapYear(t) ≤ DayWithinYear(t) < 212+InLeapYear(t)
= 7 if 212+InLeapYear(t) ≤ DayWithinYear(t) < 243+InLeapYear(t)
= 8 if 243+InLeapYear(t) ≤ DayWithinYear(t) < 273+InLeapYear(t)
= 9 if 273+InLeapYear(t) ≤ DayWithinYear(t) < 304+InLeapYear(t)
= 10 if 304+InLeapYear(t) ≤ DayWithinYear(t) < 334+InLeapYear(t)
= 11 if 334+InLeapYear(t) ≤ DayWithinYear(t) < 365+InLeapYear(t)

where

A month value of 0 specifies January; 1 specifies February; 2 specifies March; 3 specifies April; 4 specifies May; 5 specifies June; 6 specifies July; 7 specifies August; 8 specifies September; 9 specifies October; 10 specifies November; and 11 specifies December. Note that MonthFromTime(0) = 0, corresponding to Thursday, 01 January, 1970.

20.3.1.5Date Number#

A date number is identified by an integer in the range 1 through 31, inclusive. The mapping DateFromTime(t) from a time value t to a date number is defined by:

= DayWithinYear(t)-30 if MonthFromTime(t)=1
= DayWithinYear(t)-303-InLeapYear(t) if MonthFromTime(t)=10
= DayWithinYear(t)-333-InLeapYear(t) if MonthFromTime(t)=11

20.3.1.6Week Day#

The weekday for a particular time value t is defined as

WeekDay(t) = (Day(t) + 4) modulo 7

A weekday value of 0 specifies Sunday; 1 specifies Monday; 2 specifies Tuesday; 3 specifies Wednesday; 4 specifies Thursday; 5 specifies Friday; and 6 specifies Saturday. Note that WeekDay(0) = 4, corresponding to Thursday, 01 January, 1970.

20.3.1.7Local Time Zone Adjustment#

An implementation of ECMAScript is expected to determine the local time zone adjustment. The local time zone adjustment is a value LocalTZA measured in milliseconds which when added to UTC represents the local standard time. Daylight saving time is not reflected by LocalTZA.

Note

It is recommended that implementations use the time zone information of the IANA Time Zone Database http://www.iana.org/time-zones/.

20.3.1.8Daylight Saving Time Adjustment#

An implementation dependent algorithm using best available information on time zones to determine the local daylight saving time adjustment DaylightSavingTA(t), measured in milliseconds. An implementation of ECMAScript is expected to make its best effort to determine the local daylight saving time adjustment.

Note

It is recommended that implementations use the time zone information of the IANA Time Zone Database http://www.iana.org/time-zones/.

20.3.1.9LocalTime ( t )#

The abstract operation LocalTime with argument t converts t from UTC to local time by performing the following steps:

  1. Return t + LocalTZA + DaylightSavingTA(t).

20.3.1.10UTC ( t )#

The abstract operation UTC with argument t converts t from local time to UTC is defined by performing the following steps:

  1. Return t - LocalTZA - DaylightSavingTA(t - LocalTZA).
Note

UTC(LocalTime(t)) is not necessarily always equal to t.

20.3.1.11Hours, Minutes, Second, and Milliseconds#

The following abstract operations are useful in decomposing time values:

where

20.3.1.12MakeTime (hour, min, sec, ms)#

The abstract operation MakeTime calculates a number of milliseconds from its four arguments, which must be ECMAScript Number values. This operator functions as follows:

  1. If hour is not finite or min is not finite or sec is not finite or ms is not finite, return NaN.
  2. Let h be ToInteger(hour).
  3. Let m be ToInteger(min).
  4. Let s be ToInteger(sec).
  5. Let milli be ToInteger(ms).
  6. Let t be h * msPerHour + m * msPerMinute + s * msPerSecond + milli, performing the arithmetic according to IEEE 754-2008 rules (that is, as if using the ECMAScript operators * and +).
  7. Return t.

20.3.1.13MakeDay (year, month, date)#

The abstract operation MakeDay calculates a number of days from its three arguments, which must be ECMAScript Number values. This operator functions as follows:

  1. If year is not finite or month is not finite or date is not finite, return NaN.
  2. Let y be ToInteger(year).
  3. Let m be ToInteger(month).
  4. Let dt be ToInteger(date).
  5. Let ym be y + floor(m / 12).
  6. Let mn be m modulo 12.
  7. Find a value t such that YearFromTime(t) is ym and MonthFromTime(t) is mn and DateFromTime(t) is 1; but if this is not possible (because some argument is out of range), return NaN.
  8. Return Day(t) + dt - 1.

20.3.1.14MakeDate (day, time)#

The abstract operation MakeDate calculates a number of milliseconds from its two arguments, which must be ECMAScript Number values. This operator functions as follows:

  1. If day is not finite or time is not finite, return NaN.
  2. Return day × msPerDay + time.

20.3.1.15TimeClip (time)#

The abstract operation TimeClip calculates a number of milliseconds from its argument, which must be an ECMAScript Number value. This operator functions as follows:

  1. If time is not finite, return NaN.
  2. If abs(time) > 8.64 × 1015, return NaN.
  3. Let clippedTime be ToInteger(time).
  4. If clippedTime is -0, let clippedTime be +0.
  5. Return clippedTime.
Note

The point of step 4 is that an implementation is permitted a choice of internal representations of time values, for example as a 64-bit signed integer or as a 64-bit floating-point value. Depending on the implementation, this internal representation may or may not distinguish -0 and +0.

20.3.1.16Date Time String Format#

ECMAScript defines a string interchange format for date-times based upon a simplification of the ISO 8601 Extended Format. The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ

Where the fields are as follows:

YYYY is the decimal digits of the year 0000 to 9999 in the Gregorian calendar.
- "-" (hyphen) appears literally twice in the string.
MM is the month of the year from 01 (January) to 12 (December).
DD is the day of the month from 01 to 31.
T "T" appears literally in the string, to indicate the beginning of the time element.
HH is the number of complete hours that have passed since midnight as two decimal digits from 00 to 24.
: ":" (colon) appears literally twice in the string.
mm is the number of complete minutes since the start of the hour as two decimal digits from 00 to 59.
ss is the number of complete seconds since the start of the minute as two decimal digits from 00 to 59.
. "." (dot) appears literally in the string.
sss is the number of complete milliseconds since the start of the second as three decimal digits.
Z is the time zone offset specified as "Z" (for UTC) or either "+" or "-" followed by a time expression HH:mm

This format includes date-only forms:

YYYY
YYYY-MM
YYYY-MM-DD
        

It also includes “date-time” forms that consist of one of the above date-only forms immediately followed by one of the following time forms with an optional time zone offset appended:

THH:mm
THH:mm:ss
THH:mm:ss.sss
        

All numbers must be base 10. If the MM or DD fields are absent "01" is used as the value. If the HH, mm, or ss fields are absent "00" is used as the value and the value of an absent sss field is "000". When the time zone offset is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.

Illegal values (out-of-bounds as well as syntax errors) in a format string means that the format string is not a valid instance of this format.

Note 1

As every day both starts and ends with midnight, the two notations 00:00 and 24:00 are available to distinguish the two midnights that can be associated with one date. This means that the following two notations refer to exactly the same point in time: 1995-02-04T24:00 and 1995-02-05T00:00

Note 2

There exists no international standard that specifies abbreviations for civil time zones like CET, EST, etc. and sometimes the same abbreviation is even used for two very different time zones. For this reason, ISO 8601 and this format specifies numeric representations of date and time.

20.3.1.16.1Extended Years#

ECMAScript requires the ability to specify 6 digit years (extended years); approximately 285,426 years, either forward or backward, from 01 January, 1970 UTC. To represent years before 0 or after 9999, ISO 8601 permits the expansion of the year representation, but only by prior agreement between the sender and the receiver. In the simplified ECMAScript format such an expanded year representation shall have 2 extra year digits and is always prefixed with a + or - sign. The year 0 is considered positive and hence prefixed with a + sign.

Note

Examples of extended years:

-283457-03-21T15:00:59.008Z

283458 B.C.

-000001-01-01T00:00:00Z

2 B.C.

+000000-01-01T00:00:00Z

1 B.C.

+000001-01-01T00:00:00Z

1 A.D.

+001970-01-01T00:00:00Z

1970 A.D.

+002009-12-15T00:00:00Z

2009 A.D.

+287396-10-12T08:59:00.992Z

287396 A.D.

20.3.2The Date Constructor#

The Date constructor is the %Date% intrinsic object and the initial value of the Date property of the global object. When called as a constructor it creates and initializes a new Date object. When Date is called as a function rather than as a constructor, it returns a String representing the current time (UTC).

The Date constructor is a single function whose behaviour is overloaded based upon the number and types of its arguments.

The Date constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Date behaviour must include a super call to the Date constructor to create and initialize the subclass instance with a [[DateValue]] internal slot.

The length property of the Date constructor function is 7.

20.3.2.1Date ( year, month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] )#

This description applies only if the Date constructor is called with at least two arguments.

When the Date function is called, the following steps are taken:

  1. Let numberOfArgs be the number of arguments passed to this function call.
  2. Assert: numberOfArgs ≥ 2.
  3. If NewTarget is not undefined, then
    1. Let y be ? ToNumber(year).
    2. Let m be ? ToNumber(month).
    3. If date is supplied, let dt be ? ToNumber(date); else let dt be 1.
    4. If hours is supplied, let h be ? ToNumber(hours); else let h be 0.
    5. If minutes is supplied, let min be ? ToNumber(minutes); else let min be 0.
    6. If seconds is supplied, let s be ? ToNumber(seconds); else let s be 0.
    7. If ms is supplied, let milli be ? ToNumber(ms); else let milli be 0.
    8. If y is not NaN and 0 ≤ ToInteger(y) ≤ 99, let yr be 1900+ToInteger(y); otherwise, let yr be y.
    9. Let finalDate be MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)).
    10. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%DatePrototype%", « [[DateValue]] »).
    11. Set the [[DateValue]] internal slot of O to TimeClip(UTC(finalDate)).
    12. Return O.
  4. Else,
    1. Let now be the Number that is the time value (UTC) identifying the current time.
    2. Return ToDateString(now).

20.3.2.2Date ( value )#

This description applies only if the Date constructor is called with exactly one argument.

When the Date function is called, the following steps are taken:

  1. Let numberOfArgs be the number of arguments passed to this function call.
  2. Assert: numberOfArgs = 1.
  3. If NewTarget is not undefined, then
    1. If Type(value) is Object and value has a [[DateValue]] internal slot, then
      1. Let tv be thisTimeValue(value).
    2. Else,
      1. Let v be ? ToPrimitive(value).
      2. If Type(v) is String, then
        1. Let tv be the result of parsing v as a date, in exactly the same manner as for the parse method (20.3.3.2). If the parse resulted in an abrupt completion, tv is the Completion Record.
        2. ReturnIfAbrupt(tv).
      3. Else,
        1. Let tv be ? ToNumber(v).
    3. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%DatePrototype%", « [[DateValue]] »).
    4. Set the [[DateValue]] internal slot of O to TimeClip(tv).
    5. Return O.
  4. Else,
    1. Let now be the Number that is the time value (UTC) identifying the current time.
    2. Return ToDateString(now).

20.3.2.3Date ( )#

This description applies only if the Date constructor is called with no arguments.

When the Date function is called, the following steps are taken:

  1. Let numberOfArgs be the number of arguments passed to this function call.
  2. Assert: numberOfArgs = 0.
  3. If NewTarget is not undefined, then
    1. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%DatePrototype%", « [[DateValue]] »).
    2. Set the [[DateValue]] internal slot of O to the time value (UTC) identifying the current time.
    3. Return O.
  4. Else,
    1. Let now be the Number that is the time value (UTC) identifying the current time.
    2. Return ToDateString(now).

20.3.3Properties of the Date Constructor#

The value of the [[Prototype]] internal slot of the Date constructor is the intrinsic object %FunctionPrototype%.

The Date constructor has the following properties:

20.3.3.1Date.now ( )#

The now function returns a Number value that is the time value designating the UTC date and time of the occurrence of the call to now.

20.3.3.2Date.parse ( string )#

The parse function applies the ToString operator to its argument. If ToString results in an abrupt completion the Completion Record is immediately returned. Otherwise, parse interprets the resulting String as a date and time; it returns a Number, the UTC time value corresponding to the date and time. The String may be interpreted as a local time, a UTC time, or a time in some other time zone, depending on the contents of the String. The function first attempts to parse the format of the String according to the rules (including extended years) called out in Date Time String Format (20.3.1.16). If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats. Unrecognizable Strings or dates containing illegal element values in the format String shall cause Date.parse to return NaN.

If x is any Date object whose milliseconds amount is zero within a particular implementation of ECMAScript, then all of the following expressions should produce the same numeric value in that implementation, if all the properties referenced have their initial values:


x.valueOf()
Date.parse(x.toString())
Date.parse(x.toUTCString())
Date.parse(x.toISOString())
        

However, the expression


Date.parse(x.toLocaleString())
        

is not required to produce the same Number value as the preceding three expressions and, in general, the value produced by Date.parse is implementation-dependent when given any String value that does not conform to the Date Time String Format (20.3.1.16) and that could not be produced in that implementation by the toString or toUTCString method.

20.3.3.3Date.prototype#

The initial value of Date.prototype is the intrinsic object %DatePrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.3.3.4Date.UTC ( year, month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] )#

When the UTC function is called with fewer than two arguments, the behaviour is implementation-dependent. When the UTC function is called with two to seven arguments, it computes the date from year, month and (optionally) date, hours, minutes, seconds and ms. The following steps are taken:

  1. Let y be ? ToNumber(year).
  2. Let m be ? ToNumber(month).
  3. If date is supplied, let dt be ? ToNumber(date); else let dt be 1.
  4. If hours is supplied, let h be ? ToNumber(hours); else let h be 0.
  5. If minutes is supplied, let min be ? ToNumber(minutes); else let min be 0.
  6. If seconds is supplied, let s be ? ToNumber(seconds); else let s be 0.
  7. If ms is supplied, let milli be ? ToNumber(ms); else let milli be 0.
  8. If y is not NaN and 0 ≤ ToInteger(y) ≤ 99, let yr be 1900+ToInteger(y); otherwise, let yr be y.
  9. Return TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))).

The length property of the UTC function is 7.

Note

The UTC function differs from the Date constructor in two ways: it returns a time value as a Number, rather than creating a Date object, and it interprets the arguments in UTC rather than as local time.

20.3.4Properties of the Date Prototype Object#

The Date prototype object is the intrinsic object %DatePrototype%. The Date prototype object is itself an ordinary object. It is not a Date instance and does not have a [[DateValue]] internal slot.

The value of the [[Prototype]] internal slot of the Date prototype object is the intrinsic object %ObjectPrototype%.

Unless explicitly defined otherwise, the methods of the Date prototype object defined below are not generic and the this value passed to them must be an object that has a [[DateValue]] internal slot that has been initialized to a time value.

The abstract operation thisTimeValue(value) performs the following steps:

  1. If Type(value) is Object and value has a [[DateValue]] internal slot, then
    1. Return the value of value's [[DateValue]] internal slot.
  2. Throw a TypeError exception.

In following descriptions of functions that are properties of the Date prototype object, the phrase “this Date object” refers to the object that is the this value for the invocation of the function. If the Type of the this value is not Object, a TypeError exception is thrown. The phrase “this time value” within the specification of a method refers to the result returned by calling the abstract operation thisTimeValue with the this value of the method invocation passed as the argument.

20.3.4.1Date.prototype.constructor#

The initial value of Date.prototype.constructor is the intrinsic object %Date%.

20.3.4.2Date.prototype.getDate ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return DateFromTime(LocalTime(t)).

20.3.4.3Date.prototype.getDay ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return WeekDay(LocalTime(t)).

20.3.4.4Date.prototype.getFullYear ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return YearFromTime(LocalTime(t)).

20.3.4.5Date.prototype.getHours ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return HourFromTime(LocalTime(t)).

20.3.4.6Date.prototype.getMilliseconds ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return msFromTime(LocalTime(t)).

20.3.4.7Date.prototype.getMinutes ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return MinFromTime(LocalTime(t)).

20.3.4.8Date.prototype.getMonth ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return MonthFromTime(LocalTime(t)).

20.3.4.9Date.prototype.getSeconds ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return SecFromTime(LocalTime(t)).

20.3.4.10Date.prototype.getTime ( )#

The following steps are performed:

  1. Return ? thisTimeValue(this value).

20.3.4.11Date.prototype.getTimezoneOffset ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return (t - LocalTime(t)) / msPerMinute.

20.3.4.12Date.prototype.getUTCDate ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return DateFromTime(t).

20.3.4.13Date.prototype.getUTCDay ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return WeekDay(t).

20.3.4.14Date.prototype.getUTCFullYear ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return YearFromTime(t).

20.3.4.15Date.prototype.getUTCHours ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return HourFromTime(t).

20.3.4.16Date.prototype.getUTCMilliseconds ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return msFromTime(t).

20.3.4.17Date.prototype.getUTCMinutes ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return MinFromTime(t).

20.3.4.18Date.prototype.getUTCMonth ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return MonthFromTime(t).

20.3.4.19Date.prototype.getUTCSeconds ( )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return SecFromTime(t).

20.3.4.20Date.prototype.setDate ( date )#

The following steps are performed:

  1. Let t be LocalTime(? thisTimeValue(this value)).
  2. Let dt be ? ToNumber(date).
  3. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)).
  4. Let u be TimeClip(UTC(newDate)).
  5. Set the [[DateValue]] internal slot of this Date object to u.
  6. Return u.

20.3.4.21Date.prototype.setFullYear ( year [ , month [ , date ] ] )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, let t be +0; otherwise, let t be LocalTime(t).
  3. Let y be ? ToNumber(year).
  4. If month is not specified, let m be MonthFromTime(t); otherwise, let m be ? ToNumber(month).
  5. If date is not specified, let dt be DateFromTime(t); otherwise, let dt be ? ToNumber(date).
  6. Let newDate be MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)).
  7. Let u be TimeClip(UTC(newDate)).
  8. Set the [[DateValue]] internal slot of this Date object to u.
  9. Return u.

The length property of the setFullYear method is 3.

Note

If month is not specified, this method behaves as if month were specified with the value getMonth(). If date is not specified, it behaves as if date were specified with the value getDate().

20.3.4.22Date.prototype.setHours ( hour [ , min [ , sec [ , ms ] ] ] )#

The following steps are performed:

  1. Let t be LocalTime(? thisTimeValue(this value)).
  2. Let h be ? ToNumber(hour).
  3. If min is not specified, let m be MinFromTime(t); otherwise, let m be ? ToNumber(min).
  4. If sec is not specified, let s be SecFromTime(t); otherwise, let s be ? ToNumber(sec).
  5. If ms is not specified, let milli be msFromTime(t); otherwise, let milli be ? ToNumber(ms).
  6. Let date be MakeDate(Day(t), MakeTime(h, m, s, milli)).
  7. Let u be TimeClip(UTC(date)).
  8. Set the [[DateValue]] internal slot of this Date object to u.
  9. Return u.

The length property of the setHours method is 4.

Note

If min is not specified, this method behaves as if min were specified with the value getMinutes(). If sec is not specified, it behaves as if sec were specified with the value getSeconds(). If ms is not specified, it behaves as if ms were specified with the value getMilliseconds().

20.3.4.23Date.prototype.setMilliseconds ( ms )#

The following steps are performed:

  1. Let t be LocalTime(? thisTimeValue(this value)).
  2. Let ms be ? ToNumber(ms).
  3. Let time be MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms).
  4. Let u be TimeClip(UTC(MakeDate(Day(t), time))).
  5. Set the [[DateValue]] internal slot of this Date object to u.
  6. Return u.

20.3.4.24Date.prototype.setMinutes ( min [ , sec [ , ms ] ] )#

The following steps are performed:

  1. Let t be LocalTime(? thisTimeValue(this value)).
  2. Let m be ? ToNumber(min).
  3. If sec is not specified, let s be SecFromTime(t); otherwise, let s be ? ToNumber(sec).
  4. If ms is not specified, let milli be msFromTime(t); otherwise, let milli be ? ToNumber(ms).
  5. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli)).
  6. Let u be TimeClip(UTC(date)).
  7. Set the [[DateValue]] internal slot of this Date object to u.
  8. Return u.

The length property of the setMinutes method is 3.

Note

If sec is not specified, this method behaves as if sec were specified with the value getSeconds(). If ms is not specified, this behaves as if ms were specified with the value getMilliseconds().

20.3.4.25Date.prototype.setMonth ( month [ , date ] )#

The following steps are performed:

  1. Let t be LocalTime(? thisTimeValue(this value)).
  2. Let m be ? ToNumber(month).
  3. If date is not specified, let dt be DateFromTime(t); otherwise, let dt be ? ToNumber(date).
  4. Let newDate be MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t)).
  5. Let u be TimeClip(UTC(newDate)).
  6. Set the [[DateValue]] internal slot of this Date object to u.
  7. Return u.

The length property of the setMonth method is 2.

Note

If date is not specified, this method behaves as if date were specified with the value getDate().

20.3.4.26Date.prototype.setSeconds ( sec [ , ms ] )#

The following steps are performed:

  1. Let t be LocalTime(? thisTimeValue(this value)).
  2. Let s be ? ToNumber(sec).
  3. If ms is not specified, let milli be msFromTime(t); otherwise, let milli be ? ToNumber(ms).
  4. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli)).
  5. Let u be TimeClip(UTC(date)).
  6. Set the [[DateValue]] internal slot of this Date object to u.
  7. Return u.

The length property of the setSeconds method is 2.

Note

If ms is not specified, this method behaves as if ms were specified with the value getMilliseconds().

20.3.4.27Date.prototype.setTime ( time )#

The following steps are performed:

  1. Perform ? thisTimeValue(this value).
  2. Let t be ? ToNumber(time).
  3. Let v be TimeClip(t).
  4. Set the [[DateValue]] internal slot of this Date object to v.
  5. Return v.

20.3.4.28Date.prototype.setUTCDate ( date )#

  1. Let t be ? thisTimeValue(this value).
  2. Let dt be ? ToNumber(date).
  3. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)).
  4. Let v be TimeClip(newDate).
  5. Set the [[DateValue]] internal slot of this Date object to v.
  6. Return v.

20.3.4.29Date.prototype.setUTCFullYear ( year [ , month [ , date ] ] )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, let t be +0.
  3. Let y be ? ToNumber(year).
  4. If month is not specified, let m be MonthFromTime(t); otherwise, let m be ? ToNumber(month).
  5. If date is not specified, let dt be DateFromTime(t); otherwise, let dt be ? ToNumber(date).
  6. Let newDate be MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)).
  7. Let v be TimeClip(newDate).
  8. Set the [[DateValue]] internal slot of this Date object to v.
  9. Return v.

The length property of the setUTCFullYear method is 3.

Note

If month is not specified, this method behaves as if month were specified with the value getUTCMonth(). If date is not specified, it behaves as if date were specified with the value getUTCDate().

20.3.4.30Date.prototype.setUTCHours ( hour [ , min [ , sec [ , ms ] ] ] )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. Let h be ? ToNumber(hour).
  3. If min is not specified, let m be MinFromTime(t); otherwise, let m be ? ToNumber(min).
  4. If sec is not specified, let s be SecFromTime(t); otherwise, let s be ? ToNumber(sec).
  5. If ms is not specified, let milli be msFromTime(t); otherwise, let milli be ? ToNumber(ms).
  6. Let newDate be MakeDate(Day(t), MakeTime(h, m, s, milli)).
  7. Let v be TimeClip(newDate).
  8. Set the [[DateValue]] internal slot of this Date object to v.
  9. Return v.

The length property of the setUTCHours method is 4.

Note

If min is not specified, this method behaves as if min were specified with the value getUTCMinutes(). If sec is not specified, it behaves as if sec were specified with the value getUTCSeconds(). If ms is not specified, it behaves as if ms were specified with the value getUTCMilliseconds().

20.3.4.31Date.prototype.setUTCMilliseconds ( ms )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. Let milli be ? ToNumber(ms).
  3. Let time be MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), milli).
  4. Let v be TimeClip(MakeDate(Day(t), time)).
  5. Set the [[DateValue]] internal slot of this Date object to v.
  6. Return v.

20.3.4.32Date.prototype.setUTCMinutes ( min [ , sec [ , ms ] ] )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. Let m be ? ToNumber(min).
  3. If sec is not specified, let s be SecFromTime(t).
  4. Else,
    1. Let s be ? ToNumber(sec).
  5. If ms is not specified, let milli be msFromTime(t).
  6. Else,
    1. Let milli be ? ToNumber(ms).
  7. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli)).
  8. Let v be TimeClip(date).
  9. Set the [[DateValue]] internal slot of this Date object to v.
  10. Return v.

The length property of the setUTCMinutes method is 3.

Note

If sec is not specified, this method behaves as if sec were specified with the value getUTCSeconds(). If ms is not specified, it function behaves as if ms were specified with the value return by getUTCMilliseconds().

20.3.4.33Date.prototype.setUTCMonth ( month [ , date ] )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. Let m be ? ToNumber(month).
  3. If date is not specified, let dt be DateFromTime(t).
  4. Else,
    1. Let dt be ? ToNumber(date).
  5. Let newDate be MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t)).
  6. Let v be TimeClip(newDate).
  7. Set the [[DateValue]] internal slot of this Date object to v.
  8. Return v.

The length property of the setUTCMonth method is 2.

Note

If date is not specified, this method behaves as if date were specified with the value getUTCDate().

20.3.4.34Date.prototype.setUTCSeconds ( sec [ , ms ] )#

The following steps are performed:

  1. Let t be ? thisTimeValue(this value).
  2. Let s be ? ToNumber(sec).
  3. If ms is not specified, let milli be msFromTime(t).
  4. Else,
    1. Let milli be ? ToNumber(ms).
  5. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli)).
  6. Let v be TimeClip(date).
  7. Set the [[DateValue]] internal slot of this Date object to v.
  8. Return v.

The length property of the setUTCSeconds method is 2.

Note

If ms is not specified, this method behaves as if ms were specified with the value getUTCMilliseconds().

20.3.4.35Date.prototype.toDateString ( )#

This function returns a String value. The contents of the String are implementation-dependent, but are intended to represent the “date” portion of the Date in the current time zone in a convenient, human-readable form.

20.3.4.36Date.prototype.toISOString ( )#

This function returns a String value representing the instance in time corresponding to this time value. The format of the String is the Date Time string format defined in 20.3.1.16. All fields are present in the String. The time zone is always UTC, denoted by the suffix Z. If this time value is not a finite Number or if the year is not a value that can be represented in that format (if necessary using extended year format), a RangeError exception is thrown.

20.3.4.37Date.prototype.toJSON ( key )#

This function provides a String representation of a Date object for use by JSON.stringify (24.3.2).

When the toJSON method is called with argument key, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let tv be ? ToPrimitive(O, hint Number).
  3. If Type(tv) is Number and tv is not finite, return null.
  4. Return ? Invoke(O, "toISOString").
Note 1

The argument is ignored.

Note 2

The toJSON function is intentionally generic; it does not require that its this value be a Date object. Therefore, it can be transferred to other kinds of objects for use as a method. However, it does require that any such object have a toISOString method.

20.3.4.38Date.prototype.toLocaleDateString ( [ reserved1 [ , reserved2 ] ] )#

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the Date.prototype.toLocaleDateString method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the toLocaleDateString method is used.

This function returns a String value. The contents of the String are implementation-dependent, but are intended to represent the “date” portion of the Date in the current time zone in a convenient, human-readable form that corresponds to the conventions of the host environment's current locale.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

20.3.4.39Date.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )#

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the Date.prototype.toLocaleString method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the toLocaleString method is used.

This function returns a String value. The contents of the String are implementation-dependent, but are intended to represent the Date in the current time zone in a convenient, human-readable form that corresponds to the conventions of the host environment's current locale.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

20.3.4.40Date.prototype.toLocaleTimeString ( [ reserved1 [ , reserved2 ] ] )#

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the Date.prototype.toLocaleTimeString method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the toLocaleTimeString method is used.

This function returns a String value. The contents of the String are implementation-dependent, but are intended to represent the “time” portion of the Date in the current time zone in a convenient, human-readable form that corresponds to the conventions of the host environment's current locale.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

20.3.4.41Date.prototype.toString ( )#

The following steps are performed:

  1. Let O be this Date object.
  2. If O does not have a [[DateValue]] internal slot, then
    1. Let tv be NaN.
  3. Else,
    1. Let tv be thisTimeValue(O).
  4. Return ToDateString(tv).
Note 1

For any Date object d whose milliseconds amount is zero, the result of Date.parse(d.toString()) is equal to d.valueOf(). See 20.3.3.2.

Note 2

The toString function is intentionally generic; it does not require that its this value be a Date object. Therefore, it can be transferred to other kinds of objects for use as a method.

20.3.4.41.1Runtime Semantics: ToDateString(tv)#

The following steps are performed:

  1. Assert: Type(tv) is Number.
  2. If tv is NaN, return "Invalid Date".
  3. Return an implementation-dependent String value that represents tv as a date and time in the current time zone using a convenient, human-readable form.

20.3.4.42Date.prototype.toTimeString ( )#

This function returns a String value. The contents of the String are implementation-dependent, but are intended to represent the “time” portion of the Date in the current time zone in a convenient, human-readable form.

20.3.4.43Date.prototype.toUTCString ( )#

This function returns a String value. The contents of the String are implementation-dependent, but are intended to represent this time value in a convenient, human-readable form in UTC.

Note

The intent is to produce a String representation of a date that is more readable than the format specified in 20.3.1.16. It is not essential that the chosen format be unambiguous or easily machine parsable. If an implementation does not have a preferred human-readable format it is recommended to use the format defined in 20.3.1.16 but with a space rather than a "T" used to separate the date and time elements.

20.3.4.44Date.prototype.valueOf ( )#

The following steps are performed:

  1. Return ? thisTimeValue(this value).

20.3.4.45Date.prototype [ @@toPrimitive ] ( hint )#

This function is called by ECMAScript language operators to convert a Date object to a primitive value. The allowed values for hint are "default", "number", and "string". Date objects, are unique among built-in ECMAScript object in that they treat "default" as being equivalent to "string", All other built-in ECMAScript objects treat "default" as being equivalent to "number".

When the @@toPrimitive method is called with argument hint, the following steps are taken:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If hint is the String value "string" or the String value "default", then
    1. Let tryFirst be "string".
  4. Else if hint is the String value "number", then
    1. Let tryFirst be "number".
  5. Else, throw a TypeError exception.
  6. Return ? OrdinaryToPrimitive(O, tryFirst).

The value of the name property of this function is "[Symbol.toPrimitive]".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

20.3.5Properties of Date Instances#

Date instances are ordinary objects that inherit properties from the Date prototype object. Date instances also have a [[DateValue]] internal slot. The [[DateValue]] internal slot is the time value represented by this Date object.

21Text Processing#

21.1String Objects#

21.1.1The String Constructor#

The String constructor is the %String% intrinsic object and the initial value of the String property of the global object. When called as a constructor it creates and initializes a new String object. When String is called as a function rather than as a constructor, it performs a type conversion.

The String constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified String behaviour must include a super call to the String constructor to create and initialize the subclass instance with a [[StringData]] internal slot.

21.1.1.1String ( value )#

When String is called with argument value, the following steps are taken:

  1. If no arguments were passed to this function invocation, let s be "".
  2. Else,
    1. If NewTarget is undefined and Type(value) is Symbol, return SymbolDescriptiveString(value).
    2. Let s be ? ToString(value).
  3. If NewTarget is undefined, return s.
  4. Return ? StringCreate(s, ? GetPrototypeFromConstructor(NewTarget, "%StringPrototype%")).

21.1.2Properties of the String Constructor#

The value of the [[Prototype]] internal slot of the String constructor is the intrinsic object %FunctionPrototype%.

The String constructor has the following properties:

21.1.2.1String.fromCharCode ( ...codeUnits )#

The String.fromCharCode function may be called with any number of arguments which form the rest parameter codeUnits. The following steps are taken:

  1. Let codeUnits be a List containing the arguments passed to this function.
  2. Let length be the number of elements in codeUnits.
  3. Let elements be a new empty List.
  4. Let nextIndex be 0.
  5. Repeat while nextIndex < length
    1. Let next be codeUnits[nextIndex].
    2. Let nextCU be ? ToUint16(next).
    3. Append nextCU to the end of elements.
    4. Let nextIndex be nextIndex + 1.
  6. Return the String value whose elements are, in order, the elements in the List elements. If length is 0, the empty string is returned.

The length property of the fromCharCode function is 1.

21.1.2.2String.fromCodePoint ( ...codePoints )#

The String.fromCodePoint function may be called with any number of arguments which form the rest parameter codePoints. The following steps are taken:

  1. Let codePoints be a List containing the arguments passed to this function.
  2. Let length be the number of elements in codePoints.
  3. Let elements be a new empty List.
  4. Let nextIndex be 0.
  5. Repeat while nextIndex < length
    1. Let next be codePoints[nextIndex].
    2. Let nextCP be ? ToNumber(next).
    3. If SameValue(nextCP, ToInteger(nextCP)) is false, throw a RangeError exception.
    4. If nextCP < 0 or nextCP > 0x10FFFF, throw a RangeError exception.
    5. Append the elements of the UTF16Encoding of nextCP to the end of elements.
    6. Let nextIndex be nextIndex + 1.
  6. Return the String value whose elements are, in order, the elements in the List elements. If length is 0, the empty string is returned.

The length property of the fromCodePoint function is 1.

21.1.2.3String.prototype#

The initial value of String.prototype is the intrinsic object %StringPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.4String.raw ( template, ...substitutions )#

The String.raw function may be called with a variable number of arguments. The first argument is template and the remainder of the arguments form the List substitutions. The following steps are taken:

  1. Let substitutions be a List consisting of all of the arguments passed to this function, starting with the second argument. If fewer than two arguments were passed, the List is empty.
  2. Let numberOfSubstitutions be the number of elements in substitutions.
  3. Let cooked be ? ToObject(template).
  4. Let raw be ? ToObject(? Get(cooked, "raw")).
  5. Let literalSegments be ? ToLength(? Get(raw, "length")).
  6. If literalSegments ≤ 0, return the empty string.
  7. Let stringElements be a new empty List.
  8. Let nextIndex be 0.
  9. Repeat
    1. Let nextKey be ! ToString(nextIndex).
    2. Let nextSeg be ? ToString(? Get(raw, nextKey)).
    3. Append in order the code unit elements of nextSeg to the end of stringElements.
    4. If nextIndex + 1 = literalSegments, then
      1. Return the String value whose code units are, in order, the elements in the List stringElements. If stringElements has no elements, the empty string is returned.
    5. If nextIndex < numberOfSubstitutions, let next be substitutions[nextIndex].
    6. Else, let next be the empty String.
    7. Let nextSub be ? ToString(next).
    8. Append in order the code unit elements of nextSub to the end of stringElements.
    9. Let nextIndex be nextIndex + 1.
Note

String.raw is intended for use as a tag function of a Tagged Template (12.3.7). When called as such, the first argument will be a well formed template object and the rest parameter will contain the substitution values.

21.1.3Properties of the String Prototype Object#

The String prototype object is the intrinsic object %StringPrototype%. The String prototype object is an ordinary object. The String prototype is itself a String object; it has a [[StringData]] internal slot with the value "".

The value of the [[Prototype]] internal slot of the String prototype object is the intrinsic object %ObjectPrototype%.

Unless explicitly stated otherwise, the methods of the String prototype object defined below are not generic and the this value passed to them must be either a String value or an object that has a [[StringData]] internal slot that has been initialized to a String value.

The abstract operation thisStringValue(value) performs the following steps:

  1. If Type(value) is String, return value.
  2. If Type(value) is Object and value has a [[StringData]] internal slot, then
    1. Assert: value's [[StringData]] internal slot is a String value.
    2. Return the value of value's [[StringData]] internal slot.
  3. Throw a TypeError exception.

The phrase “this String value” within the specification of a method refers to the result returned by calling the abstract operation thisStringValue with the this value of the method invocation passed as the argument.

21.1.3.1String.prototype.charAt ( pos )#

Note 1

Returns a single element String containing the code unit at index pos in the String value resulting from converting this object to a String. If there is no element at that index, the result is the empty String. The result is a String value, not a String object.

If pos is a value of Number type that is an integer, then the result of x.charAt(pos) is equal to the result of x.substring(pos, pos+1).

When the charAt method is called with one argument pos, the following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let position be ? ToInteger(pos).
  4. Let size be the number of elements in S.
  5. If position < 0 or positionsize, return the empty String.
  6. Return a String of length 1, containing one code unit from S, namely the code unit at index position.
Note 2

The charAt function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.2String.prototype.charCodeAt ( pos )#

Note 1

Returns a Number (a nonnegative integer less than 216) that is the code unit value of the string element at index pos in the String resulting from converting this object to a String. If there is no element at that index, the result is NaN.

When the charCodeAt method is called with one argument pos, the following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let position be ? ToInteger(pos).
  4. Let size be the number of elements in S.
  5. If position < 0 or positionsize, return NaN.
  6. Return a value of Number type, whose value is the code unit value of the element at index position in the String S.
Note 2

The charCodeAt function is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

21.1.3.3String.prototype.codePointAt ( pos )#

Note 1

Returns a nonnegative integer Number less than 1114112 (0x110000) that is the code point value of the UTF-16 encoded code point (6.1.4) starting at the string element at index pos in the String resulting from converting this object to a String. If there is no element at that index, the result is undefined. If a valid UTF-16 surrogate pair does not begin at pos, the result is the code unit at pos.

When the codePointAt method is called with one argument pos, the following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let position be ? ToInteger(pos).
  4. Let size be the number of elements in S.
  5. If position < 0 or positionsize, return undefined.
  6. Let first be the code unit value of the element at index position in the String S.
  7. If first < 0xD800 or first > 0xDBFF or position+1 = size, return first.
  8. Let second be the code unit value of the element at index position+1 in the String S.
  9. If second < 0xDC00 or second > 0xDFFF, return first.
  10. Return UTF16Decode(first, second).
Note 2

The codePointAt function is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

21.1.3.4String.prototype.concat ( ...args )#

Note 1

When the concat method is called it returns a String consisting of the code units of the this object (converted to a String) followed by the code units of each of the arguments converted to a String. The result is a String value, not a String object.

When the concat method is called with zero or more arguments, the following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let args be a List whose elements are the arguments passed to this function.
  4. Let R be S.
  5. Repeat, while args is not empty
    1. Remove the first element from args and let next be the value of that element.
    2. Let nextString be ? ToString(next).
    3. Let R be the String value consisting of the code units of the previous value of R followed by the code units of nextString.
  6. Return R.

The length property of the concat method is 1.

Note 2

The concat function is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

21.1.3.5String.prototype.constructor#

The initial value of String.prototype.constructor is the intrinsic object %String%.

21.1.3.6String.prototype.endsWith ( searchString [ , endPosition ] )#

The following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let isRegExp be ? IsRegExp(searchString).
  4. If isRegExp is true, throw a TypeError exception.
  5. Let searchStr be ? ToString(searchString).
  6. Let len be the number of elements in S.
  7. If endPosition is undefined, let pos be len, else let pos be ? ToInteger(endPosition).
  8. Let end be min(max(pos, 0), len).
  9. Let searchLength be the number of elements in searchStr.
  10. Let start be end - searchLength.
  11. If start is less than 0, return false.
  12. If the sequence of elements of S starting at start of length searchLength is the same as the full element sequence of searchStr, return true.
  13. Otherwise, return false.
Note 1

Returns true if the sequence of elements of searchString converted to a String is the same as the corresponding elements of this object (converted to a String) starting at endPosition - length(this). Otherwise returns false.

Note 2

Throwing an exception if the first argument is a RegExp is specified in order to allow future editions to define extensions that allow such argument values.

Note 3

The endsWith function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.7String.prototype.includes ( searchString [ , position ] )#

The includes method takes two arguments, searchString and position, and performs the following steps:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let isRegExp be ? IsRegExp(searchString).
  4. If isRegExp is true, throw a TypeError exception.
  5. Let searchStr be ? ToString(searchString).
  6. Let pos be ? ToInteger(position). (If position is undefined, this step produces the value 0.)
  7. Let len be the number of elements in S.
  8. Let start be min(max(pos, 0), len).
  9. Let searchLen be the number of elements in searchStr.
  10. If there exists any integer k not smaller than start such that k + searchLen is not greater than len, and for all nonnegative integers j less than searchLen, the code unit at index k+j of S is the same as the code unit at index j of searchStr, return true; but if there is no such integer k, return false.
Note 1

If searchString appears as a substring of the result of converting this object to a String, at one or more indices that are greater than or equal to position, return true; otherwise, returns false. If position is undefined, 0 is assumed, so as to search all of the String.

Note 2

Throwing an exception if the first argument is a RegExp is specified in order to allow future editions to define extensions that allow such argument values.

Note 3

The includes function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.8String.prototype.indexOf ( searchString [ , position ] )#

Note 1

If searchString appears as a substring of the result of converting this object to a String, at one or more indices that are greater than or equal to position, then the smallest such index is returned; otherwise, -1 is returned. If position is undefined, 0 is assumed, so as to search all of the String.

The indexOf method takes two arguments, searchString and position, and performs the following steps:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let searchStr be ? ToString(searchString).
  4. Let pos be ? ToInteger(position). (If position is undefined, this step produces the value 0.)
  5. Let len be the number of elements in S.
  6. Let start be min(max(pos, 0), len).
  7. Let searchLen be the number of elements in searchStr.
  8. Return the smallest possible integer k not smaller than start such that k+searchLen is not greater than len, and for all nonnegative integers j less than searchLen, the code unit at index k+j of S is the same as the code unit at index j of searchStr; but if there is no such integer k, return the value -1.
Note 2

The indexOf function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.9String.prototype.lastIndexOf ( searchString [ , position ] )#

Note 1

If searchString appears as a substring of the result of converting this object to a String at one or more indices that are smaller than or equal to position, then the greatest such index is returned; otherwise, -1 is returned. If position is undefined, the length of the String value is assumed, so as to search all of the String.

The lastIndexOf method takes two arguments, searchString and position, and performs the following steps:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let searchStr be ? ToString(searchString).
  4. Let numPos be ? ToNumber(position). (If position is undefined, this step produces the value NaN.)
  5. If numPos is NaN, let pos be +∞; otherwise, let pos be ToInteger(numPos).
  6. Let len be the number of elements in S.
  7. Let start be min(max(pos, 0), len).
  8. Let searchLen be the number of elements in searchStr.
  9. Return the largest possible nonnegative integer k not larger than start such that k+searchLen is not greater than len, and for all nonnegative integers j less than searchLen, the code unit at index k+j of S is the same as the code unit at index j of searchStr; but if there is no such integer k, return the value -1.
Note 2

The lastIndexOf function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.10String.prototype.localeCompare ( that [ , reserved1 [ , reserved2 ] ] )#

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the localeCompare method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the localeCompare method is used.

When the localeCompare method is called with argument that, it returns a Number other than NaN that represents the result of a locale-sensitive String comparison of the this value (converted to a String) with that (converted to a String). The two Strings are S and That. The two Strings are compared in an implementation-defined fashion. The result is intended to order String values in the sort order specified by a host default locale, and will be negative, zero, or positive, depending on whether S comes before That in the sort order, the Strings are equal, or S comes after That in the sort order, respectively.

Before performing the comparisons, the following steps are performed to prepare the Strings:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let That be ? ToString(that).

The meaning of the optional second and third parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not assign any other interpretation to those parameter positions.

The localeCompare method, if considered as a function of two arguments this and that, is a consistent comparison function (as defined in 22.1.3.25) on the set of all Strings.

The actual return values are implementation-defined to permit implementers to encode additional information in the value, but the function is required to define a total ordering on all Strings. This function must treat Strings that are canonically equivalent according to the Unicode standard as identical and must return 0 when comparing Strings that are considered canonically equivalent.

Note 1

The localeCompare method itself is not directly suitable as an argument to Array.prototype.sort because the latter requires a function of two arguments.

Note 2

This function is intended to rely on whatever language-sensitive comparison functionality is available to the ECMAScript environment from the host environment, and to compare according to the rules of the host environment's current locale. However, regardless of the host provided comparison capabilities, this function must treat Strings that are canonically equivalent according to the Unicode standard as identical. It is recommended that this function should not honour Unicode compatibility equivalences or decompositions. For a definition and discussion of canonical equivalence see the Unicode Standard, chapters 2 and 3, as well as Unicode Standard Annex #15, Unicode Normalization Forms (http://www.unicode.org/reports/tr15/) and Unicode Technical Note #5, Canonical Equivalence in Applications (http://www.unicode.org/notes/tn5/). Also see Unicode Technical Standard #10, Unicode Collation Algorithm (http://www.unicode.org/reports/tr10/).

Note 3

The localeCompare function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.11String.prototype.match ( regexp )#

When the match method is called with argument regexp, the following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If regexp is neither undefined nor null, then
    1. Let matcher be ? GetMethod(regexp, @@match).
    2. If matcher is not undefined, then
      1. Return ? Call(matcher, regexp, « O »).
  3. Let S be ? ToString(O).
  4. Let rx be ? RegExpCreate(regexp, undefined).
  5. Return ? Invoke(rx, @@match, « S »).
Note

The match function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.12String.prototype.normalize ( [ form ] )#

When the normalize method is called with one argument form, the following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. If form is not provided or form is undefined, let form be "NFC".
  4. Let f be ? ToString(form).
  5. If f is not one of "NFC", "NFD", "NFKC", or "NFKD", throw a RangeError exception.
  6. Let ns be the String value that is the result of normalizing S into the normalization form named by f as specified in http://www.unicode.org/reports/tr15/tr15-29.html.
  7. Return ns.
Note

The normalize function is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

21.1.3.13String.prototype.repeat ( count )#

The following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let n be ? ToInteger(count).
  4. If n < 0, throw a RangeError exception.
  5. If n is +∞, throw a RangeError exception.
  6. Let T be a String value that is made from n copies of S appended together. If n is 0, T is the empty String.
  7. Return T.
Note 1

This method creates a String consisting of the code units of the this object (converted to String) repeated count times.

Note 2

The repeat function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.14String.prototype.replace (searchValue, replaceValue )#

When the replace method is called with arguments searchValue and replaceValue, the following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If searchValue is neither undefined nor null, then
    1. Let replacer be ? GetMethod(searchValue, @@replace).
    2. If replacer is not undefined, then
      1. Return ? Call(replacer, searchValue, « O, replaceValue »).
  3. Let string be ? ToString(O).
  4. Let searchString be ? ToString(searchValue).
  5. Let functionalReplace be IsCallable(replaceValue).
  6. If functionalReplace is false, then
    1. Let replaceValue be ? ToString(replaceValue).
  7. Search string for the first occurrence of searchString and let pos be the index within string of the first code unit of the matched substring and let matched be searchString. If no occurrences of searchString were found, return string.
  8. If functionalReplace is true, then
    1. Let replValue be ? Call(replaceValue, undefined, « matched, pos, string »).
    2. Let replStr be ? ToString(replValue).
  9. Else,
    1. Let captures be a new empty List.
    2. Let replStr be GetSubstitution(matched, string, pos, captures, replaceValue).
  10. Let tailPos be pos + the number of code units in matched.
  11. Let newString be the String formed by concatenating the first pos code units of string, replStr, and the trailing substring of string starting at index tailPos. If pos is 0, the first element of the concatenation will be the empty String.
  12. Return newString.
Note

The replace function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.14.1Runtime Semantics: GetSubstitution(matched, str, position, captures, replacement)#

The abstract operation GetSubstitution performs the following steps:

  1. Assert: Type(matched) is String.
  2. Let matchLength be the number of code units in matched.
  3. Assert: Type(str) is String.
  4. Let stringLength be the number of code units in str.
  5. Assert: position is a nonnegative integer.
  6. Assert: positionstringLength.
  7. Assert: captures is a possibly empty List of Strings.
  8. Assert: Type(replacement) is String.
  9. Let tailPos be position + matchLength.
  10. Let m be the number of elements in captures.
  11. Let result be a String value derived from replacement by copying code unit elements from replacement to result while performing replacements as specified in Table 46. These $ replacements are done left-to-right, and, once such a replacement is performed, the new replacement text is not subject to further replacements.
  12. Return result.
Table 46: Replacement Text Symbol Substitutions
Code units Unicode Characters Replacement text
0x0024, 0x0024 $$ $
0x0024, 0x0026 $& matched
0x0024, 0x0060 $` If position is 0, the replacement is the empty String. Otherwise the replacement is the substring of str that starts at index 0 and whose last code unit is at index position - 1.
0x0024, 0x0027 $' If tailPosstringLength, the replacement is the empty String. Otherwise the replacement is the substring of str that starts at index tailPos and continues to the end of str.
0x0024, N
Where
0x0031 ≤ N ≤ 0x0039
$n where
n is one of 1 2 3 4 5 6 7 8 9 and $n is not followed by a decimal digit
The nth element of captures, where n is a single digit in the range 1 to 9. If nm and the nth element of captures is undefined, use the empty String instead. If n>m, the result is implementation-defined.
0x0024, N, N
Where
0x0030 ≤ N ≤ 0x0039
$nn where
n is one of 0 1 2 3 4 5 6 7 8 9
The nnth element of captures, where nn is a two-digit decimal number in the range 01 to 99. If nnm and the nnth element of captures is undefined, use the empty String instead. If nn is 00 or nn>m, the result is implementation-defined.
0x0024 $ in any context that does not match any of the above. $

21.1.3.15String.prototype.search ( regexp )#

When the search method is called with argument regexp, the following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If regexp is neither undefined nor null, then
    1. Let searcher be ? GetMethod(regexp, @@search).
    2. If searcher is not undefined, then
      1. Return ? Call(searcher, regexp, « O »).
  3. Let string be ? ToString(O).
  4. Let rx be ? RegExpCreate(regexp, undefined).
  5. Return ? Invoke(rx, @@search, « string »).
Note

The search function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.16String.prototype.slice ( start, end )#

The slice method takes two arguments, start and end, and returns a substring of the result of converting this object to a String, starting from index start and running to, but not including, index end (or through the end of the String if end is undefined). If start is negative, it is treated as sourceLength+start where sourceLength is the length of the String. If end is negative, it is treated as sourceLength+end where sourceLength is the length of the String. The result is a String value, not a String object. The following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let len be the number of elements in S.
  4. Let intStart be ? ToInteger(start).
  5. If end is undefined, let intEnd be len; else let intEnd be ? ToInteger(end).
  6. If intStart < 0, let from be max(len + intStart, 0); otherwise let from be min(intStart, len).
  7. If intEnd < 0, let to be max(len + intEnd, 0); otherwise let to be min(intEnd, len).
  8. Let span be max(to - from, 0).
  9. Return a String value containing span consecutive elements from S beginning with the element at index from.
Note

The slice function is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

21.1.3.17String.prototype.split ( separator, limit )#

Returns an Array object into which substrings of the result of converting this object to a String have been stored. The substrings are determined by searching from left to right for occurrences of separator; these occurrences are not part of any substring in the returned array, but serve to divide up the String value. The value of separator may be a String of any length or it may be an object, such as an RegExp, that has a @@split method.

When the split method is called, the following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If separator is neither undefined nor null, then
    1. Let splitter be ? GetMethod(separator, @@split).
    2. If splitter is not undefined, then
      1. Return ? Call(splitter, separator, « O, limit »).
  3. Let S be ? ToString(O).
  4. Let A be ArrayCreate(0).
  5. Let lengthA be 0.
  6. If limit is undefined, let lim be 232-1; else let lim be ? ToUint32(limit).
  7. Let s be the number of elements in S.
  8. Let p be 0.
  9. Let R be ? ToString(separator).
  10. If lim = 0, return A.
  11. If separator is undefined, then
    1. Perform ! CreateDataProperty(A, "0", S).
    2. Return A.
  12. If s = 0, then
    1. Let z be SplitMatch(S, 0, R).
    2. If z is not false, return A.
    3. Perform ! CreateDataProperty(A, "0", S).
    4. Return A.
  13. Let q be p.
  14. Repeat, while qs
    1. Let e be SplitMatch(S, q, R).
    2. If e is false, let q be q+1.
    3. Else e is an integer index ≤ s,
      1. If e = p, let q be q+1.
      2. Else ep,
        1. Let T be a String value equal to the substring of S consisting of the code units at indices p (inclusive) through q (exclusive).
        2. Perform ! CreateDataProperty(A, ! ToString(lengthA), T).
        3. Increment lengthA by 1.
        4. If lengthA = lim, return A.
        5. Let p be e.
        6. Let q be p.
  15. Let T be a String value equal to the substring of S consisting of the code units at indices p (inclusive) through s (exclusive).
  16. Perform ! CreateDataProperty(A, ! ToString(lengthA), T).
  17. Return A.
Note 1

The value of separator may be an empty String. In this case, separator does not match the empty substring at the beginning or end of the input String, nor does it match the empty substring at the end of the previous separator match. If separator is the empty String, the String is split up into individual code unit elements; the length of the result array equals the length of the String, and each substring contains one code unit.

If the this object is (or converts to) the empty String, the result depends on whether separator can match the empty String. If it can, the result array contains no elements. Otherwise, the result array contains one element, which is the empty String.

If separator is undefined, then the result array contains just one String, which is the this value (converted to a String). If limit is not undefined, then the output array is truncated so that it contains no more than limit elements.

Note 2

The split function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.17.1Runtime Semantics: SplitMatch ( S, q, R )#

The abstract operation SplitMatch takes three parameters, a String S, an integer q, and a String R, and performs the following steps in order to return either false or the end index of a match:

  1. Assert: Type(R) is String.
  2. Let r be the number of code units in R.
  3. Let s be the number of code units in S.
  4. If q+r > s, return false.
  5. If there exists an integer i between 0 (inclusive) and r (exclusive) such that the code unit at index q+i of S is different from the code unit at index i of R, return false.
  6. Return q+r.

21.1.3.18String.prototype.startsWith ( searchString [ , position ] )#

The following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let isRegExp be ? IsRegExp(searchString).
  4. If isRegExp is true, throw a TypeError exception.
  5. Let searchStr be ? ToString(searchString).
  6. Let pos be ? ToInteger(position). (If position is undefined, this step produces the value 0.)
  7. Let len be the number of elements in S.
  8. Let start be min(max(pos, 0), len).
  9. Let searchLength be the number of elements in searchStr.
  10. If searchLength+start is greater than len, return false.
  11. If the sequence of elements of S starting at start of length searchLength is the same as the full element sequence of searchStr, return true.
  12. Otherwise, return false.
Note 1

This method returns true if the sequence of elements of searchString converted to a String is the same as the corresponding elements of this object (converted to a String) starting at index position. Otherwise returns false.

Note 2

Throwing an exception if the first argument is a RegExp is specified in order to allow future editions to define extensions that allow such argument values.

Note 3

The startsWith function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.19String.prototype.substring ( start, end )#

The substring method takes two arguments, start and end, and returns a substring of the result of converting this object to a String, starting from index start and running to, but not including, index end of the String (or through the end of the String if end is undefined). The result is a String value, not a String object.

If either argument is NaN or negative, it is replaced with zero; if either argument is larger than the length of the String, it is replaced with the length of the String.

If start is larger than end, they are swapped.

The following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let len be the number of elements in S.
  4. Let intStart be ? ToInteger(start).
  5. If end is undefined, let intEnd be len; else let intEnd be ? ToInteger(end).
  6. Let finalStart be min(max(intStart, 0), len).
  7. Let finalEnd be min(max(intEnd, 0), len).
  8. Let from be min(finalStart, finalEnd).
  9. Let to be max(finalStart, finalEnd).
  10. Return a String whose length is to - from, containing code units from S, namely the code units with indices from through to - 1, in ascending order.
Note

The substring function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.20String.prototype.toLocaleLowerCase ( [ reserved1 [ , reserved2 ] ] )#

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the toLocaleLowerCase method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the toLocaleLowerCase method is used.

This function interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

This function works exactly the same as toLowerCase except that its result is intended to yield the correct result for the host environment's current locale, rather than a locale-independent result. There will only be a difference in the few cases (such as Turkish) where the rules for that language conflict with the regular Unicode case mappings.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

Note

The toLocaleLowerCase function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.21String.prototype.toLocaleUpperCase ([ reserved1 [ , reserved2 ] ] )#

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the toLocaleUpperCase method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the toLocaleUpperCase method is used.

This function interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

This function works exactly the same as toUpperCase except that its result is intended to yield the correct result for the host environment's current locale, rather than a locale-independent result. There will only be a difference in the few cases (such as Turkish) where the rules for that language conflict with the regular Unicode case mappings.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

Note

The toLocaleUpperCase function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.22String.prototype.toLowerCase ( )#

This function interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4. The following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let cpList be a List containing in order the code points as defined in 6.1.4 of S, starting at the first element of S.
  4. For each code point c in cpList, if the Unicode Character Database provides a language insensitive lower case equivalent of c, then replace c in cpList with that equivalent code point(s).
  5. Let cuList be a new empty List.
  6. For each code point c in cpList, in order, append to cuList the elements of the UTF16Encoding of c.
  7. Let L be a String whose elements are, in order, the elements of cuList.
  8. Return L.

The result must be derived according to the locale-insensitive case mappings in the Unicode Character Database (this explicitly includes not only the UnicodeData.txt file, but also all locale-insensitive mappings in the SpecialCasings.txt file that accompanies it).

Note 1

The case mapping of some code points may produce multiple code points. In this case the result String may not be the same length as the source String. Because both toUpperCase and toLowerCase have context-sensitive behaviour, the functions are not symmetrical. In other words, s.toUpperCase().toLowerCase() is not necessarily equal to s.toLowerCase().

Note 2

The toLowerCase function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.23String.prototype.toString ( )#

When the toString method is called, the following steps are taken:

  1. Return ? thisStringValue(this value).
Note

For a String object, the toString method happens to return the same thing as the valueOf method.

21.1.3.24String.prototype.toUpperCase ( )#

This function interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

This function behaves in exactly the same way as String.prototype.toLowerCase, except that code points are mapped to their uppercase equivalents as specified in the Unicode Character Database.

Note

The toUpperCase function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.25String.prototype.trim ( )#

This function interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

The following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let T be a String value that is a copy of S with both leading and trailing white space removed. The definition of white space is the union of WhiteSpace and LineTerminator. When determining whether a Unicode code point is in Unicode general category “Zs”, code unit sequences are interpreted as UTF-16 encoded code point sequences as specified in 6.1.4.
  4. Return T.
Note

The trim function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

21.1.3.26String.prototype.valueOf ( )#

When the valueOf method is called, the following steps are taken:

  1. Return ? thisStringValue(this value).

21.1.3.27String.prototype [ @@iterator ] ( )#

When the @@iterator method is called it returns an Iterator object (25.1.1.2) that iterates over the code points of a String value, returning each code point as a String value. The following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Return CreateStringIterator(S).

The value of the name property of this function is "[Symbol.iterator]".

21.1.4Properties of String Instances#

String instances are String exotic objects and have the internal methods specified for such objects. String instances inherit properties from the String prototype object. String instances also have a [[StringData]] internal slot.

String instances have a length property, and a set of enumerable properties with integer indexed names.

21.1.4.1length#

The number of elements in the String value represented by this String object.

Once a String object is initialized, this property is unchanging. It has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.5String Iterator Objects#

An String Iterator is an object, that represents a specific iteration over some specific String instance object. There is not a named constructor for String Iterator objects. Instead, String iterator objects are created by calling certain methods of String instance objects.

21.1.5.1CreateStringIterator Abstract Operation#

Several methods of String objects return Iterator objects. The abstract operation CreateStringIterator with argument string is used to create such iterator objects. It performs the following steps:

  1. Assert: Type(string) is String.
  2. Let iterator be ObjectCreate(%StringIteratorPrototype%, « [[IteratedString]], [[StringIteratorNextIndex]] »).
  3. Set iterator's [[IteratedString]] internal slot to string.
  4. Set iterator's [[StringIteratorNextIndex]] internal slot to 0.
  5. Return iterator.

21.1.5.2The %StringIteratorPrototype% Object#

All String Iterator Objects inherit properties from the %StringIteratorPrototype% intrinsic object. The %StringIteratorPrototype% object is an ordinary object and its [[Prototype]] internal slot is the %IteratorPrototype% intrinsic object. In addition, %StringIteratorPrototype% has the following properties:

21.1.5.2.1%StringIteratorPrototype%.next ( )#

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have all of the internal slots of an String Iterator Instance (21.1.5.3), throw a TypeError exception.
  4. Let s be the value of the [[IteratedString]] internal slot of O.
  5. If s is undefined, return CreateIterResultObject(undefined, true).
  6. Let position be the value of the [[StringIteratorNextIndex]] internal slot of O.
  7. Let len be the number of elements in s.
  8. If positionlen, then
    1. Set the value of the [[IteratedString]] internal slot of O to undefined.
    2. Return CreateIterResultObject(undefined, true).
  9. Let first be the code unit value at index position in s.
  10. If first < 0xD800 or first > 0xDBFF or position+1 = len, let resultString be the string consisting of the single code unit first.
  11. Else,
    1. Let second be the code unit value at index position+1 in the String S.
    2. If second < 0xDC00 or second > 0xDFFF, let resultString be the string consisting of the single code unit first.
    3. Else, let resultString be the string consisting of the code unit first followed by the code unit second.
  12. Let resultSize be the number of code units in resultString.
  13. Set the value of the [[StringIteratorNextIndex]] internal slot of O to position + resultSize.
  14. Return CreateIterResultObject(resultString, false).

21.1.5.2.2%StringIteratorPrototype% [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "String Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

21.1.5.3Properties of String Iterator Instances#

String Iterator instances are ordinary objects that inherit properties from the %StringIteratorPrototype% intrinsic object. String Iterator instances are initially created with the internal slots listed in Table 47.

Table 47: Internal Slots of String Iterator Instances
Internal Slot Description
[[IteratedString]] The String value whose elements are being iterated.
[[StringIteratorNextIndex]] The integer index of the next string index to be examined by this iteration.

21.2RegExp (Regular Expression) Objects#

A RegExp object contains a regular expression and the associated flags.

Note

The form and functionality of regular expressions is modelled after the regular expression facility in the Perl 5 programming language.

21.2.1Patterns#

The RegExp constructor applies the following grammar to the input pattern String. An error occurs if the grammar cannot interpret the String as an expansion of Pattern.

Syntax

Pattern[U]::Disjunction[?U] Disjunction[U]::Alternative[?U] Alternative[?U]|Disjunction[?U] Alternative[U]::[empty] Alternative[?U]Term[?U] Term[U]::Assertion[?U] Atom[?U] Atom[?U]Quantifier Assertion[U]::^ $ \b \B (?=Disjunction[?U]) (?!Disjunction[?U]) Quantifier::QuantifierPrefix QuantifierPrefix? QuantifierPrefix::* + ? {DecimalDigits} {DecimalDigits,} {DecimalDigits,DecimalDigits} Atom[U]::PatternCharacter . \AtomEscape[?U] CharacterClass[?U] (Disjunction[?U]) (?:Disjunction[?U]) SyntaxCharacter::one of^$\.*+?()[]{}| PatternCharacter::SourceCharacterbut not SyntaxCharacter AtomEscape[U]::DecimalEscape CharacterEscape[?U] CharacterClassEscape CharacterEscape[U]::ControlEscape cControlLetter HexEscapeSequence RegExpUnicodeEscapeSequence[?U] IdentityEscape[?U] ControlEscape::one offnrtv ControlLetter::one ofabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ RegExpUnicodeEscapeSequence[U]::[+U]uLeadSurrogate\uTrailSurrogate [+U]uLeadSurrogate [+U]uTrailSurrogate [+U]uNonSurrogate [~U]uHex4Digits [+U]u{HexDigits}

Each \u TrailSurrogate for which the choice of associated u LeadSurrogate is ambiguous shall be associated with the nearest possible u LeadSurrogate that would otherwise have no corresponding \u TrailSurrogate.

LeadSurrogate::Hex4Digitsbut only if the SV of Hex4Digits is in the inclusive range 0xD800 to 0xDBFF TrailSurrogate::Hex4Digitsbut only if the SV of Hex4Digits is in the inclusive range 0xDC00 to 0xDFFF NonSurrogate::Hex4Digitsbut only if the SV of Hex4Digits is not in the inclusive range 0xD800 to 0xDFFF IdentityEscape[U]::[+U]SyntaxCharacter [+U]/ [~U]SourceCharacterbut not UnicodeIDContinue DecimalEscape::DecimalIntegerLiteral[lookahead ∉ DecimalDigit] CharacterClassEscape::one ofdDsSwW CharacterClass[U]::[[lookahead ∉ { ^ }]ClassRanges[?U]] [^ClassRanges[?U]] ClassRanges[U]::[empty] NonemptyClassRanges[?U] NonemptyClassRanges[U]::ClassAtom[?U] ClassAtom[?U]NonemptyClassRangesNoDash[?U] ClassAtom[?U]-ClassAtom[?U]ClassRanges[?U] NonemptyClassRangesNoDash[U]::ClassAtom[?U] ClassAtomNoDash[?U]NonemptyClassRangesNoDash[?U] ClassAtomNoDash[?U]-ClassAtom[?U]ClassRanges[?U] ClassAtom[U]::- ClassAtomNoDash[?U] ClassAtomNoDash[U]::SourceCharacterbut not one of \ or ] or - \ClassEscape[?U] ClassEscape[U]::DecimalEscape b [+U]- CharacterEscape[?U] CharacterClassEscape

21.2.1.1Static Semantics: Early Errors#

RegExpUnicodeEscapeSequence::u{HexDigits}
  • It is a Syntax Error if the MV of HexDigits > 1114111.

21.2.2Pattern Semantics#

A regular expression pattern is converted into an internal procedure using the process described below. An implementation is encouraged to use more efficient algorithms than the ones listed below, as long as the results are the same. The internal procedure is used as the value of a RegExp object's [[RegExpMatcher]] internal slot.

A Pattern is either a BMP pattern or a Unicode pattern depending upon whether or not its associated flags contain a "u". A BMP pattern matches against a String interpreted as consisting of a sequence of 16-bit values that are Unicode code points in the range of the Basic Multilingual Plane. A Unicode pattern matches against a String interpreted as consisting of Unicode code points encoded using UTF-16. In the context of describing the behaviour of a BMP pattern “character” means a single 16-bit Unicode BMP code point. In the context of describing the behaviour of a Unicode pattern “character” means a UTF-16 encoded code point (6.1.4). In either context, “character value” means the numeric value of the corresponding non-encoded code point.

The syntax and semantics of Pattern is defined as if the source code for the Pattern was a List of SourceCharacter values where each SourceCharacter corresponds to a Unicode code point. If a BMP pattern contains a non-BMP SourceCharacter the entire pattern is encoded using UTF-16 and the individual code units of that encoding are used as the elements of the List.

Note

For example, consider a pattern expressed in source text as the single non-BMP character U+1D11E (MUSICAL SYMBOL G CLEF). Interpreted as a Unicode pattern, it would be a single element (character) List consisting of the single code point 0x1D11E. However, interpreted as a BMP pattern, it is first UTF-16 encoded to produce a two element List consisting of the code units 0xD834 and 0xDD1E.

Patterns are passed to the RegExp constructor as ECMAScript String values in which non-BMP characters are UTF-16 encoded. For example, the single character MUSICAL SYMBOL G CLEF pattern, expressed as a String value, is a String of length 2 whose elements were the code units 0xD834 and 0xDD1E. So no further translation of the string would be necessary to process it as a BMP pattern consisting of two pattern characters. However, to process it as a Unicode pattern UTF16Decode must be used in producing a List consisting of a single pattern character, the code point U+1D11E.

An implementation may not actually perform such translations to or from UTF-16, but the semantics of this specification requires that the result of pattern matching be as if such translations were performed.

21.2.2.1Notation#

The descriptions below use the following variables:

  • Input is a List consisting of all of the characters, in order, of the String being matched by the regular expression pattern. Each character is either a code unit or a code point, depending upon the kind of pattern involved. The notation Input[n] means the nth character of Input, where n can range between 0 (inclusive) and InputLength (exclusive).
  • InputLength is the number of characters in Input.
  • NcapturingParens is the total number of left capturing parentheses (i.e. the total number of times the Atom::(Disjunction) production is expanded) in the pattern. A left capturing parenthesis is any ( pattern character that is matched by the ( terminal of the Atom::(Disjunction) production.
  • IgnoreCase is true if the RegExp object's [[OriginalFlags]] internal slot contains "i" and otherwise is false.
  • Multiline is true if the RegExp object's [[OriginalFlags]] internal slot contains "m" and otherwise is false.
  • Unicode is true if the RegExp object's [[OriginalFlags]] internal slot contains "u" and otherwise is false.

Furthermore, the descriptions below use the following internal data structures:

  • A CharSet is a mathematical set of characters, either code units or code points depending up the state of the Unicode flag. “All characters” means either all code unit values or all code point values also depending upon the state if Unicode.
  • A State is an ordered pair (endIndex, captures) where endIndex is an integer and captures is a List of NcapturingParens values. States are used to represent partial match states in the regular expression matching algorithms. The endIndex is one plus the index of the last input character matched so far by the pattern, while captures holds the results of capturing parentheses. The nth element of captures is either a List that represents the value obtained by the nth set of capturing parentheses or undefined if the nth set of capturing parentheses hasn't been reached yet. Due to backtracking, many States may be in use at any time during the matching process.
  • A MatchResult is either a State or the special token failure that indicates that the match failed.
  • A Continuation procedure is an internal closure (i.e. an internal procedure with some arguments already bound to values) that takes one State argument and returns a MatchResult result. If an internal closure references variables which are bound in the function that creates the closure, the closure uses the values that these variables had at the time the closure was created. The Continuation attempts to match the remaining portion (specified by the closure's already-bound arguments) of the pattern against Input, starting at the intermediate state given by its State argument. If the match succeeds, the Continuation returns the final State that it reached; if the match fails, the Continuation returns failure.
  • A Matcher procedure is an internal closure that takes two arguments — a State and a Continuation — and returns a MatchResult result. A Matcher attempts to match a middle subpattern (specified by the closure's already-bound arguments) of the pattern against Input, starting at the intermediate state given by its State argument. The Continuation argument should be a closure that matches the rest of the pattern. After matching the subpattern of a pattern to obtain a new State, the Matcher then calls Continuation on that new State to test if the rest of the pattern can match as well. If it can, the Matcher returns the State returned by Continuation; if not, the Matcher may try different choices at its choice points, repeatedly calling Continuation until it either succeeds or all possibilities have been exhausted.
  • An AssertionTester procedure is an internal closure that takes a State argument and returns a Boolean result. The assertion tester tests a specific condition (specified by the closure's already-bound arguments) against the current place in Input and returns true if the condition matched or false if not.
  • An EscapeValue is either a character or an integer. An EscapeValue is used to denote the interpretation of a DecimalEscape escape sequence: a character ch means that the escape sequence is interpreted as the character ch, while an integer n means that the escape sequence is interpreted as a backreference to the nth set of capturing parentheses.

21.2.2.2Pattern#

The production Pattern::Disjunction evaluates as follows:

  1. Evaluate Disjunction to obtain a Matcher m.
  2. Return an internal closure that takes two arguments, a String str and an integer index, and performs the following steps:
    1. Assert: index ≤ the number of elements in str.
    2. If Unicode is true, let Input be a List consisting of the sequence of code points of str interpreted as a UTF-16 encoded (6.1.4) Unicode string. Otherwise, let Input be a List consisting of the sequence of code units that are the elements of str. Input will be used throughout the algorithms in 21.2.2. Each element of Input is considered to be a character.
    3. Let InputLength be the number of characters contained in Input. This variable will be used throughout the algorithms in 21.2.2.
    4. Let listIndex be the index into Input of the character that was obtained from element index of str.
    5. Let c be a Continuation that always returns its State argument as a successful MatchResult.
    6. Let cap be a List of NcapturingParens undefined values, indexed 1 through NcapturingParens.
    7. Let x be the State (listIndex, cap).
    8. Call m(x, c) and return its result.
Note

A Pattern evaluates (“compiles”) to an internal procedure value. RegExpBuiltinExec can then apply this procedure to a String and an offset within the String to determine whether the pattern would match starting at exactly that offset within the String, and, if it does match, what the values of the capturing parentheses would be. The algorithms in 21.2.2 are designed so that compiling a pattern may throw a SyntaxError exception; on the other hand, once the pattern is successfully compiled, applying the resulting internal procedure to find a match in a String cannot throw an exception (except for any host-defined exceptions that can occur anywhere such as out-of-memory).

21.2.2.3Disjunction#

The production Disjunction::Alternative evaluates by evaluating Alternative to obtain a Matcher and returning that Matcher.

The production Disjunction::Alternative|Disjunction evaluates as follows:

  1. Evaluate Alternative to obtain a Matcher m1.
  2. Evaluate Disjunction to obtain a Matcher m2.
  3. Return an internal Matcher closure that takes two arguments, a State x and a Continuation c, and performs the following steps when evaluated:
    1. Call m1(x, c) and let r be its result.
    2. If r is not failure, return r.
    3. Call m2(x, c) and return its result.
Note

The | regular expression operator separates two alternatives. The pattern first tries to match the left Alternative (followed by the sequel of the regular expression); if it fails, it tries to match the right Disjunction (followed by the sequel of the regular expression). If the left Alternative, the right Disjunction, and the sequel all have choice points, all choices in the sequel are tried before moving on to the next choice in the left Alternative. If choices in the left Alternative are exhausted, the right Disjunction is tried instead of the left Alternative. Any capturing parentheses inside a portion of the pattern skipped by | produce undefined values instead of Strings. Thus, for example,

/a|ab/.exec("abc")

returns the result "a" and not "ab". Moreover,

/((a)|(ab))((c)|(bc))/.exec("abc")

returns the array

["abc", "a", "a", undefined, "bc", undefined, "bc"]

and not

["abc", "ab", undefined, "ab", "c", "c", undefined]

21.2.2.4Alternative#

The production Alternative::[empty] evaluates by returning a Matcher that takes two arguments, a State x and a Continuation c, and returns the result of calling c(x).

The production Alternative::AlternativeTerm evaluates as follows:

  1. Evaluate Alternative to obtain a Matcher m1.
  2. Evaluate Term to obtain a Matcher m2.
  3. Return an internal Matcher closure that takes two arguments, a State x and a Continuation c, and performs the following steps when evaluated:
    1. Create a Continuation d that takes a State argument y and returns the result of calling m2(y, c).
    2. Call m1(x, d) and return its result.
Note

Consecutive Terms try to simultaneously match consecutive portions of Input. If the left Alternative, the right Term, and the sequel of the regular expression all have choice points, all choices in the sequel are tried before moving on to the next choice in the right Term, and all choices in the right Term are tried before moving on to the next choice in the left Alternative.

21.2.2.5Term#

The production Term::Assertion evaluates by returning an internal Matcher closure that takes two arguments, a State x and a Continuation c, and performs the following steps when evaluated:

  1. Evaluate Assertion to obtain an AssertionTester t.
  2. Call t(x) and let r be the resulting Boolean value.
  3. If r is false, return failure.
  4. Call c(x) and return its result.

The production Term::Atom evaluates as follows:

  1. Return the Matcher that is the result of evaluating Atom.

The production Term::AtomQuantifier evaluates as follows:

  1. Evaluate Atom to obtain a Matcher m.
  2. Evaluate Quantifier to obtain the three results: an integer min, an integer (or ∞) max, and Boolean greedy.
  3. If max is finite and less than min, throw a SyntaxError exception.
  4. Let parenIndex be the number of left capturing parentheses in the entire regular expression that occur to the left of this production expansion's Term. This is the total number of times the Atom::(Disjunction) production is expanded prior to this production's Term plus the total number of Atom::(Disjunction) productions enclosing this Term.
  5. Let parenCount be the number of left capturing parentheses in the expansion of this production's Atom. This is the total number of Atom::(Disjunction) productions enclosed by this production's Atom.
  6. Return an internal Matcher closure that takes two arguments, a State x and a Continuation c, and performs the following steps when evaluated:
    1. Call RepeatMatcher(m, min, max, greedy, x, c, parenIndex, parenCount) and return its result.

21.2.2.5.1Runtime Semantics: RepeatMatcher Abstract Operation#

The abstract operation RepeatMatcher takes eight parameters, a Matcher m, an integer min, an integer (or ∞) max, a Boolean greedy, a State x, a Continuation c, an integer parenIndex, and an integer parenCount, and performs the following steps:

  1. If max is zero, return c(x).
  2. Create an internal Continuation closure d that takes one State argument y and performs the following steps when evaluated:
    1. If min is zero and y's endIndex is equal to x's endIndex, return failure.
    2. If min is zero, let min2 be zero; otherwise let min2 be min-1.
    3. If max is ∞, let max2 be ∞; otherwise let max2 be max-1.
    4. Call RepeatMatcher(m, min2, max2, greedy, y, c, parenIndex, parenCount) and return its result.
  3. Let cap be a fresh copy of x's captures List.
  4. For every integer k that satisfies parenIndex < k and kparenIndex+parenCount, set cap[k] to undefined.
  5. Let e be x's endIndex.
  6. Let xr be the State (e, cap).
  7. If min is not zero, return m(xr, d).
  8. If greedy is false, then
    1. Call c(x) and let z be its result.
    2. If z is not failure, return z.
    3. Call m(xr, d) and return its result.
  9. Call m(xr, d) and let z be its result.
  10. If z is not failure, return z.
  11. Call c(x) and return its result.
Note 1

An Atom followed by a Quantifier is repeated the number of times specified by the Quantifier. A Quantifier can be non-greedy, in which case the Atom pattern is repeated as few times as possible while still matching the sequel, or it can be greedy, in which case the Atom pattern is repeated as many times as possible while still matching the sequel. The Atom pattern is repeated rather than the input character sequence that it matches, so different repetitions of the Atom can match different input substrings.

Note 2

If the Atom and the sequel of the regular expression all have choice points, the Atom is first matched as many (or as few, if non-greedy) times as possible. All choices in the sequel are tried before moving on to the next choice in the last repetition of Atom. All choices in the last (nth) repetition of Atom are tried before moving on to the next choice in the next-to-last (n-1)st repetition of Atom; at which point it may turn out that more or fewer repetitions of Atom are now possible; these are exhausted (again, starting with either as few or as many as possible) before moving on to the next choice in the (n-1)st repetition of Atom and so on.

Compare

/a[a-z]{2,4}/.exec("abcdefghi")

which returns "abcde" with

/a[a-z]{2,4}?/.exec("abcdefghi")

which returns "abc".

Consider also

/(aa|aabaac|ba|b|c)*/.exec("aabaac")

which, by the choice point ordering above, returns the array

["aaba", "ba"]

and not any of:


["aabaac", "aabaac"]
["aabaac", "c"]
            

The above ordering of choice points can be used to write a regular expression that calculates the greatest common divisor of two numbers (represented in unary notation). The following example calculates the gcd of 10 and 15:

"aaaaaaaaaa,aaaaaaaaaaaaaaa".replace(/^(a+)\1*,\1+$/,"$1")

which returns the gcd in unary notation "aaaaa".

Note 3

Step 4 of the RepeatMatcher clears Atom's captures each time Atom is repeated. We can see its behaviour in the regular expression

/(z)((a+)?(b+)?(c))*/.exec("zaacbbbcac")

which returns the array

["zaacbbbcac", "z", "ac", "a", undefined, "c"]

and not

["zaacbbbcac", "z", "ac", "a", "bbb", "c"]

because each iteration of the outermost * clears all captured Strings contained in the quantified Atom, which in this case includes capture Strings numbered 2, 3, 4, and 5.

Note 4

Step 1 of the RepeatMatcher's d closure states that, once the minimum number of repetitions has been satisfied, any more expansions of Atom that match the empty character sequence are not considered for further repetitions. This prevents the regular expression engine from falling into an infinite loop on patterns such as:

/(a*)*/.exec("b")

or the slightly more complicated:

/(a*)b\1+/.exec("baaaac")

which returns the array

["b", ""]

21.2.2.6Assertion#

The production Assertion::^ evaluates by returning an internal AssertionTester closure that takes a State argument x and performs the following steps when evaluated:

  1. Let e be x's endIndex.
  2. If e is zero, return true.
  3. If Multiline is false, return false.
  4. If the character Input[e-1] is one of LineTerminator, return true.
  5. Return false.
Note

Even when the y flag is used with a pattern, ^ always matches only at the beginning of Input, or (if Multiline is true) at the beginning of a line.

The production Assertion::$ evaluates by returning an internal AssertionTester closure that takes a State argument x and performs the following steps when evaluated:

  1. Let e be x's endIndex.
  2. If e is equal to InputLength, return true.
  3. If Multiline is false, return false.
  4. If the character Input[e] is one of LineTerminator, return true.
  5. Return false.

The production Assertion::\b evaluates by returning an internal AssertionTester closure that takes a State argument x and performs the following steps when evaluated:

  1. Let e be x's endIndex.
  2. Call IsWordChar(e-1) and let a be the Boolean result.
  3. Call IsWordChar(e) and let b be the Boolean result.
  4. If a is true and b is false, return true.
  5. If a is false and b is true, return true.
  6. Return false.

The production Assertion::\B evaluates by returning an internal AssertionTester closure that takes a State argument x and performs the following steps when evaluated:

  1. Let e be x's endIndex.
  2. Call IsWordChar(e-1) and let a be the Boolean result.
  3. Call IsWordChar(e) and let b be the Boolean result.
  4. If a is true and b is false, return false.
  5. If a is false and b is true, return false.
  6. Return true.

The production Assertion::(?=Disjunction) evaluates as follows:

  1. Evaluate Disjunction to obtain a Matcher m.
  2. Return an internal Matcher closure that takes two arguments, a State x and a Continuation c, and performs the following steps:
    1. Let d be a Continuation that always returns its State argument as a successful MatchResult.
    2. Call m(x, d) and let r be its result.
    3. If r is failure, return failure.
    4. Let y be r's State.
    5. Let cap be y's captures List.
    6. Let xe be x's endIndex.
    7. Let z be the State (xe, cap).
    8. Call c(z) and return its result.

The production Assertion::(?!Disjunction) evaluates as follows:

  1. Evaluate Disjunction to obtain a Matcher m.
  2. Return an internal Matcher closure that takes two arguments, a State x and a Continuation c, and performs the following steps:
    1. Let d be a Continuation that always returns its State argument as a successful MatchResult.
    2. Call m(x, d) and let r be its result.
    3. If r is not failure, return failure.
    4. Call c(x) and return its result.

21.2.2.6.1Runtime Semantics: IsWordChar Abstract Operation#

The abstract operation IsWordChar takes an integer parameter e and performs the following steps:

  1. If e is -1 or e is InputLength, return false.
  2. Let c be the character Input[e].
  3. If c is one of the sixty-three characters below, return true.
    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
    0 1 2 3 4 5 6 7 8 9 _
  4. Return false.

21.2.2.7Quantifier#

The production Quantifier::QuantifierPrefix evaluates as follows:

  1. Evaluate QuantifierPrefix to obtain the two results: an integer min and an integer (or ∞) max.
  2. Return the three results min, max, and true.

The production Quantifier::QuantifierPrefix? evaluates as follows:

  1. Evaluate QuantifierPrefix to obtain the two results: an integer min and an integer (or ∞) max.
  2. Return the three results min, max, and false.

The production QuantifierPrefix::* evaluates as follows:

  1. Return the two results 0 and ∞.

The production QuantifierPrefix::+ evaluates as follows:

  1. Return the two results 1 and ∞.

The production QuantifierPrefix::? evaluates as follows:

  1. Return the two results 0 and 1.

The production QuantifierPrefix::{DecimalDigits} evaluates as follows:

  1. Let i be the MV of DecimalDigits (see 11.8.3).
  2. Return the two results i and i.

The production QuantifierPrefix::{DecimalDigits,} evaluates as follows:

  1. Let i be the MV of DecimalDigits.
  2. Return the two results i and ∞.

The production QuantifierPrefix::{DecimalDigits,DecimalDigits} evaluates as follows:

  1. Let i be the MV of the first DecimalDigits.
  2. Let j be the MV of the second DecimalDigits.
  3. Return the two results i and j.

21.2.2.8Atom#

The production Atom::PatternCharacter evaluates as follows:

  1. Let ch be the character matched by PatternCharacter.
  2. Let A be a one-element CharSet containing the character ch.
  3. Call CharacterSetMatcher(A, false) and return its Matcher result.

The production Atom::. evaluates as follows:

  1. Let A be the set of all characters except LineTerminator.
  2. Call CharacterSetMatcher(A, false) and return its Matcher result.

The production Atom::\AtomEscape evaluates as follows:

  1. Return the Matcher that is the result of evaluating AtomEscape.

The production Atom::CharacterClass evaluates as follows:

  1. Evaluate CharacterClass to obtain a CharSet A and a Boolean invert.
  2. Call CharacterSetMatcher(A, invert) and return its Matcher result.

The production Atom::(Disjunction) evaluates as follows:

  1. Evaluate Disjunction to obtain a Matcher m.
  2. Let parenIndex be the number of left capturing parentheses in the entire regular expression that occur to the left of this production expansion's initial left parenthesis. This is the total number of times the Atom::(Disjunction) production is expanded prior to this production's Atom plus the total number of Atom::(Disjunction) productions enclosing this Atom.
  3. Return an internal Matcher closure that takes two arguments, a State x and a Continuation c, and performs the following steps:
    1. Create an internal Continuation closure d that takes one State argument y and performs the following steps:
      1. Let cap be a fresh copy of y's captures List.
      2. Let xe be x's endIndex.
      3. Let ye be y's endIndex.
      4. Let s be a fresh List whose characters are the characters of Input at indices xe (inclusive) through ye (exclusive).
      5. Set cap[parenIndex+1] to s.
      6. Let z be the State (ye, cap).
      7. Call c(z) and return its result.
    2. Call m(x, d) and return its result.

The production Atom::(?:Disjunction) evaluates as follows:

  1. Return the Matcher that is the result of evaluating Disjunction.

21.2.2.8.1Runtime Semantics: CharacterSetMatcher Abstract Operation#

The abstract operation CharacterSetMatcher takes two arguments, a CharSet A and a Boolean flag invert, and performs the following steps:

  1. Return an internal Matcher closure that takes two arguments, a State x and a Continuation c, and performs the following steps when evaluated:
    1. Let e be x's endIndex.
    2. If e is InputLength, return failure.
    3. Let ch be the character Input[e].
    4. Let cc be Canonicalize(ch).
    5. If invert is false, then
      1. If there does not exist a member a of set A such that Canonicalize(a) is cc, return failure.
    6. Else invert is true,
      1. If there exists a member a of set A such that Canonicalize(a) is cc, return failure.
    7. Let cap be x's captures List.
    8. Let y be the State (e+1, cap).
    9. Call c(y) and return its result.

21.2.2.8.2Runtime Semantics: Canonicalize ( ch )#

The abstract operation Canonicalize takes a character parameter ch and performs the following steps:

  1. If IgnoreCase is false, return ch.
  2. If Unicode is true, then
    1. If the file CaseFolding.txt of the Unicode Character Database provides a simple or common case folding mapping for ch, return the result of applying that mapping to ch.
    2. Else, return ch.
  3. Else,
    1. Assert: ch is a UTF-16 code unit.
    2. Let s be the ECMAScript String value consisting of the single code unit ch.
    3. Let u be the same result produced as if by performing the algorithm for String.prototype.toUpperCase using s as the this value.
    4. Assert: u is a String value.
    5. If u does not consist of a single code unit, return ch.
    6. Let cu be u's single code unit element.
    7. If ch's code unit value ≥ 128 and cu's code unit value < 128, return ch.
    8. Return cu.
Note 1

Parentheses of the form ( Disjunction ) serve both to group the components of the Disjunction pattern together and to save the result of the match. The result can be used either in a backreference (\ followed by a nonzero decimal number), referenced in a replace String, or returned as part of an array from the regular expression matching internal procedure. To inhibit the capturing behaviour of parentheses, use the form (?: Disjunction ) instead.

Note 2

The form (?= Disjunction ) specifies a zero-width positive lookahead. In order for it to succeed, the pattern inside Disjunction must match at the current position, but the current position is not advanced before matching the sequel. If Disjunction can match at the current position in several ways, only the first one is tried. Unlike other regular expression operators, there is no backtracking into a (?= form (this unusual behaviour is inherited from Perl). This only matters when the Disjunction contains capturing parentheses and the sequel of the pattern contains backreferences to those captures.

For example,

/(?=(a+))/.exec("baaabac")

matches the empty String immediately after the first b and therefore returns the array:

["", "aaa"]

To illustrate the lack of backtracking into the lookahead, consider:

/(?=(a+))a*b\1/.exec("baaabac")

This expression returns

["aba", "a"]

and not:

["aaaba", "a"]
Note 3

The form (?! Disjunction ) specifies a zero-width negative lookahead. In order for it to succeed, the pattern inside Disjunction must fail to match at the current position. The current position is not advanced before matching the sequel. Disjunction can contain capturing parentheses, but backreferences to them only make sense from within Disjunction itself. Backreferences to these capturing parentheses from elsewhere in the pattern always return undefined because the negative lookahead must fail for the pattern to succeed. For example,

/(.*?)a(?!(a+)b\2c)\2(.*)/.exec("baaabaac")

looks for an a not immediately followed by some positive number n of a's, a b, another n a's (specified by the first \2) and a c. The second \2 is outside the negative lookahead, so it matches against undefined and therefore always succeeds. The whole expression returns the array:

["baaabaac", "ba", undefined, "abaac"]
Note 4

In case-insignificant matches when Unicode is true, all characters are implicitly case-folded using the simple mapping provided by the Unicode standard immediately before they are compared. The simple mapping always maps to a single code point, so it does not map, for example, "ß" (U+00DF) to "SS". It may however map a code point outside the Basic Latin range to a character within, for example, "ſ" (U+017F) to "s". Such characters are not mapped if Unicode is false. This prevents Unicode code points such as U+017F and U+212A from matching regular expressions such as /[a-z]/i, but they will match /[a-z]/ui.

21.2.2.9AtomEscape#

The production AtomEscape::DecimalEscape evaluates as follows:

  1. Evaluate DecimalEscape to obtain an EscapeValue E.
  2. If E is a character, then
    1. Let ch be E's character.
    2. Let A be a one-element CharSet containing the character ch.
    3. Call CharacterSetMatcher(A, false) and return its Matcher result.
  3. Assert: E must be an integer.
  4. Let n be that integer.
  5. If n=0 or n>NcapturingParens, throw a SyntaxError exception.
  6. Return an internal Matcher closure that takes two arguments, a State x and a Continuation c, and performs the following steps:
    1. Let cap be x's captures List.
    2. Let s be cap[n].
    3. If s is undefined, return c(x).
    4. Let e be x's endIndex.
    5. Let len be s's length.
    6. Let f be e+len.
    7. If f>InputLength, return failure.
    8. If there exists an integer i between 0 (inclusive) and len (exclusive) such that Canonicalize(s[i]) is not the same character value as Canonicalize(Input[e+i]), return failure.
    9. Let y be the State (f, cap).
    10. Call c(y) and return its result.

The production AtomEscape::CharacterEscape evaluates as follows:

  1. Evaluate CharacterEscape to obtain a character ch.
  2. Let A be a one-element CharSet containing the character ch.
  3. Call CharacterSetMatcher(A, false) and return its Matcher result.

The production AtomEscape::CharacterClassEscape evaluates as follows:

  1. Evaluate CharacterClassEscape to obtain a CharSet A.
  2. Call CharacterSetMatcher(A, false) and return its Matcher result.
Note

An escape sequence of the form \ followed by a nonzero decimal number n matches the result of the nth set of capturing parentheses (see 0). It is an error if the regular expression has fewer than n capturing parentheses. If the regular expression has n or more capturing parentheses but the nth one is undefined because it has not captured anything, then the backreference always succeeds.

21.2.2.10CharacterEscape#

The production CharacterEscape::ControlEscape evaluates by returning the character according to Table 48.

Table 48: ControlEscape Character Values
ControlEscape Character Value Code Point Unicode Name Symbol
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>

The production CharacterEscape::cControlLetter evaluates as follows:

  1. Let ch be the character matched by ControlLetter.
  2. Let i be ch's character value.
  3. Let j be the remainder of dividing i by 32.
  4. Return the character whose character value is j.

The production CharacterEscape::HexEscapeSequence evaluates as follows:

  1. Return the character whose code is the SV of HexEscapeSequence.

The production CharacterEscape::RegExpUnicodeEscapeSequence evaluates as follows:

  1. Return the result of evaluating RegExpUnicodeEscapeSequence.

The production CharacterEscape::IdentityEscape evaluates as follows:

  1. Return the character matched by IdentityEscape.

The production RegExpUnicodeEscapeSequence::uLeadSurrogate\uTrailSurrogate evaluates as follows:

  1. Let lead be the result of evaluating LeadSurrogate.
  2. Let trail be the result of evaluating TrailSurrogate.
  3. Let cp be UTF16Decode(lead, trail).
  4. Return the character whose character value is cp.

The production RegExpUnicodeEscapeSequence::uLeadSurrogate evaluates as follows:

  1. Return the character whose code is the result of evaluating LeadSurrogate.

The production RegExpUnicodeEscapeSequence::uTrailSurrogate evaluates as follows:

  1. Return the character whose code is the result of evaluating TrailSurrogate.

The production RegExpUnicodeEscapeSequence::uNonSurrogate evaluates as follows:

  1. Return the character whose code is the result of evaluating NonSurrogate.

The production RegExpUnicodeEscapeSequence::uHex4Digits evaluates as follows:

  1. Return the character whose code is the SV of Hex4Digits.

The production RegExpUnicodeEscapeSequence::u{HexDigits} evaluates as follows:

  1. Return the character whose code is the MV of HexDigits.

The production LeadSurrogate::Hex4Digits evaluates as follows:

  1. Return the character whose code is the SV of Hex4Digits.

The production TrailSurrogate::Hex4Digits evaluates as follows:

  1. Return the character whose code is the SV of Hex4Digits.

The production NonSurrogate::Hex4Digits evaluates as follows:

  1. Return the character whose code is the SV of Hex4Digits.

21.2.2.11DecimalEscape#

The production DecimalEscape::DecimalIntegerLiteral evaluates as follows:

  1. Let i be the MV of DecimalIntegerLiteral.
  2. If i is zero, return the EscapeValue consisting of the character U+0000 (NULL).
  3. Return the EscapeValue consisting of the integer i.

The definition of “the MV of DecimalIntegerLiteral” is in 11.8.3.

Note

If \ is followed by a decimal number n whose first digit is not 0, then the escape sequence is considered to be a backreference. It is an error if n is greater than the total number of left capturing parentheses in the entire regular expression. \0 represents the <NUL> character and cannot be followed by a decimal digit.

21.2.2.12CharacterClassEscape#

The production CharacterClassEscape::d evaluates by returning the ten-element set of characters containing the characters 0 through 9 inclusive.

The production CharacterClassEscape::D evaluates by returning the set of all characters not included in the set returned by CharacterClassEscape::d .

The production CharacterClassEscape::s evaluates by returning the set of characters containing the characters that are on the right-hand side of the WhiteSpace or LineTerminator productions.

The production CharacterClassEscape::S evaluates by returning the set of all characters not included in the set returned by CharacterClassEscape::s .

The production CharacterClassEscape::w evaluates by returning the set of characters containing the sixty-three characters:

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
0 1 2 3 4 5 6 7 8 9 _

The production CharacterClassEscape::W evaluates by returning the set of all characters not included in the set returned by CharacterClassEscape::w .

21.2.2.13CharacterClass#

The production CharacterClass::[ClassRanges] evaluates by evaluating ClassRanges to obtain a CharSet and returning that CharSet and the Boolean false.

The production CharacterClass::[^ClassRanges] evaluates by evaluating ClassRanges to obtain a CharSet and returning that CharSet and the Boolean true.

21.2.2.14ClassRanges#

The production ClassRanges::[empty] evaluates by returning the empty CharSet.

The production ClassRanges::NonemptyClassRanges evaluates by evaluating NonemptyClassRanges to obtain a CharSet and returning that CharSet.

21.2.2.15NonemptyClassRanges#

The production NonemptyClassRanges::ClassAtom evaluates as follows:

  1. Return the CharSet that is the result of evaluating ClassAtom.

The production NonemptyClassRanges::ClassAtomNonemptyClassRangesNoDash evaluates as follows:

  1. Evaluate ClassAtom to obtain a CharSet A.
  2. Evaluate NonemptyClassRangesNoDash to obtain a CharSet B.
  3. Return the union of CharSets A and B.

The production NonemptyClassRanges::ClassAtom-ClassAtomClassRanges evaluates as follows:

  1. Evaluate the first ClassAtom to obtain a CharSet A.
  2. Evaluate the second ClassAtom to obtain a CharSet B.
  3. Evaluate ClassRanges to obtain a CharSet C.
  4. Call CharacterRange(A, B) and let D be the resulting CharSet.
  5. Return the union of CharSets D and C.

21.2.2.15.1Runtime Semantics: CharacterRange Abstract Operation#

The abstract operation CharacterRange takes two CharSet parameters A and B and performs the following steps:

  1. If A does not contain exactly one character or B does not contain exactly one character, throw a SyntaxError exception.
  2. Let a be the one character in CharSet A.
  3. Let b be the one character in CharSet B.
  4. Let i be the character value of character a.
  5. Let j be the character value of character b.
  6. If i > j, throw a SyntaxError exception.
  7. Return the set containing all characters numbered i through j, inclusive.

21.2.2.16NonemptyClassRangesNoDash#

The production NonemptyClassRangesNoDash::ClassAtom evaluates as follows:

  1. Return the CharSet that is the result of evaluating ClassAtom.

The production NonemptyClassRangesNoDash::ClassAtomNoDashNonemptyClassRangesNoDash evaluates as follows:

  1. Evaluate ClassAtomNoDash to obtain a CharSet A.
  2. Evaluate NonemptyClassRangesNoDash to obtain a CharSet B.
  3. Return the union of CharSets A and B.

The production NonemptyClassRangesNoDash::ClassAtomNoDash-ClassAtomClassRanges evaluates as follows:

  1. Evaluate ClassAtomNoDash to obtain a CharSet A.
  2. Evaluate ClassAtom to obtain a CharSet B.
  3. Evaluate ClassRanges to obtain a CharSet C.
  4. Call CharacterRange(A, B) and let D be the resulting CharSet.
  5. Return the union of CharSets D and C.
Note 1

ClassRanges can expand into a single ClassAtom and/or ranges of two ClassAtom separated by dashes. In the latter case the ClassRanges includes all characters between the first ClassAtom and the second ClassAtom, inclusive; an error occurs if either ClassAtom does not represent a single character (for example, if one is \w) or if the first ClassAtom's character value is greater than the second ClassAtom's character value.

Note 2

Even if the pattern ignores case, the case of the two ends of a range is significant in determining which characters belong to the range. Thus, for example, the pattern /[E-F]/i matches only the letters E, F, e, and f, while the pattern /[E-f]/i matches all upper and lower-case letters in the Unicode Basic Latin block as well as the symbols [, \, ], ^, _, and `.

Note 3

A - character can be treated literally or it can denote a range. It is treated literally if it is the first or last character of ClassRanges, the beginning or end limit of a range specification, or immediately follows a range specification.

21.2.2.17ClassAtom#

The production ClassAtom::- evaluates by returning the CharSet containing the one character -.

The production ClassAtom::ClassAtomNoDash evaluates by evaluating ClassAtomNoDash to obtain a CharSet and returning that CharSet.

21.2.2.18ClassAtomNoDash#

The production ClassAtomNoDash::SourceCharacterbut not one of \ or ] or - evaluates as follows:

  1. Return the CharSet containing the character matched by SourceCharacter.

The production ClassAtomNoDash::\ClassEscape evaluates as follows:

  1. Return the CharSet that is the result of evaluating ClassEscape.

21.2.2.19ClassEscape#

The production ClassEscape::DecimalEscape evaluates as follows:

  1. Evaluate DecimalEscape to obtain an EscapeValue E.
  2. If E is not a character, throw a SyntaxError exception.
  3. Let ch be E's character.
  4. Return the one-element CharSet containing the character ch.

The production ClassEscape::b evaluates as follows:

  1. Return the CharSet containing the single character <BS> U+0008 (BACKSPACE).

The production ClassEscape::- evaluates as follows:

  1. Return the CharSet containing the single character - U+002D (HYPHEN-MINUS).

The production ClassEscape::CharacterEscape evaluates as follows:

  1. Return the CharSet containing the single character that is the result of evaluating CharacterEscape.

The production ClassEscape::CharacterClassEscape evaluates as follows:

  1. Return the CharSet that is the result of evaluating CharacterClassEscape.
Note

A ClassAtom can use any of the escape sequences that are allowed in the rest of the regular expression except for \b, \B, and backreferences. Inside a CharacterClass, \b means the backspace character, while \B and backreferences raise errors. Using a backreference inside a ClassAtom causes an error.

21.2.3The RegExp Constructor#

The RegExp constructor is the %RegExp% intrinsic object and the initial value of the RegExp property of the global object. When RegExp is called as a function rather than as a constructor, it creates and initializes a new RegExp object. Thus the function call RegExp(…) is equivalent to the object creation expression new RegExp(…) with the same arguments.

The RegExp constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified RegExp behaviour must include a super call to the RegExp constructor to create and initialize subclass instances with the necessary internal slots.

21.2.3.1RegExp ( pattern, flags )#

The following steps are taken:

  1. Let patternIsRegExp be ? IsRegExp(pattern).
  2. If NewTarget is not undefined, let newTarget be NewTarget.
  3. Else,
    1. Let newTarget be the active function object.
    2. If patternIsRegExp is true and flags is undefined, then
      1. Let patternConstructor be ? Get(pattern, "constructor").
      2. If SameValue(newTarget, patternConstructor) is true, return pattern.
  4. If Type(pattern) is Object and pattern has a [[RegExpMatcher]] internal slot, then
    1. Let P be the value of pattern's [[OriginalSource]] internal slot.
    2. If flags is undefined, let F be the value of pattern's [[OriginalFlags]] internal slot.
    3. Else, let F be flags.
  5. Else if patternIsRegExp is true, then
    1. Let P be ? Get(pattern, "source").
    2. If flags is undefined, then
      1. Let F be ? Get(pattern, "flags").
    3. Else, let F be flags.
  6. Else,
    1. Let P be pattern.
    2. Let F be flags.
  7. Let O be ? RegExpAlloc(newTarget).
  8. Return ? RegExpInitialize(O, P, F).
Note

If pattern is supplied using a StringLiteral, the usual escape sequence substitutions are performed before the String is processed by RegExp. If pattern must contain an escape sequence to be recognized by RegExp, any U+005C (REVERSE SOLIDUS) code points must be escaped within the StringLiteral to prevent them being removed when the contents of the StringLiteral are formed.

21.2.3.2Abstract Operations for the RegExp Constructor#

21.2.3.2.1Runtime Semantics: RegExpAlloc ( newTarget )#

When the abstract operation RegExpAlloc with argument newTarget is called, the following steps are taken:

  1. Let obj be ? OrdinaryCreateFromConstructor(newTarget, "%RegExpPrototype%", « [[RegExpMatcher]], [[OriginalSource]], [[OriginalFlags]] »).
  2. Perform ! DefinePropertyOrThrow(obj, "lastIndex", PropertyDescriptor {[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  3. Return obj.

21.2.3.2.2Runtime Semantics: RegExpInitialize ( obj, pattern, flags )#

When the abstract operation RegExpInitialize with arguments obj, pattern, and flags is called, the following steps are taken:

  1. If pattern is undefined, let P be the empty String.
  2. Else, let P be ? ToString(pattern).
  3. If flags is undefined, let F be the empty String.
  4. Else, let F be ? ToString(flags).
  5. If F contains any code unit other than "g", "i", "m", "u", or "y" or if it contains the same code unit more than once, throw a SyntaxError exception.
  6. If F contains "u", let BMP be false; else let BMP be true.
  7. If BMP is true, then
    1. Parse P using the grammars in 21.2.1 and interpreting each of its 16-bit elements as a Unicode BMP code point. UTF-16 decoding is not applied to the elements. The goal symbol for the parse is Pattern. Throw a SyntaxError exception if P did not conform to the grammar, if any elements of P were not matched by the parse, or if any Early Error conditions exist.
    2. Let patternCharacters be a List whose elements are the code unit elements of P.
  8. Else,
    1. Parse P using the grammars in 21.2.1 and interpreting P as UTF-16 encoded Unicode code points (6.1.4). The goal symbol for the parse is Pattern[U]. Throw a SyntaxError exception if P did not conform to the grammar, if any elements of P were not matched by the parse, or if any Early Error conditions exist.
    2. Let patternCharacters be a List whose elements are the code points resulting from applying UTF-16 decoding to P's sequence of elements.
  9. Set the value of obj's [[OriginalSource]] internal slot to P.
  10. Set the value of obj's [[OriginalFlags]] internal slot to F.
  11. Set obj's [[RegExpMatcher]] internal slot to the internal procedure that evaluates the above parse of P by applying the semantics provided in 21.2.2 using patternCharacters as the pattern's List of SourceCharacter values and F as the flag parameters.
  12. Perform ? Set(obj, "lastIndex", 0, true).
  13. Return obj.

21.2.3.2.3Runtime Semantics: RegExpCreate ( P, F )#

When the abstract operation RegExpCreate with arguments P and F is called, the following steps are taken:

  1. Let obj be ? RegExpAlloc(%RegExp%).
  2. Return ? RegExpInitialize(obj, P, F).

21.2.3.2.4Runtime Semantics: EscapeRegExpPattern ( P, F )#

When the abstract operation EscapeRegExpPattern with arguments P and F is called, the following occurs:

  1. Let S be a String in the form of a Pattern (Pattern[U] if F contains "u") equivalent to P interpreted as UTF-16 encoded Unicode code points (6.1.4), in which certain code points are escaped as described below. S may or may not be identical to P; however, the internal procedure that would result from evaluating S as a Pattern (Pattern[U] if F contains "u") must behave identically to the internal procedure given by the constructed object's [[RegExpMatcher]] internal slot. Multiple calls to this abstract operation using the same values for P and F must produce identical results.
  2. The code points / or any LineTerminator occurring in the pattern shall be escaped in S as necessary to ensure that the String value formed by concatenating the Strings "/", S, "/", and F can be parsed (in an appropriate lexical context) as a RegularExpressionLiteral that behaves identically to the constructed regular expression. For example, if P is "/", then S could be "\/" or "\u002F", among other possibilities, but not "/", because /// followed by F would be parsed as a SingleLineComment rather than a RegularExpressionLiteral. If P is the empty String, this specification can be met by letting S be "(?:)".
  3. Return S.

21.2.4Properties of the RegExp Constructor#

The value of the [[Prototype]] internal slot of the RegExp constructor is the intrinsic object %FunctionPrototype%.

The RegExp constructor has the following properties:

21.2.4.1RegExp.prototype#

The initial value of RegExp.prototype is the intrinsic object %RegExpPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.2.4.2get RegExp [ @@species ]#

RegExp[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Return the this value.

The value of the name property of this function is "get [Symbol.species]".

Note

RegExp prototype methods normally use their this object's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its @@species property.

21.2.5Properties of the RegExp Prototype Object#

The RegExp prototype object is the intrinsic object %RegExpPrototype%. The RegExp prototype object is an ordinary object. It is not a RegExp instance and does not have a [[RegExpMatcher]] internal slot or any of the other internal slots of RegExp instance objects.

The value of the [[Prototype]] internal slot of the RegExp prototype object is the intrinsic object %ObjectPrototype%.

Note

The RegExp prototype object does not have a valueOf property of its own; however, it inherits the valueOf property from the Object prototype object.

21.2.5.1RegExp.prototype.constructor#

The initial value of RegExp.prototype.constructor is the intrinsic object %RegExp%.

21.2.5.2RegExp.prototype.exec ( string )#

Performs a regular expression match of string against the regular expression and returns an Array object containing the results of the match, or null if string did not match.

The String ToString(string) is searched for an occurrence of the regular expression pattern as follows:

  1. Let R be the this value.
  2. If Type(R) is not Object, throw a TypeError exception.
  3. If R does not have a [[RegExpMatcher]] internal slot, throw a TypeError exception.
  4. Let S be ? ToString(string).
  5. Return ? RegExpBuiltinExec(R, S).

21.2.5.2.1Runtime Semantics: RegExpExec ( R, S )#

The abstract operation RegExpExec with arguments R and S performs the following steps:

  1. Assert: Type(R) is Object.
  2. Assert: Type(S) is String.
  3. Let exec be ? Get(R, "exec").
  4. If IsCallable(exec) is true, then
    1. Let result be ? Call(exec, R, « S »).
    2. If Type(result) is neither Object or Null, throw a TypeError exception.
    3. Return result.
  5. If R does not have a [[RegExpMatcher]] internal slot, throw a TypeError exception.
  6. Return ? RegExpBuiltinExec(R, S).
Note

If a callable exec property is not found this algorithm falls back to attempting to use the built-in RegExp matching algorithm. This provides compatible behaviour for code written for prior editions where most built-in algorithms that use regular expressions did not perform a dynamic property lookup of exec.

21.2.5.2.2Runtime Semantics: RegExpBuiltinExec ( R, S )#

The abstract operation RegExpBuiltinExec with arguments R and S performs the following steps:

  1. Assert: R is an initialized RegExp instance.
  2. Assert: Type(S) is String.
  3. Let length be the number of code units in S.
  4. Let lastIndex be ? ToLength(? Get(R, "lastIndex")).
  5. Let global be ToBoolean(? Get(R, "global")).
  6. Let sticky be ToBoolean(? Get(R, "sticky")).
  7. If global is false and sticky is false, let lastIndex be 0.
  8. Let matcher be the value of R's [[RegExpMatcher]] internal slot.
  9. Let flags be the value of R's [[OriginalFlags]] internal slot.
  10. If flags contains "u", let fullUnicode be true, else let fullUnicode be false.
  11. Let matchSucceeded be false.
  12. Repeat, while matchSucceeded is false
    1. If lastIndex > length, then
      1. Perform ? Set(R, "lastIndex", 0, true).
      2. Return null.
    2. Let r be matcher(S, lastIndex).
    3. If r is failure, then
      1. If sticky is true, then
        1. Perform ? Set(R, "lastIndex", 0, true).
        2. Return null.
      2. Let lastIndex be AdvanceStringIndex(S, lastIndex, fullUnicode).
    4. Else,
      1. Assert: r is a State.
      2. Set matchSucceeded to true.
  13. Let e be r's endIndex value.
  14. If fullUnicode is true, then
    1. e is an index into the Input character list, derived from S, matched by matcher. Let eUTF be the smallest index into S that corresponds to the character at element e of Input. If e is greater than or equal to the length of Input, then eUTF is the number of code units in S.
    2. Let e be eUTF.
  15. If global is true or sticky is true, then
    1. Perform ? Set(R, "lastIndex", e, true).
  16. Let n be the length of r's captures List. (This is the same value as 21.2.2.1's NcapturingParens.)
  17. Let A be ArrayCreate(n + 1).
  18. Assert: The value of A's "length" property is n + 1.
  19. Let matchIndex be lastIndex.
  20. Perform ! CreateDataProperty(A, "index", matchIndex).
  21. Perform ! CreateDataProperty(A, "input", S).
  22. Let matchedSubstr be the matched substring (i.e. the portion of S between offset lastIndex inclusive and offset e exclusive).
  23. Perform ! CreateDataProperty(A, "0", matchedSubstr).
  24. For each integer i such that i > 0 and in
    1. Let captureI be ith element of r's captures List.
    2. If captureI is undefined, let capturedValue be undefined.
    3. Else if fullUnicode is true, then
      1. Assert: captureI is a List of code points.
      2. Let capturedValue be a string whose code units are the UTF16Encoding of the code points of captureI.
    4. Else, fullUnicode is false,
      1. Assert: captureI is a List of code units.
      2. Let capturedValue be a string consisting of the code units of captureI.
    5. Perform ! CreateDataProperty(A, ! ToString(i), capturedValue).
  25. Return A.

21.2.5.2.3AdvanceStringIndex ( S, index, unicode )#

The abstract operation AdvanceStringIndex with arguments S, index, and unicode performs the following steps:

  1. Assert: Type(S) is String.
  2. Assert: index is an integer such that 0≤index≤253-1.
  3. Assert: Type(unicode) is Boolean.
  4. If unicode is false, return index+1.
  5. Let length be the number of code units in S.
  6. If index+1 ≥ length, return index+1.
  7. Let first be the code unit value at index index in S.
  8. If first < 0xD800 or first > 0xDBFF, return index+1.
  9. Let second be the code unit value at index index+1 in S.
  10. If second < 0xDC00 or second > 0xDFFF, return index+1.
  11. Return index+2.

21.2.5.3get RegExp.prototype.flags#

RegExp.prototype.flags is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let R be the this value.
  2. If Type(R) is not Object, throw a TypeError exception.
  3. Let result be the empty String.
  4. Let global be ToBoolean(? Get(R, "global")).
  5. If global is true, append "g" as the last code unit of result.
  6. Let ignoreCase be ToBoolean(? Get(R, "ignoreCase")).
  7. If ignoreCase is true, append "i" as the last code unit of result.
  8. Let multiline be ToBoolean(? Get(R, "multiline")).
  9. If multiline is true, append "m" as the last code unit of result.
  10. Let unicode be ToBoolean(? Get(R, "unicode")).
  11. If unicode is true, append "u" as the last code unit of result.
  12. Let sticky be ToBoolean(? Get(R, "sticky")).
  13. If sticky is true, append "y" as the last code unit of result.
  14. Return result.

21.2.5.4get RegExp.prototype.global#

RegExp.prototype.global is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let R be the this value.
  2. If Type(R) is not Object, throw a TypeError exception.
  3. If R does not have an [[OriginalFlags]] internal slot, throw a TypeError exception.
  4. Let flags be the value of R's [[OriginalFlags]] internal slot.
  5. If flags contains the code unit "g", return true.
  6. Return false.

21.2.5.5get RegExp.prototype.ignoreCase#

RegExp.prototype.ignoreCase is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let R be the this value.
  2. If Type(R) is not Object, throw a TypeError exception.
  3. If R does not have an [[OriginalFlags]] internal slot, throw a TypeError exception.
  4. Let flags be the value of R's [[OriginalFlags]] internal slot.
  5. If flags contains the code unit "i", return true.
  6. Return false.

21.2.5.6RegExp.prototype [ @@match ] ( string )#

When the @@match method is called with argument string, the following steps are taken:

  1. Let rx be the this value.
  2. If Type(rx) is not Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let global be ToBoolean(? Get(rx, "global")).
  5. If global is false, then
    1. Return ? RegExpExec(rx, S).
  6. Else global is true,
    1. Let fullUnicode be ToBoolean(? Get(rx, "unicode")).
    2. Perform ? Set(rx, "lastIndex", 0, true).
    3. Let A be ArrayCreate(0).
    4. Let n be 0.
    5. Repeat,
      1. Let result be ? RegExpExec(rx, S).
      2. If result is null, then
        1. If n=0, return null.
        2. Else, return A.
      3. Else result is not null,
        1. Let matchStr be ? ToString(? Get(result, "0")).
        2. Let status be CreateDataProperty(A, ! ToString(n), matchStr).
        3. Assert: status is true.
        4. If matchStr is the empty String, then
          1. Let thisIndex be ? ToLength(? Get(rx, "lastIndex")).
          2. Let nextIndex be AdvanceStringIndex(S, thisIndex, fullUnicode).
          3. Perform ? Set(rx, "lastIndex", nextIndex, true).
        5. Increment n.

The value of the name property of this function is "[Symbol.match]".

Note

The @@match property is used by the IsRegExp abstract operation to identify objects that have the basic behaviour of regular expressions. The absence of a @@match property or the existence of such a property whose value does not Boolean coerce to true indicates that the object is not intended to be used as a regular expression object.

21.2.5.7get RegExp.prototype.multiline#

RegExp.prototype.multiline is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let R be the this value.
  2. If Type(R) is not Object, throw a TypeError exception.
  3. If R does not have an [[OriginalFlags]] internal slot, throw a TypeError exception.
  4. Let flags be the value of R's [[OriginalFlags]] internal slot.
  5. If flags contains the code unit "m", return true.
  6. Return false.

21.2.5.8RegExp.prototype [ @@replace ] ( string, replaceValue )#

When the @@replace method is called with arguments string and replaceValue, the following steps are taken:

  1. Let rx be the this value.
  2. If Type(rx) is not Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let lengthS be the number of code unit elements in S.
  5. Let functionalReplace be IsCallable(replaceValue).
  6. If functionalReplace is false, then
    1. Let replaceValue be ? ToString(replaceValue).
  7. Let global be ToBoolean(? Get(rx, "global")).
  8. If global is true, then
    1. Let fullUnicode be ToBoolean(? Get(rx, "unicode")).
    2. Perform ? Set(rx, "lastIndex", 0, true).
  9. Let results be a new empty List.
  10. Let done be false.
  11. Repeat, while done is false
    1. Let result be ? RegExpExec(rx, S).
    2. If result is null, set done to true.
    3. Else result is not null,
      1. Append result to the end of results.
      2. If global is false, set done to true.
      3. Else,
        1. Let matchStr be ? ToString(? Get(result, "0")).
        2. If matchStr is the empty String, then
          1. Let thisIndex be ? ToLength(? Get(rx, "lastIndex")).
          2. Let nextIndex be AdvanceStringIndex(S, thisIndex, fullUnicode).
          3. Perform ? Set(rx, "lastIndex", nextIndex, true).
  12. Let accumulatedResult be the empty String value.
  13. Let nextSourcePosition be 0.
  14. Repeat, for each result in results,
    1. Let nCaptures be ? ToLength(? Get(result, "length")).
    2. Let nCaptures be max(nCaptures - 1, 0).
    3. Let matched be ? ToString(? Get(result, "0")).
    4. Let matchLength be the number of code units in matched.
    5. Let position be ? ToInteger(? Get(result, "index")).
    6. Let position be max(min(position, lengthS), 0).
    7. Let n be 1.
    8. Let captures be a new empty List.
    9. Repeat while nnCaptures
      1. Let capN be ? Get(result, ! ToString(n)).
      2. If capN is not undefined, then
        1. Let capN be ? ToString(capN).
      3. Append capN as the last element of captures.
      4. Let n be n+1.
    10. If functionalReplace is true, then
      1. Let replacerArgs be « matched ».
      2. Append in list order the elements of captures to the end of the List replacerArgs.
      3. Append position and S as the last two elements of replacerArgs.
      4. Let replValue be ? Call(replaceValue, undefined, replacerArgs).
      5. Let replacement be ? ToString(replValue).
    11. Else,
      1. Let replacement be GetSubstitution(matched, S, position, captures, replaceValue).
    12. If positionnextSourcePosition, then
      1. NOTE position should not normally move backwards. If it does, it is an indication of an ill-behaving RegExp subclass or use of an access triggered side-effect to change the global flag or other characteristics of rx. In such cases, the corresponding substitution is ignored.
      2. Let accumulatedResult be the String formed by concatenating the code units of the current value of accumulatedResult with the substring of S consisting of the code units from nextSourcePosition (inclusive) up to position (exclusive) and with the code units of replacement.
      3. Let nextSourcePosition be position + matchLength.
  15. If nextSourcePositionlengthS, return accumulatedResult.
  16. Return the String formed by concatenating the code units of accumulatedResult with the substring of S consisting of the code units from nextSourcePosition (inclusive) up through the final code unit of S (inclusive).

The value of the name property of this function is "[Symbol.replace]".

21.2.5.9RegExp.prototype [ @@search ] ( string )#

When the @@search method is called with argument string, the following steps are taken:

  1. Let rx be the this value.
  2. If Type(rx) is not Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let previousLastIndex be ? Get(rx, "lastIndex").
  5. Perform ? Set(rx, "lastIndex", 0, true).
  6. Let result be ? RegExpExec(rx, S).
  7. Perform ? Set(rx, "lastIndex", previousLastIndex, true).
  8. If result is null, return -1.
  9. Return ? Get(result, "index").

The value of the name property of this function is "[Symbol.search]".

Note

The lastIndex and global properties of this RegExp object are ignored when performing the search. The lastIndex property is left unchanged.

21.2.5.10get RegExp.prototype.source#

RegExp.prototype.source is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let R be the this value.
  2. If Type(R) is not Object, throw a TypeError exception.
  3. If R does not have an [[OriginalSource]] internal slot, throw a TypeError exception.
  4. If R does not have an [[OriginalFlags]] internal slot, throw a TypeError exception.
  5. Let src be the value of R's [[OriginalSource]] internal slot.
  6. Let flags be the value of R's [[OriginalFlags]] internal slot.
  7. Return EscapeRegExpPattern(src, flags).

21.2.5.11RegExp.prototype [ @@split ] ( string, limit )#

Note 1

Returns an Array object into which substrings of the result of converting string to a String have been stored. The substrings are determined by searching from left to right for matches of the this value regular expression; these occurrences are not part of any substring in the returned array, but serve to divide up the String value.

The this value may be an empty regular expression or a regular expression that can match an empty String. In this case, the regular expression does not match the empty substring at the beginning or end of the input String, nor does it match the empty substring at the end of the previous separator match. (For example, if the regular expression matches the empty String, the String is split up into individual code unit elements; the length of the result array equals the length of the String, and each substring contains one code unit.) Only the first match at a given index of the String is considered, even if backtracking could yield a non-empty-substring match at that index. (For example, /a*?/[Symbol.split]("ab") evaluates to the array ["a","b"], while /a*/[Symbol.split]("ab") evaluates to the array ["","b"].)

If the string is (or converts to) the empty String, the result depends on whether the regular expression can match the empty String. If it can, the result array contains no elements. Otherwise, the result array contains one element, which is the empty String.

If the regular expression contains capturing parentheses, then each time separator is matched the results (including any undefined results) of the capturing parentheses are spliced into the output array. For example,

/<(\/)?([^<>]+)>/[Symbol.split]("A<B>bold</B>and<CODE>coded</CODE>")

evaluates to the array

["A",undefined,"B","bold","/","B","and",undefined,"CODE","coded","/","CODE",""]

If limit is not undefined, then the output array is truncated so that it contains no more than limit elements.

When the @@split method is called, the following steps are taken:

  1. Let rx be the this value.
  2. If Type(rx) is not Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let C be ? SpeciesConstructor(rx, %RegExp%).
  5. Let flags be ? ToString(? Get(rx, "flags")).
  6. If flags contains "u", let unicodeMatching be true.
  7. Else, let unicodeMatching be false.
  8. If flags contains "y", let newFlags be flags.
  9. Else, let newFlags be the string that is the concatenation of flags and "y".
  10. Let splitter be ? Construct(C, « rx, newFlags »).
  11. Let A be ArrayCreate(0).
  12. Let lengthA be 0.
  13. If limit is undefined, let lim be 232-1; else let lim be ? ToUint32(limit).
  14. Let size be the number of elements in S.
  15. Let p be 0.
  16. If lim = 0, return A.
  17. If size = 0, then
    1. Let z be ? RegExpExec(splitter, S).
    2. If z is not null, return A.
    3. Perform ! CreateDataProperty(A, "0", S).
    4. Return A.
  18. Let q be p.
  19. Repeat, while q < size
    1. Perform ? Set(splitter, "lastIndex", q, true).
    2. Let z be ? RegExpExec(splitter, S).
    3. If z is null, let q be AdvanceStringIndex(S, q, unicodeMatching).
    4. Else z is not null,
      1. Let e be ? ToLength(? Get(splitter, "lastIndex")).
      2. Let e be min(e, size).
      3. If e = p, let q be AdvanceStringIndex(S, q, unicodeMatching).
      4. Else ep,
        1. Let T be a String value equal to the substring of S consisting of the elements at indices p (inclusive) through q (exclusive).
        2. Perform ! CreateDataProperty(A, ! ToString(lengthA), T).
        3. Let lengthA be lengthA + 1.
        4. If lengthA = lim, return A.
        5. Let p be e.
        6. Let numberOfCaptures be ? ToLength(? Get(z, "length")).
        7. Let numberOfCaptures be max(numberOfCaptures-1, 0).
        8. Let i be 1.
        9. Repeat, while inumberOfCaptures,
          1. Let nextCapture be ? Get(z, ! ToString(i)).
          2. Perform ! CreateDataProperty(A, ! ToString(lengthA), nextCapture).
          3. Let i be i + 1.
          4. Let lengthA be lengthA + 1.
          5. If lengthA = lim, return A.
        10. Let q be p.
  20. Let T be a String value equal to the substring of S consisting of the elements at indices p (inclusive) through size (exclusive).
  21. Perform ! CreateDataProperty(A, ! ToString(lengthA), T).
  22. Return A.

The value of the name property of this function is "[Symbol.split]".

Note 2

The @@split method ignores the value of the global and sticky properties of this RegExp object.

21.2.5.12get RegExp.prototype.sticky#

RegExp.prototype.sticky is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let R be the this value.
  2. If Type(R) is not Object, throw a TypeError exception.
  3. If R does not have an [[OriginalFlags]] internal slot, throw a TypeError exception.
  4. Let flags be the value of R's [[OriginalFlags]] internal slot.
  5. If flags contains the code unit "y", return true.
  6. Return false.

21.2.5.13RegExp.prototype.test ( S )#

The following steps are taken:

  1. Let R be the this value.
  2. If Type(R) is not Object, throw a TypeError exception.
  3. Let string be ? ToString(S).
  4. Let match be ? RegExpExec(R, string).
  5. If match is not null, return true; else return false.

21.2.5.14RegExp.prototype.toString ( )#

  1. Let R be the this value.
  2. If Type(R) is not Object, throw a TypeError exception.
  3. Let pattern be ? ToString(? Get(R, "source")).
  4. Let flags be ? ToString(? Get(R, "flags")).
  5. Let result be the String value formed by concatenating "/", pattern, "/", and flags.
  6. Return result.
Note

The returned String has the form of a RegularExpressionLiteral that evaluates to another RegExp object with the same behaviour as this object.

21.2.5.15get RegExp.prototype.unicode#

RegExp.prototype.unicode is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let R be the this value.
  2. If Type(R) is not Object, throw a TypeError exception.
  3. If R does not have an [[OriginalFlags]] internal slot, throw a TypeError exception.
  4. Let flags be the value of R's [[OriginalFlags]] internal slot.
  5. If flags contains the code unit "u", return true.
  6. Return false.

21.2.6Properties of RegExp Instances#

RegExp instances are ordinary objects that inherit properties from the RegExp prototype object. RegExp instances have internal slots [[RegExpMatcher]], [[OriginalSource]], and [[OriginalFlags]]. The value of the [[RegExpMatcher]] internal slot is an implementation dependent representation of the Pattern of the RegExp object.

Note

Prior to ECMAScript 2015, RegExp instances were specified as having the own data properties source, global, ignoreCase, and multiline. Those properties are now specified as accessor properties of RegExp.prototype.

RegExp instances also have the following property:

21.2.6.1lastIndex#

The value of the lastIndex property specifies the String index at which to start the next match. It is coerced to an integer when used (see 21.2.5.2.2). This property shall have the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

22Indexed Collections(索引集合)#

22.1Array Objects(数组对象)#

Array objects are exotic objects that give special treatment to a certain class of property names. See 9.4.2 for a definition of this special treatment.

数组对象是特殊对象,对特定类别的属性名称给予特殊处理。 见9.4.2关于这种特殊处理的定义。

22.1.1The Array Constructor#

The Array constructor is the %Array% intrinsic object and the initial value of the Array property of the global object. When called as a constructor it creates and initializes a new exotic Array object. When Array is called as a function rather than as a constructor, it also creates and initializes a new Array object. Thus the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments.

Array构造函数是%Array%内部对象和全局对象的Array属性的初始值。当作为构造函数调用时,它会创建并初始化一个新的特殊数组对象。当数组被调用为函数而不是构造函数时,它还会创建并初始化一个新的数组对象。因此,函数调用Array(...)等价于具有相同参数的对象创建表达式new Array(...)。

The Array constructor is a single function whose behaviour is overloaded based upon the number and types of its arguments.

Array构造函数是一个函数,它的行为根据其参数的数量和类型而被重载。

The Array constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the exotic Array behaviour must include a super call to the Array constructor to initialize subclass instances that are exotic Array objects. However, most of the Array.prototype methods are generic methods that are not dependent upon their this value being an exotic Array object.

The length property of the Array constructor function is 1.

Array构造函数被设计为可分类的。它可以用作类定义的extends子句的值。打算继承外来数组行为的子类构造函数必须包含对Array构造函数的super调用,以初始化属于特殊数组对象的子类实例。但是,大多数Array.prototype方法都是通用方法,它们不依赖于它们的值是一个特殊数组对象。 Array构造函数的length属性为1。

22.1.1.1Array ( )#

This description applies if and only if the Array constructor is called with no arguments.

  1. Let numberOfArgs be the number of arguments passed to this function call.
  2. Assert: numberOfArgs = 0.
  3. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
  4. Let proto be ? GetPrototypeFromConstructor(newTarget, "%ArrayPrototype%").
  5. Return ArrayCreate(0, proto).

22.1.1.2Array (len)#

This description applies if and only if the Array constructor is called with exactly one argument.

  1. Let numberOfArgs be the number of arguments passed to this function call.
  2. Assert: numberOfArgs = 1.
  3. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
  4. Let proto be ? GetPrototypeFromConstructor(newTarget, "%ArrayPrototype%").
  5. Let array be ArrayCreate(0, proto).
  6. If Type(len) is not Number, then
    1. Let defineStatus be CreateDataProperty(array, "0", len).
    2. Assert: defineStatus is true.
    3. Let intLen be 1.
  7. Else,
    1. Let intLen be ToUint32(len).
    2. If intLenlen, throw a RangeError exception.
  8. Perform ! Set(array, "length", intLen, true).
  9. Return array.

22.1.1.3Array (...items )#

This description applies if and only if the Array constructor is called with at least two arguments.

When the Array function is called, the following steps are taken:

  1. Let numberOfArgs be the number of arguments passed to this function call.
  2. Assert: numberOfArgs ≥ 2.
  3. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
  4. Let proto be ? GetPrototypeFromConstructor(newTarget, "%ArrayPrototype%").
  5. Let array be ? ArrayCreate(numberOfArgs, proto).
  6. Let k be 0.
  7. Let items be a zero-origined List containing the argument items in order.
  8. Repeat, while k < numberOfArgs
    1. Let Pk be ! ToString(k).
    2. Let itemK be items[k].
    3. Let defineStatus be CreateDataProperty(array, Pk, itemK).
    4. Assert: defineStatus is true.
    5. Increase k by 1.
  9. Assert: the value of array's length property is numberOfArgs.
  10. Return array.

22.1.2Properties of the Array Constructor#

The value of the [[Prototype]] internal slot of the Array constructor is the intrinsic object %FunctionPrototype%.

The Array constructor has the following properties:

22.1.2.1Array.from ( items [ , mapfn [ , thisArg ] ] )#

When the from method is called with argument items and optional arguments mapfn and thisArg, the following steps are taken:

  1. Let C be the this value.
  2. If mapfn is undefined, let mapping be false.
  3. Else,
    1. If IsCallable(mapfn) is false, throw a TypeError exception.
    2. If thisArg was supplied, let T be thisArg; else let T be undefined.
    3. Let mapping be true.
  4. Let usingIterator be ? GetMethod(items, @@iterator).
  5. If usingIterator is not undefined, then
    1. If IsConstructor(C) is true, then
      1. Let A be ? Construct(C).
    2. Else,
      1. Let A be ArrayCreate(0).
    3. Let iterator be ? GetIterator(items, usingIterator).
    4. Let k be 0.
    5. Repeat
      1. If k ≥ 253-1, then
        1. Let error be Completion{[[Type]]: throw, [[Value]]: a newly created TypeError object, [[Target]]: empty}.
        2. Return ? IteratorClose(iterator, error).
      2. Let Pk be ! ToString(k).
      3. Let next be ? IteratorStep(iterator).
      4. If next is false, then
        1. Perform ? Set(A, "length", k, true).
        2. Return A.
      5. Let nextValue be ? IteratorValue(next).
      6. If mapping is true, then
        1. Let mappedValue be Call(mapfn, T, « nextValue, k »).
        2. If mappedValue is an abrupt completion, return ? IteratorClose(iterator, mappedValue).
        3. Let mappedValue be mappedValue.[[Value]].
      7. Else, let mappedValue be nextValue.
      8. Let defineStatus be CreateDataPropertyOrThrow(A, Pk, mappedValue).
      9. If defineStatus is an abrupt completion, return ? IteratorClose(iterator, defineStatus).
      10. Increase k by 1.
  6. NOTE: items is not an Iterable so assume it is an array-like object.
  7. Let arrayLike be ! ToObject(items).
  8. Let len be ? ToLength(? Get(arrayLike, "length")).
  9. If IsConstructor(C) is true, then
    1. Let A be ? Construct(C, « len »).
  10. Else,
    1. Let A be ? ArrayCreate(len).
  11. Let k be 0.
  12. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kValue be ? Get(arrayLike, Pk).
    3. If mapping is true, then
      1. Let mappedValue be ? Call(mapfn, T, « kValue, k »).
    4. Else, let mappedValue be kValue.
    5. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
    6. Increase k by 1.
  13. Perform ? Set(A, "length", len, true).
  14. Return A.
Note

The from function is an intentionally generic factory method; it does not require that its this value be the Array constructor. Therefore it can be transferred to or inherited by any other constructors that may be called with a single numeric argument.

22.1.2.2Array.isArray ( arg )#

The isArray function takes one argument arg, and performs the following steps:

  1. Return ? IsArray(arg).

22.1.2.3Array.of ( ...items )#

When the of method is called with any number of arguments, the following steps are taken:

  1. Let len be the actual number of arguments passed to this function.
  2. Let items be the List of arguments passed to this function.
  3. Let C be the this value.
  4. If IsConstructor(C) is true, then
    1. Let A be ? Construct(C, « len »).
  5. Else,
    1. Let A be ? ArrayCreate(len).
  6. Let k be 0.
  7. Repeat, while k < len
    1. Let kValue be items[k].
    2. Let Pk be ! ToString(k).
    3. Perform ? CreateDataPropertyOrThrow(A, Pk, kValue).
    4. Increase k by 1.
  8. Perform ? Set(A, "length", len, true).
  9. Return A.
Note 1

The items argument is assumed to be a well-formed rest argument value.

Note 2

The of function is an intentionally generic factory method; it does not require that its this value be the Array constructor. Therefore it can be transferred to or inherited by other constructors that may be called with a single numeric argument.

22.1.2.4Array.prototype#

The value of Array.prototype is %ArrayPrototype%, the intrinsic Array prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

22.1.2.5get Array [ @@species ]#

Array[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Return the this value.

The value of the name property of this function is "get [Symbol.species]".

Note

Array prototype methods normally use their this object's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its @@species property.

22.1.3Properties of the Array Prototype Object#

The Array prototype object is the intrinsic object %ArrayPrototype%. The Array prototype object is an Array exotic objects and has the internal methods specified for such objects. It has a length property whose initial value is 0 and whose attributes are { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

The value of the [[Prototype]] internal slot of the Array prototype object is the intrinsic object %ObjectPrototype%.

Note

The Array prototype object is specified to be an Array exotic object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.

22.1.3.1Array.prototype.concat ( ...arguments )#

When the concat method is called with zero or more arguments, it returns an array containing the array elements of the object followed by the array elements of each argument in order.

The following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let A be ? ArraySpeciesCreate(O, 0).
  3. Let n be 0.
  4. Let items be a List whose first element is O and whose subsequent elements are, in left to right order, the arguments that were passed to this function invocation.
  5. Repeat, while items is not empty
    1. Remove the first element from items and let E be the value of the element.
    2. Let spreadable be ? IsConcatSpreadable(E).
    3. If spreadable is true, then
      1. Let k be 0.
      2. Let len be ? ToLength(? Get(E, "length")).
      3. If n + len > 253-1, throw a TypeError exception.
      4. Repeat, while k < len
        1. Let P be ! ToString(k).
        2. Let exists be ? HasProperty(E, P).
        3. If exists is true, then
          1. Let subElement be ? Get(E, P).
          2. Perform ? CreateDataPropertyOrThrow(A, ! ToString(n), subElement).
        4. Increase n by 1.
        5. Increase k by 1.
    4. Else E is added as a single item rather than spread,
      1. If n≥253-1, throw a TypeError exception.
      2. Perform ? CreateDataPropertyOrThrow(A, ! ToString(n), E).
      3. Increase n by 1.
  6. Perform ? Set(A, "length", n, true).
  7. Return A.

The length property of the concat method is 1.

Note 1

The explicit setting of the length property in step 6 is necessary to ensure that its value is correct in situations where the trailing elements of the result Array are not present.

Note 2

The concat function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.1.1Runtime Semantics: IsConcatSpreadable ( O )#

The abstract operation IsConcatSpreadable with argument O performs the following steps:

  1. If Type(O) is not Object, return false.
  2. Let spreadable be ? Get(O, @@isConcatSpreadable).
  3. If spreadable is not undefined, return ToBoolean(spreadable).
  4. Return ? IsArray(O).

22.1.3.2Array.prototype.constructor#

The initial value of Array.prototype.constructor is the intrinsic object %Array%.

22.1.3.3Array.prototype.copyWithin (target, start [ , end ] )#

The copyWithin method takes up to three arguments target, start and end.

Note 1

The end argument is optional with the length of the this object as its default value. If target is negative, it is treated as length+target where length is the length of the array. If start is negative, it is treated as length+start. If end is negative, it is treated as length+end.

The following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. Let relativeTarget be ? ToInteger(target).
  4. If relativeTarget < 0, let to be max((len + relativeTarget), 0); else let to be min(relativeTarget, len).
  5. Let relativeStart be ? ToInteger(start).
  6. If relativeStart < 0, let from be max((len + relativeStart), 0); else let from be min(relativeStart, len).
  7. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToInteger(end).
  8. If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let final be min(relativeEnd, len).
  9. Let count be min(final-from, len-to).
  10. If from<to and to<from+count, then
    1. Let direction be -1.
    2. Let from be from + count - 1.
    3. Let to be to + count - 1.
  11. Else,
    1. Let direction be 1.
  12. Repeat, while count > 0
    1. Let fromKey be ! ToString(from).
    2. Let toKey be ! ToString(to).
    3. Let fromPresent be ? HasProperty(O, fromKey).
    4. If fromPresent is true, then
      1. Let fromVal be ? Get(O, fromKey).
      2. Perform ? Set(O, toKey, fromVal, true).
    5. Else fromPresent is false,
      1. Perform ? DeletePropertyOrThrow(O, toKey).
    6. Let from be from + direction.
    7. Let to be to + direction.
    8. Let count be count - 1.
  13. Return O.
Note 2

The copyWithin function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.4Array.prototype.entries ( )#

The following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Return CreateArrayIterator(O, "key+value").

22.1.3.5Array.prototype.every ( callbackfn [ , thisArg ] )#

Note 1

callbackfn should be a function that accepts three arguments and returns a value that is coercible to the Boolean value true or false. every calls callbackfn once for each element present in the array, in ascending order, until it finds one where callbackfn returns false. If such an element is found, every immediately returns false. Otherwise, if callbackfn returned true for all elements, every will return true. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the object being traversed.

every does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by every is set before the first call to callbackfn. Elements which are appended to the array after the call to every begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to callbackfn will be the value at the time every visits them; elements that are deleted after the call to every begins and before being visited are not visited. every acts like the "for all" quantifier in mathematics. In particular, for an empty array, it returns true.

When the every method is called with one or two arguments, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. If thisArg was supplied, let T be thisArg; else let T be undefined.
  5. Let k be 0.
  6. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let testResult be ToBoolean(? Call(callbackfn, T, « kValue, k, O »)).
      3. If testResult is false, return false.
    4. Increase k by 1.
  7. Return true.
Note 2

The every function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.6Array.prototype.fill (value [ , start [ , end ] ] )#

The fill method takes up to three arguments value, start and end.

Note 1

The start and end arguments are optional with default values of 0 and the length of the this object. If start is negative, it is treated as length+start where length is the length of the array. If end is negative, it is treated as length+end.

The following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. Let relativeStart be ? ToInteger(start).
  4. If relativeStart < 0, let k be max((len + relativeStart), 0); else let k be min(relativeStart, len).
  5. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToInteger(end).
  6. If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let final be min(relativeEnd, len).
  7. Repeat, while k < final
    1. Let Pk be ! ToString(k).
    2. Perform ? Set(O, Pk, value, true).
    3. Increase k by 1.
  8. Return O.
Note 2

The fill function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.7Array.prototype.filter ( callbackfn [ , thisArg ] )#

Note 1

callbackfn should be a function that accepts three arguments and returns a value that is coercible to the Boolean value true or false. filter calls callbackfn once for each element in the array, in ascending order, and constructs a new array of all the values for which callbackfn returns true. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the object being traversed.

filter does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by filter is set before the first call to callbackfn. Elements which are appended to the array after the call to filter begins will not be visited by callbackfn. If existing elements of the array are changed their value as passed to callbackfn will be the value at the time filter visits them; elements that are deleted after the call to filter begins and before being visited are not visited.

When the filter method is called with one or two arguments, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. If thisArg was supplied, let T be thisArg; else let T be undefined.
  5. Let A be ? ArraySpeciesCreate(O, 0).
  6. Let k be 0.
  7. Let to be 0.
  8. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let selected be ToBoolean(? Call(callbackfn, T, « kValue, k, O »)).
      3. If selected is true, then
        1. Perform ? CreateDataPropertyOrThrow(A, ! ToString(to), kValue).
        2. Increase to by 1.
    4. Increase k by 1.
  9. Return A.
Note 2

The filter function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.8Array.prototype.find ( predicate [ , thisArg ] )#

The find method is called with one or two arguments, predicate and thisArg.

Note 1

predicate should be a function that accepts three arguments and returns a value that is coercible to a Boolean value. find calls predicate once for each element of the array, in ascending order, until it finds one where predicate returns true. If such an element is found, find immediately returns that element value. Otherwise, find returns undefined.

If a thisArg parameter is provided, it will be used as the this value for each invocation of predicate. If it is not provided, undefined is used instead.

predicate is called with three arguments: the value of the element, the index of the element, and the object being traversed.

find does not directly mutate the object on which it is called but the object may be mutated by the calls to predicate.

The range of elements processed by find is set before the first call to callbackfn. Elements that are appended to the array after the call to find begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to predicate will be the value at the time that find visits them.

When the find method is called, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If IsCallable(predicate) is false, throw a TypeError exception.
  4. If thisArg was supplied, let T be thisArg; else let T be undefined.
  5. Let k be 0.
  6. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kValue be ? Get(O, Pk).
    3. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
    4. If testResult is true, return kValue.
    5. Increase k by 1.
  7. Return undefined.
Note 2

The find function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.9Array.prototype.findIndex ( predicate [ , thisArg ] )#

Note 1

predicate should be a function that accepts three arguments and returns a value that is coercible to the Boolean value true or false. findIndex calls predicate once for each element of the array, in ascending order, until it finds one where predicate returns true. If such an element is found, findIndex immediately returns the index of that element value. Otherwise, findIndex returns -1.

If a thisArg parameter is provided, it will be used as the this value for each invocation of predicate. If it is not provided, undefined is used instead.

predicate is called with three arguments: the value of the element, the index of the element, and the object being traversed.

findIndex does not directly mutate the object on which it is called but the object may be mutated by the calls to predicate.

The range of elements processed by findIndex is set before the first call to callbackfn. Elements that are appended to the array after the call to findIndex begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to predicate will be the value at the time that findIndex visits them.

When the findIndex method is called with one or two arguments, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If IsCallable(predicate) is false, throw a TypeError exception.
  4. If thisArg was supplied, let T be thisArg; else let T be undefined.
  5. Let k be 0.
  6. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kValue be ? Get(O, Pk).
    3. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
    4. If testResult is true, return k.
    5. Increase k by 1.
  7. Return -1.
Note 2

The findIndex function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.10Array.prototype.forEach ( callbackfn [ , thisArg ] )#

Note 1

callbackfn should be a function that accepts three arguments. forEach calls callbackfn once for each element present in the array, in ascending order. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the object being traversed.

forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

When the forEach method is called with one or two arguments, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. If thisArg was supplied, let T be thisArg; else let T be undefined.
  5. Let k be 0.
  6. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Perform ? Call(callbackfn, T, « kValue, k, O »).
    4. Increase k by 1.
  7. Return undefined.
Note 2

The forEach function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.11Array.prototype.includes ( searchElement [ , fromIndex ] )#

Note 1

includes compares searchElement to the elements of the array, in ascending order, using the SameValueZero algorithm, and if found at any position, returns true; otherwise, false is returned.

The optional second argument fromIndex defaults to 0 (i.e. the whole array is searched). If it is greater than or equal to the length of the array, false is returned, i.e. the array will not be searched. If it is negative, it is used as the offset from the end of the array to compute fromIndex. If the computed index is less than 0, the whole array will be searched.

When the includes method is called, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If len is 0, return false.
  4. Let n be ? ToInteger(fromIndex). (If fromIndex is undefined, this step produces the value 0.)
  5. If n ≥ 0, then
    1. Let k be n.
  6. Else n < 0,
    1. Let k be len + n.
    2. If k < 0, let k be 0.
  7. Repeat, while k < len
    1. Let elementK be the result of ? Get(O, ! ToString(k)).
    2. If SameValueZero(searchElement, elementK) is true, return true.
    3. Increase k by 1.
  8. Return false.
Note 2

The includes function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

Note 3

The includes method intentionally differs from the similar indexOf method in two ways. First, it uses the SameValueZero algorithm, instead of Strict Equality Comparison, allowing it to detect NaN array elements. Second, it does not skip missing array elements, instead treating them as undefined.

22.1.3.12Array.prototype.indexOf ( searchElement [ , fromIndex ] )#

Note 1

indexOf compares searchElement to the elements of the array, in ascending order, using the Strict Equality Comparison algorithm, and if found at one or more indices, returns the smallest such index; otherwise, -1 is returned.

The optional second argument fromIndex defaults to 0 (i.e. the whole array is searched). If it is greater than or equal to the length of the array, -1 is returned, i.e. the array will not be searched. If it is negative, it is used as the offset from the end of the array to compute fromIndex. If the computed index is less than 0, the whole array will be searched.

When the indexOf method is called with one or two arguments, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If len is 0, return -1.
  4. Let n be ? ToInteger(fromIndex). (If fromIndex is undefined, this step produces the value 0.)
  5. If nlen, return -1.
  6. If n ≥ 0, then
    1. If n is -0, let k be +0; else let k be n.
  7. Else n < 0,
    1. Let k be len + n.
    2. If k < 0, let k be 0.
  8. Repeat, while k < len
    1. Let kPresent be ? HasProperty(O, ! ToString(k)).
    2. If kPresent is true, then
      1. Let elementK be ? Get(O, ! ToString(k)).
      2. Let same be the result of performing Strict Equality Comparison searchElement === elementK.
      3. If same is true, return k.
    3. Increase k by 1.
  9. Return -1.
Note 2

The indexOf function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.13Array.prototype.join (separator)#

Note 1

The elements of the array are converted to Strings, and these Strings are then concatenated, separated by occurrences of the separator. If no separator is provided, a single comma is used as the separator.

The join method takes one argument, separator, and performs the following steps:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If separator is undefined, let separator be the single-element String ",".
  4. Let sep be ? ToString(separator).
  5. If len is zero, return the empty String.
  6. Let element0 be Get(O, "0").
  7. If element0 is undefined or null, let R be the empty String; otherwise, let R be ? ToString(element0).
  8. Let k be 1.
  9. Repeat, while k < len
    1. Let S be the String value produced by concatenating R and sep.
    2. Let element be ? Get(O, ! ToString(k)).
    3. If element is undefined or null, let next be the empty String; otherwise, let next be ? ToString(element).
    4. Let R be a String value produced by concatenating S and next.
    5. Increase k by 1.
  10. Return R.
Note 2

The join function is intentionally generic; it does not require that its this value be an Array object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.14Array.prototype.keys ( )#

The following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Return CreateArrayIterator(O, "key").

22.1.3.15Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] )#

Note 1

lastIndexOf compares searchElement to the elements of the array in descending order using the Strict Equality Comparison algorithm, and if found at one or more indices, returns the largest such index; otherwise, -1 is returned.

The optional second argument fromIndex defaults to the array's length minus one (i.e. the whole array is searched). If it is greater than or equal to the length of the array, the whole array will be searched. If it is negative, it is used as the offset from the end of the array to compute fromIndex. If the computed index is less than 0, -1 is returned.

When the lastIndexOf method is called with one or two arguments, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If len is 0, return -1.
  4. If argument fromIndex was passed, let n be ? ToInteger(fromIndex); else let n be len-1.
  5. If n ≥ 0, then
    1. If n is -0, let k be +0; else let k be min(n, len - 1).
  6. Else n < 0,
    1. Let k be len + n.
  7. Repeat, while k ≥ 0
    1. Let kPresent be ? HasProperty(O, ! ToString(k)).
    2. If kPresent is true, then
      1. Let elementK be ? Get(O, ! ToString(k)).
      2. Let same be the result of performing Strict Equality Comparison searchElement === elementK.
      3. If same is true, return k.
    3. Decrease k by 1.
  8. Return -1.
Note 2

The lastIndexOf function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.16Array.prototype.map ( callbackfn [ , thisArg ] )#

Note 1

callbackfn should be a function that accepts three arguments. map calls callbackfn once for each element in the array, in ascending order, and constructs a new Array from the results. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the object being traversed.

map does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by map is set before the first call to callbackfn. Elements which are appended to the array after the call to map begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to callbackfn will be the value at the time map visits them; elements that are deleted after the call to map begins and before being visited are not visited.

When the map method is called with one or two arguments, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. If thisArg was supplied, let T be thisArg; else let T be undefined.
  5. Let A be ? ArraySpeciesCreate(O, len).
  6. Let k be 0.
  7. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let mappedValue be ? Call(callbackfn, T, « kValue, k, O »).
      3. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
    4. Increase k by 1.
  8. Return A.
Note 2

The map function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.17Array.prototype.pop ( )#

Note 1

The last element of the array is removed from the array and returned.

When the pop method is called, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If len is zero, then
    1. Perform ? Set(O, "length", 0, true).
    2. Return undefined.
  4. Else len > 0,
    1. Let newLen be len-1.
    2. Let indx be ! ToString(newLen).
    3. Let element be ? Get(O, indx).
    4. Perform ? DeletePropertyOrThrow(O, indx).
    5. Perform ? Set(O, "length", newLen, true).
    6. Return element.
Note 2

The pop function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.18Array.prototype.push ( ...items )#

Note 1

The arguments are appended to the end of the array, in the order in which they appear. The new length of the array is returned as the result of the call.

When the push method is called with zero or more arguments, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. Let items be a List whose elements are, in left to right order, the arguments that were passed to this function invocation.
  4. Let argCount be the number of elements in items.
  5. If len + argCount > 253-1, throw a TypeError exception.
  6. Repeat, while items is not empty
    1. Remove the first element from items and let E be the value of the element.
    2. Perform ? Set(O, ! ToString(len), E, true).
    3. Let len be len+1.
  7. Perform ? Set(O, "length", len, true).
  8. Return len.

The length property of the push method is 1.

Note 2

The push function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.19Array.prototype.reduce ( callbackfn [ , initialValue ] )#

Note 1

callbackfn should be a function that takes four arguments. reduce calls the callback, as a function, once for each element present in the array, in ascending order.

callbackfn is called with four arguments: the previousValue (value from the previous call to callbackfn), the currentValue (value of the current element), the currentIndex, and the object being traversed. The first time that callback is called, the previousValue and currentValue can be one of two values. If an initialValue was provided in the call to reduce, then previousValue will be equal to initialValue and currentValue will be equal to the first value in the array. If no initialValue was provided, then previousValue will be equal to the first value in the array and currentValue will be equal to the second. It is a TypeError if the array contains no elements and initialValue is not provided.

reduce does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by reduce is set before the first call to callbackfn. Elements that are appended to the array after the call to reduce begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to callbackfn will be the value at the time reduce visits them; elements that are deleted after the call to reduce begins and before being visited are not visited.

callbackfn应该是一个带有四个参数的函数。 reduce作为函数调用回调,对于数组中存在的每个元素,按升序调用一次。
callbackfn使用四个参数调用:previousValue(上一次调用callbackfn的值),currentValue(当前元素的值),currentIndex和被遍历的对象。第一次调用回调时,previousValue和currentValue可以是两个值之一。如果在reduce的调用中提供了initialValue,则previousValue将等于initialValue,currentValue将等于数组中的第一个值。如果没有提供initialValue,则previousValue将等于数组中的第一个值,currentValue将等于第二个值。如果数组不包含元素且未提供initialValue,则为TypeError。
reduce不会直接改变调用它的对象,但是对象可能会被callbackfn的调用所突变。
reduce处理的元素范围在第一次调用callbackfn之前设置。 callbackfn将不会访问在调用reduce开始后附加到数组的元素。如果更改了数组的现有元素,则传递给callbackfn的值将是reduce访问它们时的值;不会访问在调用reduce开始之后和访问之前删除的元素。

When the reduce method is called with one or two arguments, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. If len is 0 and initialValue is not present, throw a TypeError exception.
  5. Let k be 0.
  6. If initialValue is present, then
    1. Set accumulator to initialValue.
  7. Else initialValue is not present,
    1. Let kPresent be false.
    2. Repeat, while kPresent is false and k < len
      1. Let Pk be ! ToString(k).
      2. Let kPresent be ? HasProperty(O, Pk).
      3. If kPresent is true, then
        1. Let accumulator be ? Get(O, Pk).
      4. Increase k by 1.
    3. If kPresent is false, throw a TypeError exception.
  8. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let accumulator be ? Call(callbackfn, undefined, « accumulator, kValue, k, O »).
    4. Increase k by 1.
  9. Return accumulator.
let arr = [1,2,3,4,5]; arr.reduce((a, b) => a + b, 100); // 115 Note 2

The reduce function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.20Array.prototype.reduceRight ( callbackfn [ , initialValue ] )#

Note 1

callbackfn should be a function that takes four arguments. reduceRight calls the callback, as a function, once for each element present in the array, in descending order.

callbackfn is called with four arguments: the previousValue (value from the previous call to callbackfn), the currentValue (value of the current element), the currentIndex, and the object being traversed. The first time the function is called, the previousValue and currentValue can be one of two values. If an initialValue was provided in the call to reduceRight, then previousValue will be equal to initialValue and currentValue will be equal to the last value in the array. If no initialValue was provided, then previousValue will be equal to the last value in the array and currentValue will be equal to the second-to-last value. It is a TypeError if the array contains no elements and initialValue is not provided.

reduceRight does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by reduceRight is set before the first call to callbackfn. Elements that are appended to the array after the call to reduceRight begins will not be visited by callbackfn. If existing elements of the array are changed by callbackfn, their value as passed to callbackfn will be the value at the time reduceRight visits them; elements that are deleted after the call to reduceRight begins and before being visited are not visited.

When the reduceRight method is called with one or two arguments, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. If len is 0 and initialValue is not present, throw a TypeError exception.
  5. Let k be len-1.
  6. If initialValue is present, then
    1. Set accumulator to initialValue.
  7. Else initialValue is not present,
    1. Let kPresent be false.
    2. Repeat, while kPresent is false and k ≥ 0
      1. Let Pk be ! ToString(k).
      2. Let kPresent be ? HasProperty(O, Pk).
      3. If kPresent is true, then
        1. Let accumulator be ? Get(O, Pk).
      4. Decrease k by 1.
    3. If kPresent is false, throw a TypeError exception.
  8. Repeat, while k ≥ 0
    1. Let Pk be ! ToString(k).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let accumulator be ? Call(callbackfn, undefined, « accumulator, kValue, k, O »).
    4. Decrease k by 1.
  9. Return accumulator.
Note 2

The reduceRight function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.21Array.prototype.reverse ( )#

Note 1

The elements of the array are rearranged so as to reverse their order. The object is returned as the result of the call.

When the reverse method is called, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. Let middle be floor(len/2).
  4. Let lower be 0.
  5. Repeat, while lowermiddle
    1. Let upper be len - lower - 1.
    2. Let upperP be ! ToString(upper).
    3. Let lowerP be ! ToString(lower).
    4. Let lowerExists be ? HasProperty(O, lowerP).
    5. If lowerExists is true, then
      1. Let lowerValue be ? Get(O, lowerP).
    6. Let upperExists be ? HasProperty(O, upperP).
    7. If upperExists is true, then
      1. Let upperValue be ? Get(O, upperP).
    8. If lowerExists is true and upperExists is true, then
      1. Perform ? Set(O, lowerP, upperValue, true).
      2. Perform ? Set(O, upperP, lowerValue, true).
    9. Else if lowerExists is false and upperExists is true, then
      1. Perform ? Set(O, lowerP, upperValue, true).
      2. Perform ? DeletePropertyOrThrow(O, upperP).
    10. Else if lowerExists is true and upperExists is false, then
      1. Perform ? DeletePropertyOrThrow(O, lowerP).
      2. Perform ? Set(O, upperP, lowerValue, true).
    11. Else both lowerExists and upperExists are false,
      1. No action is required.
    12. Increase lower by 1.
  6. Return O.
Note 2

The reverse function is intentionally generic; it does not require that its this value be an Array object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.22Array.prototype.shift ( )#

Note 1

The first element of the array is removed from the array and returned.

When the shift method is called, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If len is zero, then
    1. Perform ? Set(O, "length", 0, true).
    2. Return undefined.
  4. Let first be ? Get(O, "0").
  5. Let k be 1.
  6. Repeat, while k < len
    1. Let from be ! ToString(k).
    2. Let to be ! ToString(k-1).
    3. Let fromPresent be ? HasProperty(O, from).
    4. If fromPresent is true, then
      1. Let fromVal be ? Get(O, from).
      2. Perform ? Set(O, to, fromVal, true).
    5. Else fromPresent is false,
      1. Perform ? DeletePropertyOrThrow(O, to).
    6. Increase k by 1.
  7. Perform ? DeletePropertyOrThrow(O, ! ToString(len-1)).
  8. Perform ? Set(O, "length", len-1, true).
  9. Return first.
Note 2

The shift function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.23Array.prototype.slice (start, end)#

Note 1

The slice method takes two arguments, start and end, and returns an array containing the elements of the array from element start up to, but not including, element end (or through the end of the array if end is undefined). If start is negative, it is treated as length+start where length is the length of the array. If end is negative, it is treated as length+end where length is the length of the array.

The following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. Let relativeStart be ? ToInteger(start).
  4. If relativeStart < 0, let k be max((len + relativeStart), 0); else let k be min(relativeStart, len).
  5. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToInteger(end).
  6. If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let final be min(relativeEnd, len).
  7. Let count be max(final - k, 0).
  8. Let A be ? ArraySpeciesCreate(O, count).
  9. Let n be 0.
  10. Repeat, while k < final
    1. Let Pk be ! ToString(k).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Perform ? CreateDataPropertyOrThrow(A, ! ToString(n), kValue).
    4. Increase k by 1.
    5. Increase n by 1.
  11. Perform ? Set(A, "length", n, true).
  12. Return A.
Note 2

The explicit setting of the length property of the result Array in step 11 was necessary in previous editions of ECMAScript to ensure that its length was correct in situations where the trailing elements of the result Array were not present. Setting length became unnecessary starting in ES2015 when the result Array was initialized to its proper length rather than an empty Array but is carried forward to preserve backward compatibility.

Note 3

The slice function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.24Array.prototype.some ( callbackfn [ , thisArg ] )#

Note 1

callbackfn should be a function that accepts three arguments and returns a value that is coercible to the Boolean value true or false. some calls callbackfn once for each element present in the array, in ascending order, until it finds one where callbackfn returns true. If such an element is found, some immediately returns true. Otherwise, some returns false. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the object being traversed.

some does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by some is set before the first call to callbackfn. Elements that are appended to the array after the call to some begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to callbackfn will be the value at the time that some visits them; elements that are deleted after the call to some begins and before being visited are not visited. some acts like the "exists" quantifier in mathematics. In particular, for an empty array, it returns false.

When the some method is called with one or two arguments, the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. If thisArg was supplied, let T be thisArg; else let T be undefined.
  5. Let k be 0.
  6. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let testResult be ToBoolean(? Call(callbackfn, T, « kValue, k, O »)).
      3. If testResult is true, return true.
    4. Increase k by 1.
  7. Return false.
Note 2

The some function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.25Array.prototype.sort (comparefn)#

The elements of this array are sorted. The sort is not necessarily stable (that is, elements that compare equal do not necessarily remain in their original order). If comparefn is not undefined, it should be a function that accepts two arguments x and y and returns a negative value if x < y, zero if x = y, or a positive value if x > y.

Upon entry, the following steps are performed to initialize evaluation of the sort function:

  1. Let obj be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(obj, "length")).

Within this specification of the sort method, an object, obj, is said to be sparse if the following algorithm returns true:

  1. For each integer i in the range 0≤i< len
    1. Let elem be obj.[[GetOwnProperty]](! ToString(i)).
    2. If elem is undefined, return true.
  2. Return false.

The sort order is the ordering, after completion of this function, of the integer indexed property values of obj whose integer indexes are less than len. The result of the sort function is then determined as follows:

If comparefn is not undefined and is not a consistent comparison function for the elements of this array (see below), the sort order is implementation-defined. The sort order is also implementation-defined if comparefn is undefined and SortCompare does not act as a consistent comparison function.

Let proto be obj.[[GetPrototypeOf]](). If proto is not null and there exists an integer j such that all of the conditions below are satisfied then the sort order is implementation-defined:

The sort order is also implementation defined if obj is sparse and any of the following conditions are true:

  • IsExtensible(obj) is false.
  • Any integer index property of obj whose name is a nonnegative integer less than len is a data property whose [[Configurable]] attribute is false.

The sort order is also implementation defined if any of the following conditions are true:

  • If obj is an exotic object (including Proxy exotic objects) whose behaviour for [[Get]], [[Set]], [[Delete]], and [[GetOwnProperty]] is not the ordinary object implementation of these internal methods.
  • If any index property of obj whose name is a nonnegative integer less than len is an accessor property or is a data property whose [[Writable]] attribute is false.
  • If comparefn is undefined and the application of ToString to any value passed as an argument to SortCompare modifies obj or any object on obj's prototype chain.
  • If comparefn is undefined and all applications of ToString, to any specific value passed as an argument to SortCompare, do not produce the same result.

The following steps are taken:

  1. Perform an implementation-dependent sequence of calls to the [[Get]] and [[Set]] internal methods of obj, to the DeletePropertyOrThrow and HasOwnProperty abstract operation with obj as the first argument, and to SortCompare (described below), such that:
    • The property key argument for each call to [[Get]], [[Set]], HasOwnProperty, or DeletePropertyOrThrow is the string representation of a nonnegative integer less than len.
    • The arguments for calls to SortCompare are values returned by a previous call to the [[Get]] internal method, unless the properties accessed by those previous calls did not exist according to HasOwnProperty. If both perspective arguments to SortCompare correspond to non-existent properties, use +0 instead of calling SortCompare. If only the first perspective argument is non-existent use +1. If only the second perspective argument is non-existent use -1.
    • If obj is not sparse then DeletePropertyOrThrow must not be called.
    • If any [[Set]] call returns false a TypeError exception is thrown.
    • If an abrupt completion is returned from any of these operations, it is immediately returned as the value of this function.
  2. Return obj.

Unless the sort order is specified above to be implementation-defined, the returned object must have the following two characteristics:

  • There must be some mathematical permutation π of the nonnegative integers less than len, such that for every nonnegative integer j less than len, if property old[j] existed, then new[π(j)] is exactly the same value as old[j]. But if property old[j] did not exist, then new[π(j)] does not exist.
  • Then for all nonnegative integers j and k, each less than len, if SortCompare(old[j], old[k]) < 0 (see SortCompare below), then new[π(j)] < new[π(k)].

Here the notation old[j] is used to refer to the hypothetical result of calling the [[Get]] internal method of obj with argument j before this function is executed, and the notation new[j] to refer to the hypothetical result of calling the [[Get]] internal method of obj with argument j after this function has been executed.

A function comparefn is a consistent comparison function for a set of values S if all of the requirements below are met for all values a, b, and c (possibly the same value) in the set S: The notation a <CF b means comparefn(a, b) < 0; a =CF b means comparefn(a, b) = 0 (of either sign); and a >CF b means comparefn(a, b) > 0.

  • Calling comparefn(a, b) always returns the same value v when given a specific pair of values a and b as its two arguments. Furthermore, Type(v) is Number, and v is not NaN. Note that this implies that exactly one of a <CF b, a =CF b, and a >CF b will be true for a given pair of a and b.
  • Calling comparefn(a, b) does not modify obj or any object on obj's prototype chain.
  • a =CF a (reflexivity)
  • If a =CF b, then b =CF a (symmetry)
  • If a =CF b and b =CF c, then a =CF c (transitivity of =CF)
  • If a <CF b and b <CF c, then a <CF c (transitivity of <CF)
  • If a >CF b and b >CF c, then a >CF c (transitivity of >CF)
Note 1

The above conditions are necessary and sufficient to ensure that comparefn divides the set S into equivalence classes and that these equivalence classes are totally ordered.

Note 2

The sort function is intentionally generic; it does not require that its this value be an Array object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.25.1Runtime Semantics: SortCompare( x, y )#

The SortCompare abstract operation is called with two arguments x and y. It also has access to the comparefn argument passed to the current invocation of the sort method. The following steps are taken:

  1. If x and y are both undefined, return +0.
  2. If x is undefined, return 1.
  3. If y is undefined, return -1.
  4. If the argument comparefn is not undefined, then
    1. Let v be ? ToNumber(? Call(comparefn, undefined, « x, y »)).
    2. If v is NaN, return +0.
    3. Return v.
  5. Let xString be ? ToString(x).
  6. Let yString be ? ToString(y).
  7. Let xSmaller be the result of performing Abstract Relational Comparison xString < yString.
  8. If xSmaller is true, return -1.
  9. Let ySmaller be the result of performing Abstract Relational Comparison yString < xString.
  10. If ySmaller is true, return 1.
  11. Return +0.
Note 1

Because non-existent property values always compare greater than undefined property values, and undefined always compares greater than any other value, undefined property values always sort to the end of the result, followed by non-existent property values.

Note 2

Method calls performed by the ToString abstract operations in steps 5 and 7 have the potential to cause SortCompare to not behave as a consistent comparison function.

22.1.3.26Array.prototype.splice (start, deleteCount, ...items )#

Note 1

When the splice method is called with two or more arguments start, deleteCount and zero or more items, the deleteCount elements of the array starting at integer index start are replaced by the arguments items. An Array object containing the deleted elements (if any) is returned.

The following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. Let relativeStart be ? ToInteger(start).
  4. If relativeStart < 0, let actualStart be max((len + relativeStart), 0); else let actualStart be min(relativeStart, len).
  5. If the number of actual arguments is 0, then
    1. Let insertCount be 0.
    2. Let actualDeleteCount be 0.
  6. Else if the number of actual arguments is 1, then
    1. Let insertCount be 0.
    2. Let actualDeleteCount be len - actualStart.
  7. Else,
    1. Let insertCount be the number of actual arguments minus 2.
    2. Let dc be ? ToInteger(deleteCount).
    3. Let actualDeleteCount be min(max(dc, 0), len - actualStart).
  8. If len+insertCount-actualDeleteCount > 253-1, throw a TypeError exception.
  9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount).
  10. Let k be 0.
  11. Repeat, while k < actualDeleteCount
    1. Let from be ! ToString(actualStart+k).
    2. Let fromPresent be ? HasProperty(O, from).
    3. If fromPresent is true, then
      1. Let fromValue be ? Get(O, from).
      2. Perform ? CreateDataPropertyOrThrow(A, ! ToString(k), fromValue).
    4. Increment k by 1.
  12. Perform ? Set(A, "length", actualDeleteCount, true).
  13. Let items be a List whose elements are, in left to right order, the portion of the actual argument list starting with the third argument. The list is empty if fewer than three arguments were passed.
  14. Let itemCount be the number of elements in items.
  15. If itemCount < actualDeleteCount, then
    1. Let k be actualStart.
    2. Repeat, while k < (len - actualDeleteCount)
      1. Let from be ! ToString(k+actualDeleteCount).
      2. Let to be ! ToString(k+itemCount).
      3. Let fromPresent be ? HasProperty(O, from).
      4. If fromPresent is true, then
        1. Let fromValue be ? Get(O, from).
        2. Perform ? Set(O, to, fromValue, true).
      5. Else fromPresent is false,
        1. Perform ? DeletePropertyOrThrow(O, to).
      6. Increase k by 1.
    3. Let k be len.
    4. Repeat, while k > (len - actualDeleteCount + itemCount)
      1. Perform ? DeletePropertyOrThrow(O, ! ToString(k-1)).
      2. Decrease k by 1.
  16. Else if itemCount > actualDeleteCount, then
    1. Let k be (len - actualDeleteCount).
    2. Repeat, while k > actualStart
      1. Let from be ! ToString(k + actualDeleteCount - 1).
      2. Let to be ! ToString(k + itemCount - 1).
      3. Let fromPresent be ? HasProperty(O, from).
      4. If fromPresent is true, then
        1. Let fromValue be ? Get(O, from).
        2. Perform ? Set(O, to, fromValue, true).
      5. Else fromPresent is false,
        1. Perform ? DeletePropertyOrThrow(O, to).
      6. Decrease k by 1.
  17. Let k be actualStart.
  18. Repeat, while items is not empty
    1. Remove the first element from items and let E be the value of that element.
    2. Perform ? Set(O, ! ToString(k), E, true).
    3. Increase k by 1.
  19. Perform ? Set(O, "length", len - actualDeleteCount + itemCount, true).
  20. Return A.
Note 2

The explicit setting of the length property of the result Array in step 19 was necessary in previous editions of ECMAScript to ensure that its length was correct in situations where the trailing elements of the result Array were not present. Setting length became unnecessary starting in ES2015 when the result Array was initialized to its proper length rather than an empty Array but is carried forward to preserve backward compatibility.

Note 3

The splice function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.27Array.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )#

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the Array.prototype.toLocaleString method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the toLocaleString method is used.

Note 1

The first edition of ECMA-402 did not include a replacement specification for the Array.prototype.toLocaleString method.

The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

The following steps are taken:

  1. Let array be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(array, "length")).
  3. Let separator be the String value for the list-separator String appropriate for the host environment's current locale (this is derived in an implementation-defined way).
  4. If len is zero, return the empty String.
  5. Let firstElement be ? Get(array, "0").
  6. If firstElement is undefined or null, then
    1. Let R be the empty String.
  7. Else,
    1. Let R be ? ToString(? Invoke(firstElement, "toLocaleString")).
  8. Let k be 1.
  9. Repeat, while k < len
    1. Let S be a String value produced by concatenating R and separator.
    2. Let nextElement be ? Get(array, ! ToString(k)).
    3. If nextElement is undefined or null, then
      1. Let R be the empty String.
    4. Else,
      1. Let R be ? ToString(? Invoke(nextElement, "toLocaleString")).
    5. Let R be a String value produced by concatenating S and R.
    6. Increase k by 1.
  10. Return R.
Note 2

The elements of the array are converted to Strings using their toLocaleString methods, and these Strings are then concatenated, separated by occurrences of a separator String that has been derived in an implementation-defined locale-specific way. The result of calling this function is intended to be analogous to the result of toString, except that the result of this function is intended to be locale-specific.

Note 3

The toLocaleString function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.28Array.prototype.toString ( )#

When the toString method is called, the following steps are taken:

  1. Let array be ? ToObject(this value).
  2. Let func be ? Get(array, "join").
  3. If IsCallable(func) is false, let func be the intrinsic function %ObjProto_toString%.
  4. Return ? Call(func, array).
Note

The toString function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.29Array.prototype.unshift ( ...items )#

Note 1

The arguments are prepended to the start of the array, such that their order within the array is the same as the order in which they appear in the argument list.

When the unshift method is called with zero or more arguments item1, item2, etc., the following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Let len be ? ToLength(? Get(O, "length")).
  3. Let argCount be the number of actual arguments.
  4. If argCount > 0, then
    1. If len+argCount > 253-1, throw a TypeError exception.
    2. Let k be len.
    3. Repeat, while k > 0,
      1. Let from be ! ToString(k-1).
      2. Let to be ! ToString(k+argCount-1).
      3. Let fromPresent be ? HasProperty(O, from).
      4. If fromPresent is true, then
        1. Let fromValue be ? Get(O, from).
        2. Perform ? Set(O, to, fromValue, true).
      5. Else fromPresent is false,
        1. Perform ? DeletePropertyOrThrow(O, to).
      6. Decrease k by 1.
    4. Let j be 0.
    5. Let items be a List whose elements are, in left to right order, the arguments that were passed to this function invocation.
    6. Repeat, while items is not empty
      1. Remove the first element from items and let E be the value of that element.
      2. Perform ? Set(O, ! ToString(j), E, true).
      3. Increase j by 1.
  5. Perform ? Set(O, "length", len+argCount, true).
  6. Return len+argCount.

The length property of the unshift method is 1.

Note 2

The unshift function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.30Array.prototype.values ( )#

The following steps are taken:

  1. Let O be ? ToObject(this value).
  2. Return CreateArrayIterator(O, "value").

This function is the %ArrayProto_values% intrinsic object.

22.1.3.31Array.prototype [ @@iterator ] ( )#

The initial value of the @@iterator property is the same function object as the initial value of the Array.prototype.values property.

22.1.3.32Array.prototype [ @@unscopables ]#

The initial value of the @@unscopables data property is an object created by the following steps:

  1. Let blackList be ObjectCreate(null).
  2. Perform CreateDataProperty(blackList, "copyWithin", true).
  3. Perform CreateDataProperty(blackList, "entries", true).
  4. Perform CreateDataProperty(blackList, "fill", true).
  5. Perform CreateDataProperty(blackList, "find", true).
  6. Perform CreateDataProperty(blackList, "findIndex", true).
  7. Perform CreateDataProperty(blackList, "includes", true).
  8. Perform CreateDataProperty(blackList, "keys", true).
  9. Perform CreateDataProperty(blackList, "values", true).
  10. Assert: Each of the above calls will return true.
  11. Return blackList.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Note

The own property names of this object are property names that were not included as standard properties of Array.prototype prior to the ECMAScript 2015 specification. These names are ignored for with statement binding purposes in order to preserve the behaviour of existing code that might use one of these names as a binding in an outer scope that is shadowed by a with statement whose binding object is an Array object.

22.1.4Properties of Array Instances#

Array instances are Array exotic objects and have the internal methods specified for such objects. Array instances inherit properties from the Array prototype object.

Array instances have a length property, and a set of enumerable properties with array index names.

22.1.4.1length#

The length property of an Array instance is a data property whose value is always numerically greater than the name of every configurable own property whose name is an array index.

The length property initially has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Note

Reducing the value of the length property has the side-effect of deleting own array elements whose array index is between the old and new length values. However, non-configurable properties can not be deleted. Attempting to set the length property of an Array object to a value that is numerically less than or equal to the largest numeric own property name of an existing non-configurable array indexed property of the array will result in the length being set to a numeric value that is one greater than that non-configurable numeric own property name. See 9.4.2.1.

22.1.5Array Iterator Objects#

An Array Iterator is an object, that represents a specific iteration over some specific Array instance object. There is not a named constructor for Array Iterator objects. Instead, Array iterator objects are created by calling certain methods of Array instance objects.

22.1.5.1CreateArrayIterator Abstract Operation#

Several methods of Array objects return Iterator objects. The abstract operation CreateArrayIterator with arguments array and kind is used to create such iterator objects. It performs the following steps:

  1. Assert: Type(array) is Object.
  2. Let iterator be ObjectCreate(%ArrayIteratorPrototype%, « [[IteratedObject]], [[ArrayIteratorNextIndex]], [[ArrayIterationKind]] »).
  3. Set iterator's [[IteratedObject]] internal slot to array.
  4. Set iterator's [[ArrayIteratorNextIndex]] internal slot to 0.
  5. Set iterator's [[ArrayIterationKind]] internal slot to kind.
  6. Return iterator.

22.1.5.2The %ArrayIteratorPrototype% Object#

All Array Iterator Objects inherit properties from the %ArrayIteratorPrototype% intrinsic object. The %ArrayIteratorPrototype% object is an ordinary object and its [[Prototype]] internal slot is the %IteratorPrototype% intrinsic object. In addition, %ArrayIteratorPrototype% has the following properties:

22.1.5.2.1%ArrayIteratorPrototype%.next( )#

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have all of the internal slots of an Array Iterator Instance (22.1.5.3), throw a TypeError exception.
  4. Let a be the value of the [[IteratedObject]] internal slot of O.
  5. If a is undefined, return CreateIterResultObject(undefined, true).
  6. Let index be the value of the [[ArrayIteratorNextIndex]] internal slot of O.
  7. Let itemKind be the value of the [[ArrayIterationKind]] internal slot of O.
  8. If a has a [[TypedArrayName]] internal slot, then
    1. Let len be the value of a's [[ArrayLength]] internal slot.
  9. Else,
    1. Let len be ? ToLength(? Get(a, "length")).
  10. If indexlen, then
    1. Set the value of the [[IteratedObject]] internal slot of O to undefined.
    2. Return CreateIterResultObject(undefined, true).
  11. Set the value of the [[ArrayIteratorNextIndex]] internal slot of O to index+1.
  12. If itemKind is "key", return CreateIterResultObject(index, false).
  13. Let elementKey be ! ToString(index).
  14. Let elementValue be ? Get(a, elementKey).
  15. If itemKind is "value", let result be elementValue.
  16. Else,
    1. Assert: itemKind is "key+value".
    2. Let result be CreateArrayFromListindex, elementValue »).
  17. Return CreateIterResultObject(result, false).

22.1.5.2.2%ArrayIteratorPrototype% [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "Array Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

22.1.5.3Properties of Array Iterator Instances#

Array Iterator instances are ordinary objects that inherit properties from the %ArrayIteratorPrototype% intrinsic object. Array Iterator instances are initially created with the internal slots listed in Table 49.

Table 49: Internal Slots of Array Iterator Instances
Internal Slot Description
[[IteratedObject]] The object whose array elements are being iterated.
[[ArrayIteratorNextIndex]] The integer index of the next integer index to be examined by this iteration.
[[ArrayIterationKind]] A String value that identifies what is returned for each element of the iteration. The possible values are: "key", "value", "key+value".

22.2TypedArray Objects#

TypedArray objects present an array-like view of an underlying binary data buffer (24.1). Each element of a TypedArray instance has the same underlying binary scalar data type. There is a distinct TypedArray constructor, listed in Table 50, for each of the nine supported element types. Each constructor in Table 50 has a corresponding distinct prototype object.

Table 50: The TypedArray Constructors
Constructor Name and Intrinsic Element Type Element Size Conversion Operation Description Equivalent C Type
Int8Array
%Int8Array%
Int8 1 ToInt8 8-bit 2's complement signed integer signed char
Uint8Array
%Uint8Array%
Uint8 1 ToUint8 8-bit unsigned integer unsigned char
Uint8ClampedArray
%Uint8ClampedArray%
Uint8C 1 ToUint8Clamp 8-bit unsigned integer (clamped conversion) unsigned char
Int16Array
%Int16Array%
Int16 2 ToInt16 16-bit 2's complement signed integer short
Uint16Array
%Uint16Array%
Uint16 2 ToUint16 16-bit unsigned integer unsigned short
Int32Array
%Int32Array%
Int32 4 ToInt32 32-bit 2's complement signed integer int
Uint32Array
%Uint32Array%
Uint32 4 ToUint32 32-bit unsigned integer unsigned int
Float32Array
%Float32Array%
Float32 4 32-bit IEEE floating point float
Float64Array
%Float64Array%
Float64 8 64-bit IEEE floating point double

In the definitions below, references to TypedArray should be replaced with the appropriate constructor name from the above table. The phrase “the element size in bytes” refers to the value in the Element Size column of the table in the row corresponding to the constructor. The phrase “element Type” refers to the value in the Element Type column for that row.

22.2.1The %TypedArray% Intrinsic Object#

The %TypedArray% intrinsic object is a constructor function object that all of the TypedArray constructor object inherit from. %TypedArray% and its corresponding prototype object provide common properties that are inherited by all TypedArray constructors and their instances. The %TypedArray% intrinsic does not have a global name or appear as a property of the global object.

The %TypedArray% intrinsic function object acts as the abstract superclass of the various TypedArray constructors. Because it is an abstract class constructor it will throw an error when invoked. The TypeArray constructors do not perform a super call to it.

22.2.1.1%TypedArray%()#

The %TypedArray% constructor performs the following steps:

  1. Throw a TypeError exception.

The length property of the %TypedArray% constructor function is 0.

22.2.2Properties of the %TypedArray% Intrinsic Object#

The value of the [[Prototype]] internal slot of %TypedArray% is the intrinsic object %FunctionPrototype%.

The name property of the %TypedArray% constructor function is "TypedArray".

The %TypedArray% constructor has the following properties:

22.2.2.1%TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )#

When the from method is called with argument source, and optional arguments mapfn and thisArg, the following steps are taken:

  1. Let C be the this value.
  2. If IsConstructor(C) is false, throw a TypeError exception.
  3. If mapfn was supplied and mapfn is not undefined, then
    1. If IsCallable(mapfn) is false, throw a TypeError exception.
    2. Let mapping be true.
  4. Else, let mapping be false.
  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
  6. Let arrayLike be ? IterableToArrayLike(source).
  7. Let len be ? ToLength(? Get(arrayLike, "length")).
  8. Let targetObj be ? TypedArrayCreate(C, « len »).
  9. Let k be 0.
  10. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kValue be ? Get(arrayLike, Pk).
    3. If mapping is true, then
      1. Let mappedValue be ? Call(mapfn, T, « kValue, k »).
    4. Else, let mappedValue be kValue.
    5. Perform ? Set(targetObj, Pk, mappedValue, true).
    6. Increase k by 1.
  11. Return targetObj.

22.2.2.1.1Runtime Semantics: IterableToArrayLike( items )#

The abstract operation IterableToArrayLike performs the following steps:

  1. Let usingIterator be ? GetMethod(items, @@iterator).
  2. If usingIterator is not undefined, then
    1. Let iterator be ? GetIterator(items, usingIterator).
    2. Let values be a new empty List.
    3. Let next be true.
    4. Repeat, while next is not false
      1. Let next be ? IteratorStep(iterator).
      2. If next is not false, then
        1. Let nextValue be ? IteratorValue(next).
        2. Append nextValue to the end of the List values.
    5. Return CreateArrayFromList(values).
  3. NOTE: items is not an Iterable so assume it is already an array-like object.
  4. Return ! ToObject(items).

22.2.2.2%TypedArray%.of ( ...items )#

When the of method is called with any number of arguments, the following steps are taken:

  1. Let len be the actual number of arguments passed to this function.
  2. Let items be the List of arguments passed to this function.
  3. Let C be the this value.
  4. If IsConstructor(C) is false, throw a TypeError exception.
  5. Let newObj be ? TypedArrayCreate(C, « len »).
  6. Let k be 0.
  7. Repeat, while k < len
    1. Let kValue be items[k].
    2. Let Pk be ! ToString(k).
    3. Perform ? Set(newObj, Pk, kValue, true).
    4. Increase k by 1.
  8. Return newObj.
Note

The items argument is assumed to be a well-formed rest argument value.

22.2.2.3%TypedArray%.prototype#

The initial value of %TypedArray%.prototype is the %TypedArrayPrototype% intrinsic object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

22.2.2.4get %TypedArray% [ @@species ]#

%TypedArray%[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Return the this value.

The value of the name property of this function is "get [Symbol.species]".

Note

%TypedArrayPrototype% methods normally use their this object's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its @@species property.

22.2.3Properties of the %TypedArrayPrototype% Object#

The value of the [[Prototype]] internal slot of the %TypedArrayPrototype% object is the intrinsic object %ObjectPrototype%. The %TypedArrayPrototype% object is an ordinary object. It does not have a [[ViewedArrayBuffer]] or any other of the internal slots that are specific to TypedArray instance objects.

22.2.3.1get %TypedArray%.prototype.buffer#

%TypedArray%.prototype.buffer is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception.
  4. Let buffer be the value of O's [[ViewedArrayBuffer]] internal slot.
  5. Return buffer.

22.2.3.2get %TypedArray%.prototype.byteLength#

%TypedArray%.prototype.byteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception.
  4. Let buffer be the value of O's [[ViewedArrayBuffer]] internal slot.
  5. If IsDetachedBuffer(buffer) is true, return 0.
  6. Let size be the value of O's [[ByteLength]] internal slot.
  7. Return size.

22.2.3.3get %TypedArray%.prototype.byteOffset#

%TypedArray%.prototype.byteOffset is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception.
  4. Let buffer be the value of O's [[ViewedArrayBuffer]] internal slot.
  5. If IsDetachedBuffer(buffer) is true, return 0.
  6. Let offset be the value of O's [[ByteOffset]] internal slot.
  7. Return offset.

22.2.3.4%TypedArray%.prototype.constructor#

The initial value of %TypedArray%.prototype.constructor is the %TypedArray% intrinsic object.

22.2.3.5%TypedArray%.prototype.copyWithin (target, start [ , end ] )#

%TypedArray%.prototype.copyWithin is a distinct function that implements the same algorithm as Array.prototype.copyWithin as defined in 22.1.3.3 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length" and the actual copying of values in step 12 must be performed in a manner that preserves the bit-level encoding of the source data

The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.5.1Runtime Semantics: ValidateTypedArray ( O )#

When called with argument O, the following steps are taken:

  1. If Type(O) is not Object, throw a TypeError exception.
  2. If O does not have a [[TypedArrayName]] internal slot, throw a TypeError exception.
  3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception.
  4. Let buffer be the value of O's [[ViewedArrayBuffer]] internal slot.
  5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  6. Return buffer.

22.2.3.6%TypedArray%.prototype.entries ( )#

The following steps are taken:

  1. Let O be the this value.
  2. Perform ? ValidateTypedArray(O).
  3. Return CreateArrayIterator(O, "key+value").

22.2.3.7%TypedArray%.prototype.every ( callbackfn [ , thisArg ] )#

%TypedArray%.prototype.every is a distinct function that implements the same algorithm as Array.prototype.every as defined in 22.1.3.5 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm and must take into account the possibility that calls to callbackfn may cause the this value to become detached.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.8%TypedArray%.prototype.fill (value [ , start [ , end ] ] )#

%TypedArray%.prototype.fill is a distinct function that implements the same algorithm as Array.prototype.fill as defined in 22.1.3.6 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.9%TypedArray%.prototype.filter ( callbackfn [ , thisArg ] )#

The interpretation and use of the arguments of %TypedArray%.prototype.filter are the same as for Array.prototype.filter as defined in 22.1.3.7.

When the filter method is called with one or two arguments, the following steps are taken:

  1. Let O be the this value.
  2. Perform ? ValidateTypedArray(O).
  3. Let len be the value of O's [[ArrayLength]] internal slot.
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
  6. Let kept be a new empty List.
  7. Let k be 0.
  8. Let captured be 0.
  9. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kValue be ? Get(O, Pk).
    3. Let selected be ToBoolean(? Call(callbackfn, T, « kValue, k, O »)).
    4. If selected is true, then
      1. Append kValue to the end of kept.
      2. Increase captured by 1.
    5. Increase k by 1.
  10. Let A be ? TypedArraySpeciesCreate(O, « captured »).
  11. Let n be 0.
  12. For each element e of kept
    1. Perform ! Set(A, ! ToString(n), e, true).
    2. Increment n by 1.
  13. Return A.

This function is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

22.2.3.10%TypedArray%.prototype.find (predicate [ , thisArg ] )#

%TypedArray%.prototype.find is a distinct function that implements the same algorithm as Array.prototype.find as defined in 22.1.3.8 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm and must take into account the possibility that calls to predicate may cause the this value to become detached.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.11%TypedArray%.prototype.findIndex ( predicate [ , thisArg ] )#

%TypedArray%.prototype.findIndex is a distinct function that implements the same algorithm as Array.prototype.findIndex as defined in 22.1.3.9 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm and must take into account the possibility that calls to predicate may cause the this value to become detached.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.12%TypedArray%.prototype.forEach ( callbackfn [ , thisArg ] )#

%TypedArray%.prototype.forEach is a distinct function that implements the same algorithm as Array.prototype.forEach as defined in 22.1.3.10 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm and must take into account the possibility that calls to callbackfn may cause the this value to become detached.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.13%TypedArray%.prototype.indexOf (searchElement [ , fromIndex ] )#

%TypedArray%.prototype.indexOf is a distinct function that implements the same algorithm as Array.prototype.indexOf as defined in 22.1.3.12 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.14%TypedArray%.prototype.includes ( searchElement [ , fromIndex ] )#

%TypedArray%.prototype.includes is a distinct function that implements the same algorithm as Array.prototype.includes as defined in 22.1.3.11 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.15%TypedArray%.prototype.join ( separator )#

%TypedArray%.prototype.join is a distinct function that implements the same algorithm as Array.prototype.join as defined in 22.1.3.13 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.16%TypedArray%.prototype.keys ( )#

The following steps are taken:

  1. Let O be the this value.
  2. Perform ? ValidateTypedArray(O).
  3. Return CreateArrayIterator(O, "key").

22.2.3.17%TypedArray%.prototype.lastIndexOf ( searchElement [ , fromIndex ] )#

%TypedArray%.prototype.lastIndexOf is a distinct function that implements the same algorithm as Array.prototype.lastIndexOf as defined in 22.1.3.15 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.18get %TypedArray%.prototype.length#

%TypedArray%.prototype.length is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have a [[TypedArrayName]] internal slot, throw a TypeError exception.
  4. Assert: O has [[ViewedArrayBuffer]] and [[ArrayLength]] internal slots.
  5. Let buffer be the value of O's [[ViewedArrayBuffer]] internal slot.
  6. If IsDetachedBuffer(buffer) is true, return 0.
  7. Let length be the value of O's [[ArrayLength]] internal slot.
  8. Return length.

This function is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

22.2.3.19%TypedArray%.prototype.map ( callbackfn [ , thisArg ] )#

The interpretation and use of the arguments of %TypedArray%.prototype.map are the same as for Array.prototype.map as defined in 22.1.3.16.

When the map method is called with one or two arguments, the following steps are taken:

  1. Let O be the this value.
  2. Perform ? ValidateTypedArray(O).
  3. Let len be the value of O's [[ArrayLength]] internal slot.
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
  6. Let A be ? TypedArraySpeciesCreate(O, « len »).
  7. Let k be 0.
  8. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kValue be ? Get(O, Pk).
    3. Let mappedValue be ? Call(callbackfn, T, « kValue, k, O »).
    4. Perform ? Set(A, Pk, mappedValue, true).
    5. Increase k by 1.
  9. Return A.

This function is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

22.2.3.20%TypedArray%.prototype.reduce ( callbackfn [ , initialValue ] )#

%TypedArray%.prototype.reduce is a distinct function that implements the same algorithm as Array.prototype.reduce as defined in 22.1.3.19 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm and must take into account the possibility that calls to callbackfn may cause the this value to become detached.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.21%TypedArray%.prototype.reduceRight ( callbackfn [ , initialValue ] )#

%TypedArray%.prototype.reduceRight is a distinct function that implements the same algorithm as Array.prototype.reduceRight as defined in 22.1.3.20 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm and must take into account the possibility that calls to callbackfn may cause the this value to become detached.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.22%TypedArray%.prototype.reverse ( )#

%TypedArray%.prototype.reverse is a distinct function that implements the same algorithm as Array.prototype.reverse as defined in 22.1.3.21 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.23%TypedArray%.prototype.set ( overloaded [ , offset ])#

%TypedArray%.prototype.set is a single function whose behaviour is overloaded based upon the type of its first argument.

This function is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

22.2.3.23.1%TypedArray%.prototype.set (array [ , offset ] )#

Sets multiple values in this TypedArray, reading the values from the object array. The optional offset value indicates the first element index in this TypedArray where values are written. If omitted, it is assumed to be 0.

  1. Assert: array is any ECMAScript language value other than an Object with a [[TypedArrayName]] internal slot. If it is such an Object, the definition in 22.2.3.23.2 applies.
  2. Let target be the this value.
  3. If Type(target) is not Object, throw a TypeError exception.
  4. If target does not have a [[TypedArrayName]] internal slot, throw a TypeError exception.
  5. Assert: target has a [[ViewedArrayBuffer]] internal slot.
  6. Let targetOffset be ? ToInteger(offset).
  7. If targetOffset < 0, throw a RangeError exception.
  8. Let targetBuffer be the value of target's [[ViewedArrayBuffer]] internal slot.
  9. If IsDetachedBuffer(targetBuffer) is true, throw a TypeError exception.
  10. Let targetLength be the value of target's [[ArrayLength]] internal slot.
  11. Let targetName be the String value of target's [[TypedArrayName]] internal slot.
  12. Let targetElementSize be the Number value of the Element Size value specified in Table 50 for targetName.
  13. Let targetType be the String value of the Element Type value in Table 50 for targetName.
  14. Let targetByteOffset be the value of target's [[ByteOffset]] internal slot.
  15. Let src be ? ToObject(array).
  16. Let srcLength be ? ToLength(? Get(src, "length")).
  17. If srcLength + targetOffset > targetLength, throw a RangeError exception.
  18. Let targetByteIndex be targetOffset × targetElementSize + targetByteOffset.
  19. Let k be 0.
  20. Let limit be targetByteIndex + targetElementSize × srcLength.
  21. Repeat, while targetByteIndex < limit
    1. Let Pk be ! ToString(k).
    2. Let kNumber be ? ToNumber(? Get(src, Pk)).
    3. If IsDetachedBuffer(targetBuffer) is true, throw a TypeError exception.
    4. Perform SetValueInBuffer(targetBuffer, targetByteIndex, targetType, kNumber).
    5. Set k to k + 1.
    6. Set targetByteIndex to targetByteIndex + targetElementSize.
  22. Return undefined.

22.2.3.23.2%TypedArray%.prototype.set(typedArray [ , offset ] )#

Sets multiple values in this TypedArray, reading the values from the typedArray argument object. The optional offset value indicates the first element index in this TypedArray where values are written. If omitted, it is assumed to be 0.

  1. Assert: typedArray has a [[TypedArrayName]] internal slot. If it does not, the definition in 22.2.3.23.1 applies.
  2. Let target be the this value.
  3. If Type(target) is not Object, throw a TypeError exception.
  4. If target does not have a [[TypedArrayName]] internal slot, throw a TypeError exception.
  5. Assert: target has a [[ViewedArrayBuffer]] internal slot.
  6. Let targetOffset be ? ToInteger(offset).
  7. If targetOffset < 0, throw a RangeError exception.
  8. Let targetBuffer be the value of target's [[ViewedArrayBuffer]] internal slot.
  9. If IsDetachedBuffer(targetBuffer) is true, throw a TypeError exception.
  10. Let targetLength be the value of target's [[ArrayLength]] internal slot.
  11. Let srcBuffer be the value of typedArray's [[ViewedArrayBuffer]] internal slot.
  12. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception.
  13. Let targetName be the String value of target's [[TypedArrayName]] internal slot.
  14. Let targetType be the String value of the Element Type value in Table 50 for targetName.
  15. Let targetElementSize be the Number value of the Element Size value specified in Table 50 for targetName.
  16. Let targetByteOffset be the value of target's [[ByteOffset]] internal slot.
  17. Let srcName be the String value of typedArray's [[TypedArrayName]] internal slot.
  18. Let srcType be the String value of the Element Type value in Table 50 for srcName.
  19. Let srcElementSize be the Number value of the Element Size value specified in Table 50 for srcName.
  20. Let srcLength be the value of typedArray's [[ArrayLength]] internal slot.
  21. Let srcByteOffset be the value of typedArray's [[ByteOffset]] internal slot.
  22. If srcLength + targetOffset > targetLength, throw a RangeError exception.
  23. If SameValue(srcBuffer, targetBuffer) is true, then
    1. Let srcBuffer be ? CloneArrayBuffer(targetBuffer, srcByteOffset, %ArrayBuffer%).
    2. NOTE: %ArrayBuffer% is used to clone targetBuffer because is it known to not have any observable side-effects.
    3. Let srcByteIndex be 0.
  24. Else, let srcByteIndex be srcByteOffset.
  25. Let targetByteIndex be targetOffset × targetElementSize + targetByteOffset.
  26. Let limit be targetByteIndex + targetElementSize × srcLength.
  27. If SameValue(srcType, targetType) is false, then
    1. Repeat, while targetByteIndex < limit
      1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, srcType).
      2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, targetType, value).
      3. Set srcByteIndex to srcByteIndex + srcElementSize.
      4. Set targetByteIndex to targetByteIndex + targetElementSize.
  28. Else,
    1. NOTE: If srcType and targetType are the same, the transfer must be performed in a manner that preserves the bit-level encoding of the source data.
    2. Repeat, while targetByteIndex < limit
      1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, "Uint8").
      2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, "Uint8", value).
      3. Set srcByteIndex to srcByteIndex + 1.
      4. Set targetByteIndex to targetByteIndex + 1.
  29. Return undefined.

22.2.3.24%TypedArray%.prototype.slice ( start, end )#

The interpretation and use of the arguments of %TypedArray%.prototype.slice are the same as for Array.prototype.slice as defined in 22.1.3.23. The following steps are taken:

  1. Let O be the this value.
  2. Perform ? ValidateTypedArray(O).
  3. Let len be the value of O's [[ArrayLength]] internal slot.
  4. Let relativeStart be ? ToInteger(start).
  5. If relativeStart < 0, let k be max((len + relativeStart), 0); else let k be min(relativeStart, len).
  6. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToInteger(end).
  7. If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let final be min(relativeEnd, len).
  8. Let count be max(final - k, 0).
  9. Let A be ? TypedArraySpeciesCreate(O, « count »).
  10. Let srcName be the String value of O's [[TypedArrayName]] internal slot.
  11. Let srcType be the String value of the Element Type value in Table 50 for srcName.
  12. Let targetName be the String value of A's [[TypedArrayName]] internal slot.
  13. Let targetType be the String value of the Element Type value in Table 50 for targetName.
  14. If SameValue(srcType, targetType) is false, then
    1. Let n be 0.
    2. Repeat, while k < final
      1. Let Pk be ! ToString(k).
      2. Let kValue be ? Get(O, Pk).
      3. Perform ? Set(A, ! ToString(n), kValue, true).
      4. Increase k by 1.
      5. Increase n by 1.
  15. Else if count > 0, then
    1. Let srcBuffer be the value of O's [[ViewedArrayBuffer]] internal slot.
    2. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception.
    3. Let targetBuffer be the value of A's [[ViewedArrayBuffer]] internal slot.
    4. Let elementSize be the Number value of the Element Size value specified in Table 50 for srcType.
    5. NOTE: If srcType and targetType are the same, the transfer must be performed in a manner that preserves the bit-level encoding of the source data.
    6. Let srcByteOffet be the value of O's [[ByteOffset]] internal slot.
    7. Let targetByteIndex be A's [[ByteOffset]] internal slot.
    8. Let srcByteIndex be (k × elementSize) + srcByteOffet.
    9. Let limit be targetByteIndex + count × elementSize.
    10. Repeat, while targetByteIndex < limit
      1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, "Uint8").
      2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, "Uint8", value).
      3. Increase srcByteIndex by 1.
      4. Increase targetByteIndex by 1.
  16. Return A.

This function is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

22.2.3.25%TypedArray%.prototype.some ( callbackfn [ , thisArg ] )#

%TypedArray%.prototype.some is a distinct function that implements the same algorithm as Array.prototype.some as defined in 22.1.3.24 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm and must take into account the possibility that calls to callbackfn may cause the this value to become detached.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

22.2.3.26%TypedArray%.prototype.sort ( comparefn )#

%TypedArray%.prototype.sort is a distinct function that, except as described below, implements the same requirements as those of Array.prototype.sort as defined in 22.1.3.25. The implementation of the %TypedArray%.prototype.sort specification may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. The only internal methods of the this object that the algorithm may call are [[Get]] and [[Set]].

This function is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

Upon entry, the following steps are performed to initialize evaluation of the sort function. These steps are used instead of the entry steps in 22.1.3.25:

  1. Let obj be the this value.
  2. Let buffer be ? ValidateTypedArray(obj).
  3. Let len be the value of obj's [[ArrayLength]] internal slot.

The implementation defined sort order condition for exotic objects is not applied by %TypedArray%.prototype.sort.

The following version of SortCompare is used by %TypedArray%.prototype.sort. It performs a numeric comparison rather than the string comparison used in 22.1.3.25. SortCompare has access to the comparefn and buffer values of the current invocation of the sort method.

When the TypedArray SortCompare abstract operation is called with two arguments x and y, the following steps are taken:

  1. Assert: Both Type(x) and Type(y) is Number.
  2. If the argument comparefn is not undefined, then
    1. Let v be ? Call(comparefn, undefined, « x, y »).
    2. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
    3. If v is NaN, return +0.
    4. Return v.
  3. If x and y are both NaN, return +0.
  4. If x is NaN, return 1.
  5. If y is NaN, return -1.
  6. If x < y, return -1.
  7. If x > y, return 1.
  8. If x is -0 and y is +0, return -1.
  9. If x is +0 and y is -0, return 1.
  10. Return +0.
Note

Because NaN always compares greater than any other value, NaN property values always sort to the end of the result when comparefn is not provided.

22.2.3.27%TypedArray%.prototype.subarray( begin, end )#

Returns a new TypedArray object whose element type is the same as this TypedArray and whose ArrayBuffer is the same as the ArrayBuffer of this TypedArray, referencing the elements at begin, inclusive, up to end, exclusive. If either begin or end is negative, it refers to an index from the end of the array, as opposed to from the beginning.

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have a [[TypedArrayName]] internal slot, throw a TypeError exception.
  4. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  5. Let buffer be the value of O's [[ViewedArrayBuffer]] internal slot.
  6. Let srcLength be the value of O's [[ArrayLength]] internal slot.
  7. Let relativeBegin be ? ToInteger(begin).
  8. If relativeBegin < 0, let beginIndex be max((srcLength + relativeBegin), 0); else let beginIndex be min(relativeBegin, srcLength).
  9. If end is undefined, let relativeEnd be srcLength; else, let relativeEnd be ? ToInteger(end).
  10. If relativeEnd < 0, let endIndex be max((srcLength + relativeEnd), 0); else let endIndex be min(relativeEnd, srcLength).
  11. Let newLength be max(endIndex - beginIndex, 0).
  12. Let constructorName be the String value of O's [[TypedArrayName]] internal slot.
  13. Let elementSize be the Number value of the Element Size value specified in Table 50 for constructorName.
  14. Let srcByteOffset be the value of O's [[ByteOffset]] internal slot.
  15. Let beginByteOffset be srcByteOffset + beginIndex × elementSize.
  16. Let argumentsList be « buffer, beginByteOffset, newLength ».
  17. Return ? TypedArraySpeciesCreate(O, argumentsList).

This function is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

22.2.3.28%TypedArray%.prototype.toLocaleString ([ reserved1 [ , reserved2 ] ])#

%TypedArray%.prototype.toLocaleString is a distinct function that implements the same algorithm as Array.prototype.toLocaleString as defined in 22.1.3.27 except that the this object's [[ArrayLength]] internal slot is accessed in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic. ValidateTypedArray is applied to the this value prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

Note

If the ECMAScript implementation includes the ECMA-402 Internationalization API this function is based upon the algorithm for Array.prototype.toLocaleString that is in the ECMA-402 specification.

22.2.3.29%TypedArray%.prototype.toString ( )#

The initial value of the %TypedArray%.prototype.toString data property is the same built-in function object as the Array.prototype.toString method defined in 22.1.3.28.

22.2.3.30%TypedArray%.prototype.values ( )#

The following steps are taken:

  1. Let O be the this value.
  2. Perform ? ValidateTypedArray(O).
  3. Return CreateArrayIterator(O, "value").

22.2.3.31%TypedArray%.prototype [ @@iterator ] ( )#

The initial value of the @@iterator property is the same function object as the initial value of the %TypedArray%.prototype.values property.

22.2.3.32get %TypedArray%.prototype [ @@toStringTag ]#

%TypedArray%.prototype[@@toStringTag] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let O be the this value.
  2. If Type(O) is not Object, return undefined.
  3. If O does not have a [[TypedArrayName]] internal slot, return undefined.
  4. Let name be the value of O's [[TypedArrayName]] internal slot.
  5. Assert: name is a String value.
  6. Return name.

This property has the attributes { [[Enumerable]]: false, [[Configurable]]: true }.

The initial value of the name property of this function is "get [Symbol.toStringTag]".

22.2.4The TypedArray Constructors#

Each of the TypedArray constructor objects is an intrinsic object that has the structure described below, differing only in the name used as the constructor name instead of TypedArray, in Table 50.

The TypedArray intrinsic constructor functions are single functions whose behaviour is overloaded based upon the number and types of its arguments. The actual behaviour of a call of TypedArray depends upon the number and kind of arguments that are passed to it.

The TypedArray constructors are not intended to be called as a function and will throw an exception when called in that manner.

The TypedArray constructors are designed to be subclassable. They may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified TypedArray behaviour must include a super call to the TypedArray constructor to create and initialize the subclass instance with the internal state necessary to support the %TypedArray%.prototype built-in methods.

The length property of the TypedArray constructor function is 3.

22.2.4.1TypedArray ( )#

This description applies only if the TypedArray function is called with no arguments.

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let constructorName be the String value of the Constructor Name value specified in Table 50 for this TypedArray constructor.
  3. Return ? AllocateTypedArray(constructorName, NewTarget, "%TypedArrayPrototype%", 0).

22.2.4.2TypedArray ( length )#

This description applies only if the TypedArray function is called with at least one argument and the Type of the first argument is not Object.

TypedArray called with argument length performs the following steps:

  1. Assert: Type(length) is not Object.
  2. If NewTarget is undefined, throw a TypeError exception.
  3. If length is undefined, throw a TypeError exception.
  4. Let numberLength be ? ToNumber(length).
  5. Let elementLength be ToLength(numberLength).
  6. If SameValueZero(numberLength, elementLength) is false, throw a RangeError exception.
  7. Let constructorName be the String value of the Constructor Name value specified in Table 50 for this TypedArray constructor.
  8. Return ? AllocateTypedArray(constructorName, NewTarget, "%TypedArrayPrototype%", elementLength).

22.2.4.2.1Runtime Semantics: AllocateTypedArray (constructorName, newTarget, defaultProto [ , length ])#

The abstract operation AllocateTypedArray with arguments constructorName, newTarget, defaultProto and optional argument length is used to validate and create an instance of a TypedArray constructor. constructorName is required to be the name of a TypedArray constructor in Table 50. If the length argument is passed an ArrayBuffer of that length is also allocated and associated with the new TypedArray instance. AllocateTypedArray provides common semantics that is used by all of the TypedArray overloads. AllocateTypedArray performs the following steps:

  1. Let proto be ? GetPrototypeFromConstructor(newTarget, defaultProto).
  2. Let obj be IntegerIndexedObjectCreate(proto, « [[ViewedArrayBuffer]], [[TypedArrayName]], [[ByteLength]], [[ByteOffset]], [[ArrayLength]] »).
  3. Assert: The [[ViewedArrayBuffer]] internal slot of obj is undefined.
  4. Set obj's [[TypedArrayName]] internal slot to constructorName.
  5. If length was not passed, then
    1. Set obj's [[ByteLength]] internal slot to 0.
    2. Set obj's [[ByteOffset]] internal slot to 0.
    3. Set obj's [[ArrayLength]] internal slot to 0.
  6. Else,
    1. Perform ? AllocateTypedArrayBuffer(obj, length).
  7. Return obj.

22.2.4.2.2Runtime Semantics: AllocateTypedArrayBuffer ( O, length )#

The abstract operation AllocateTypedArrayBuffer with arguments O and length allocates and associates an ArrayBuffer with the TypedArray instance O. It performs the following steps:

  1. Assert: O is an Object that has a [[ViewedArrayBuffer]] internal slot.
  2. Assert: The [[ViewedArrayBuffer]] internal slot of O is undefined.
  3. Assert: length ≥ 0.
  4. Let constructorName be the String value of O's [[TypedArrayName]] internal slot.
  5. Let elementSize be the Element Size value in Table 50 for constructorName.
  6. Let byteLength be elementSize × length.
  7. Let data be ? AllocateArrayBuffer(%ArrayBuffer%, byteLength).
  8. Set O's [[ViewedArrayBuffer]] internal slot to data.
  9. Set O's [[ByteLength]] internal slot to byteLength.
  10. Set O's [[ByteOffset]] internal slot to 0.
  11. Set O's [[ArrayLength]] internal slot to length.
  12. Return O.

22.2.4.3TypedArray ( typedArray )#

This description applies only if the TypedArray function is called with at least one argument and the Type of the first argument is Object and that object has a [[TypedArrayName]] internal slot.

TypedArray called with argument typedArray performs the following steps:

  1. Assert: Type(typedArray) is Object and typedArray has a [[TypedArrayName]] internal slot.
  2. If NewTarget is undefined, throw a TypeError exception.
  3. Let constructorName be the String value of the Constructor Name value specified in Table 50 for this TypedArray constructor.
  4. Let O be ? AllocateTypedArray(constructorName, NewTarget, "%TypedArrayPrototype%").
  5. Let srcArray be typedArray.
  6. Let srcData be the value of srcArray's [[ViewedArrayBuffer]] internal slot.
  7. If IsDetachedBuffer(srcData) is true, throw a TypeError exception.
  8. Let constructorName be the String value of O's [[TypedArrayName]] internal slot.
  9. Let elementType be the String value of the Element Type value in Table 50 for constructorName.
  10. Let elementLength be the value of srcArray's [[ArrayLength]] internal slot.
  11. Let srcName be the String value of srcArray's [[TypedArrayName]] internal slot.
  12. Let srcType be the String value of the Element Type value in Table 50 for srcName.
  13. Let srcElementSize be the Element Size value in Table 50 for srcName.
  14. Let srcByteOffset be the value of srcArray's [[ByteOffset]] internal slot.
  15. Let elementSize be the Element Size value in Table 50 for constructorName.
  16. Let byteLength be elementSize × elementLength.
  17. If SameValue(elementType, srcType) is true, then
    1. Let data be ? CloneArrayBuffer(srcData, srcByteOffset).
  18. Else,
    1. Let bufferConstructor be ? SpeciesConstructor(srcData, %ArrayBuffer%).
    2. Let data be ? AllocateArrayBuffer(bufferConstructor, byteLength).
    3. If IsDetachedBuffer(srcData) is true, throw a TypeError exception.
    4. Let srcByteIndex be srcByteOffset.
    5. Let targetByteIndex be 0.
    6. Let count be elementLength.
    7. Repeat, while count > 0
      1. Let value be GetValueFromBuffer(srcData, srcByteIndex, srcType).
      2. Perform SetValueInBuffer(data, targetByteIndex, elementType, value).
      3. Set srcByteIndex to srcByteIndex + srcElementSize.
      4. Set targetByteIndex to targetByteIndex + elementSize.
      5. Decrement count by 1.
  19. Set O's [[ViewedArrayBuffer]] internal slot to data.
  20. Set O's [[ByteLength]] internal slot to byteLength.
  21. Set O's [[ByteOffset]] internal slot to 0.
  22. Set O's [[ArrayLength]] internal slot to elementLength.
  23. Return O.

22.2.4.4TypedArray ( object )#

This description applies only if the TypedArray function is called with at least one argument and the Type of the first argument is Object and that object does not have either a [[TypedArrayName]] or an [[ArrayBufferData]] internal slot.

TypedArray called with argument object performs the following steps:

  1. Assert: Type(object) is Object and object does not have either a [[TypedArrayName]] or an [[ArrayBufferData]] internal slot.
  2. If NewTarget is undefined, throw a TypeError exception.
  3. Let constructorName be the String value of the Constructor Name value specified in Table 50 for this TypedArray constructor.
  4. Let O be ? AllocateTypedArray(constructorName, NewTarget, "%TypedArrayPrototype%").
  5. Let arrayLike be ? IterableToArrayLike(object).
  6. Let len be ? ToLength(? Get(arrayLike, "length")).
  7. Perform ? AllocateTypedArrayBuffer(O, len).
  8. Let k be 0.
  9. Repeat, while k < len
    1. Let Pk be ! ToString(k).
    2. Let kValue be ? Get(arrayLike, Pk).
    3. Perform ? Set(O, Pk, kValue, true).
    4. Increase k by 1.
  10. Return O.

22.2.4.5TypedArray ( buffer [ , byteOffset [ , length ] ] )#

This description applies only if the TypedArray function is called with at least one argument and the Type of the first argument is Object and that object has an [[ArrayBufferData]] internal slot.

TypedArray called with arguments buffer, byteOffset, and length performs the following steps:

  1. Assert: Type(buffer) is Object and buffer has an [[ArrayBufferData]] internal slot.
  2. If NewTarget is undefined, throw a TypeError exception.
  3. Let constructorName be the String value of the Constructor Name value specified in Table 50 for this TypedArray constructor.
  4. Let O be ? AllocateTypedArray(constructorName, NewTarget, "%TypedArrayPrototype%").
  5. Let constructorName be the String value of O's [[TypedArrayName]] internal slot.
  6. Let elementSize be the Number value of the Element Size value in Table 50 for constructorName.
  7. Let offset be ? ToInteger(byteOffset).
  8. If offset < 0, throw a RangeError exception.
  9. If offset is -0, let offset be +0.
  10. If offset modulo elementSize ≠ 0, throw a RangeError exception.
  11. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  12. Let bufferByteLength be the value of buffer's [[ArrayBufferByteLength]] internal slot.
  13. If length is undefined, then
    1. If bufferByteLength modulo elementSize ≠ 0, throw a RangeError exception.
    2. Let newByteLength be bufferByteLength - offset.
    3. If newByteLength < 0, throw a RangeError exception.
  14. Else,
    1. Let newLength be ? ToLength(length).
    2. Let newByteLength be newLength × elementSize.
    3. If offset+newByteLength > bufferByteLength, throw a RangeError exception.
  15. Set O's [[ViewedArrayBuffer]] internal slot to buffer.
  16. Set O's [[ByteLength]] internal slot to newByteLength.
  17. Set O's [[ByteOffset]] internal slot to offset.
  18. Set O's [[ArrayLength]] internal slot to newByteLength / elementSize.
  19. Return O.

22.2.4.6TypedArrayCreate ( constructor, argumentList )#

The abstract operation TypedArrayCreate with arguments constructor and argumentList is used to specify the creation of a new TypedArray object using a constructor function. It performs the following steps:

  1. Let newTypedArray be ? Construct(constructor, argumentList).
  2. Perform ? ValidateTypedArray(newTypedArray).
  3. If argumentList is a List of a single Number, then
    1. If the value of newTypedArray's [[ArrayLength]] internal slot < argumentList[0], throw a TypeError exception.
  4. Return newTypedArray.

22.2.4.7TypedArraySpeciesCreate ( exemplar, argumentList )#

The abstract operation TypedArraySpeciesCreate with arguments exemplar and argumentList is used to specify the creation of a new TypedArray object using a constructor function that is derived from exemplar. It performs the following steps:

  1. Assert: exemplar is an Object that has a [[TypedArrayName]] internal slot.
  2. Let defaultConstructor be the intrinsic object listed in column one of Table 50 for the value of exemplar's [[TypedArrayName]] internal slot.
  3. Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor).
  4. Return ? TypedArrayCreate(constructor, argumentList).

22.2.5Properties of the TypedArray Constructors#

The value of the [[Prototype]] internal slot of each TypedArray constructor is the %TypedArray% intrinsic object.

Each TypedArray constructor has a name property whose value is the String value of the constructor name specified for it in Table 50.

Each TypedArray constructor has the following properties:

22.2.5.1TypedArray.BYTES_PER_ELEMENT#

The value of TypedArray.BYTES_PER_ELEMENT is the Number value of the Element Size value specified in Table 50 for TypedArray.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

22.2.5.2TypedArray.prototype#

The initial value of TypedArray.prototype is the corresponding TypedArray prototype intrinsic object (22.2.6).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

22.2.6Properties of TypedArray Prototype Objects#

The value of the [[Prototype]] internal slot of a TypedArray prototype object is the intrinsic object %TypedArrayPrototype%. A TypedArray prototype object is an ordinary object. It does not have a [[ViewedArrayBuffer]] or any other of the internal slots that are specific to TypedArray instance objects.

22.2.6.1TypedArray.prototype.BYTES_PER_ELEMENT#

The value of TypedArray.prototype.BYTES_PER_ELEMENT is the Number value of the Element Size value specified in Table 50 for TypedArray.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

22.2.6.2TypedArray.prototype.constructor#

The initial value of a TypedArray.prototype.constructor is the corresponding %TypedArray% intrinsic object.

22.2.7Properties of TypedArray Instances#

TypedArray instances are Integer Indexed exotic objects. Each TypedArray instance inherits properties from the corresponding TypedArray prototype object. Each TypedArray instance has the following internal slots: [[TypedArrayName]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]], and [[ArrayLength]].

23Keyed Collection#

23.1Map Objects#

Map objects are collections of key/value pairs where both the keys and values may be arbitrary ECMAScript language values. A distinct key value may only occur in one key/value pair within the Map's collection. Distinct key values are discriminated using the SameValueZero comparison algorithm.

Map object must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structures used in this Map objects specification is only intended to describe the required observable semantics of Map objects. It is not intended to be a viable implementation model.

23.1.1The Map Constructor#

The Map constructor is the %Map% intrinsic object and the initial value of the Map property of the global object. When called as a constructor it creates and initializes a new Map object. Map is not intended to be called as a function and will throw an exception when called in that manner.

The Map constructor is designed to be subclassable. It may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified Map behaviour must include a super call to the Map constructor to create and initialize the subclass instance with the internal state necessary to support the Map.prototype built-in methods.

23.1.1.1Map ( [ iterable ] )#

When the Map function is called with optional argument, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let map be ? OrdinaryCreateFromConstructor(NewTarget, "%MapPrototype%", « [[MapData]] »).
  3. Set map's [[MapData]] internal slot to a new empty List.
  4. If iterable is not present, let iterable be undefined.
  5. If iterable is either undefined or null, let iter be undefined.
  6. Else,
    1. Let adder be ? Get(map, "set").
    2. If IsCallable(adder) is false, throw a TypeError exception.
    3. Let iter be ? GetIterator(iterable).
  7. If iter is undefined, return map.
  8. Repeat
    1. Let next be ? IteratorStep(iter).
    2. If next is false, return map.
    3. Let nextItem be ? IteratorValue(next).
    4. If Type(nextItem) is not Object, then
      1. Let error be Completion{[[Type]]: throw, [[Value]]: a newly created TypeError object, [[Target]]: empty}.
      2. Return ? IteratorClose(iter, error).
    5. Let k be Get(nextItem, "0").
    6. If k is an abrupt completion, return ? IteratorClose(iter, k).
    7. Let v be Get(nextItem, "1").
    8. If v is an abrupt completion, return ? IteratorClose(iter, v).
    9. Let status be Call(adder, map, « k.[[Value]], v.[[Value]] »).
    10. If status is an abrupt completion, return ? IteratorClose(iter, status).
Note

If the parameter iterable is present, it is expected to be an object that implements an @@iterator method that returns an iterator object that produces a two element array-like object whose first element is a value that will be used as a Map key and whose second element is the value to associate with that key.

23.1.2Properties of the Map Constructor#

The value of the [[Prototype]] internal slot of the Map constructor is the intrinsic object %FunctionPrototype%.

The Map constructor has the following properties:

23.1.2.1Map.prototype#

The initial value of Map.prototype is the intrinsic object %MapPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.1.2.2get Map [ @@species ]#

Map[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Return the this value.

The value of the name property of this function is "get [Symbol.species]".

Note

Methods that create derived collection objects should call @@species to determine the constructor to use to create the derived objects. Subclass constructor may over-ride @@species to change the default constructor assignment.

23.1.3Properties of the Map Prototype Object#

The Map prototype object is the intrinsic object %MapPrototype%. The value of the [[Prototype]] internal slot of the Map prototype object is the intrinsic object %ObjectPrototype%. The Map prototype object is an ordinary object. It does not have a [[MapData]] internal slot.

23.1.3.1Map.prototype.clear ( )#

The following steps are taken:

  1. Let M be the this value.
  2. If Type(M) is not Object, throw a TypeError exception.
  3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of M's [[MapData]] internal slot.
  5. Repeat for each Record {[[Key]], [[Value]]} p that is an element of entries,
    1. Set p.[[Key]] to empty.
    2. Set p.[[Value]] to empty.
  6. Return undefined.
Note

The existing [[MapData]] List is preserved because there may be existing Map Iterator objects that are suspended midway through iterating over that List.

23.1.3.2Map.prototype.constructor#

The initial value of Map.prototype.constructor is the intrinsic object %Map%.

23.1.3.3Map.prototype.delete ( key )#

The following steps are taken:

  1. Let M be the this value.
  2. If Type(M) is not Object, throw a TypeError exception.
  3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of M's [[MapData]] internal slot.
  5. Repeat for each Record {[[Key]], [[Value]]} p that is an element of entries,
    1. If p.[[Key]] is not empty and SameValueZero(p.[[Key]], key) is true, then
      1. Set p.[[Key]] to empty.
      2. Set p.[[Value]] to empty.
      3. Return true.
  6. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

23.1.3.4Map.prototype.entries ( )#

The following steps are taken:

  1. Let M be the this value.
  2. Return ? CreateMapIterator(M, "key+value").

23.1.3.5Map.prototype.forEach ( callbackfn [ , thisArg ] )#

When the forEach method is called with one or two arguments, the following steps are taken:

  1. Let M be the this value.
  2. If Type(M) is not Object, throw a TypeError exception.
  3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
  6. Let entries be the List that is the value of M's [[MapData]] internal slot.
  7. Repeat for each Record {[[Key]], [[Value]]} e that is an element of entries, in original key insertion order
    1. If e.[[Key]] is not empty, then
      1. Perform ? Call(callbackfn, T, « e.[[Value]], e.[[Key]], M »).
  8. Return undefined.
Note

callbackfn should be a function that accepts three arguments. forEach calls callbackfn once for each key/value pair present in the map object, in key insertion order. callbackfn is called only for keys of the map which actually exist; it is not called for keys that have been deleted from the map.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the item, the key of the item, and the Map object being traversed.

forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn. Each entry of a map's [[MapData]] is only visited once. New keys added after the call to forEach begins are visited. A key will be revisited if it is deleted after it has been visited and then re-added before the forEach call completes. Keys that are deleted after the call to forEach begins and before being visited are not visited unless the key is added again before the forEach call completes.

23.1.3.6Map.prototype.get ( key )#

The following steps are taken:

  1. Let M be the this value.
  2. If Type(M) is not Object, throw a TypeError exception.
  3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of M's [[MapData]] internal slot.
  5. Repeat for each Record {[[Key]], [[Value]]} p that is an element of entries,
    1. If p.[[Key]] is not empty and SameValueZero(p.[[Key]], key) is true, return p.[[Value]].
  6. Return undefined.

23.1.3.7Map.prototype.has ( key )#

The following steps are taken:

  1. Let M be the this value.
  2. If Type(M) is not Object, throw a TypeError exception.
  3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of M's [[MapData]] internal slot.
  5. Repeat for each Record {[[Key]], [[Value]]} p that is an element of entries,
    1. If p.[[Key]] is not empty and SameValueZero(p.[[Key]], key) is true, return true.
  6. Return false.

23.1.3.8Map.prototype.keys ( )#

The following steps are taken:

  1. Let M be the this value.
  2. Return ? CreateMapIterator(M, "key").

23.1.3.9Map.prototype.set ( key, value )#

The following steps are taken:

  1. Let M be the this value.
  2. If Type(M) is not Object, throw a TypeError exception.
  3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of M's [[MapData]] internal slot.
  5. Repeat for each Record {[[Key]], [[Value]]} p that is an element of entries,
    1. If p.[[Key]] is not empty and SameValueZero(p.[[Key]], key) is true, then
      1. Set p.[[Value]] to value.
      2. Return M.
  6. If key is -0, let key be +0.
  7. Let p be the Record {[[Key]]: key, [[Value]]: value}.
  8. Append p as the last element of entries.
  9. Return M.

23.1.3.10get Map.prototype.size#

Map.prototype.size is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let M be the this value.
  2. If Type(M) is not Object, throw a TypeError exception.
  3. If M does not have a [[MapData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of M's [[MapData]] internal slot.
  5. Let count be 0.
  6. For each Record {[[Key]], [[Value]]} p that is an element of entries
    1. If p.[[Key]] is not empty, set count to count+1.
  7. Return count.

23.1.3.11Map.prototype.values ( )#

The following steps are taken:

  1. Let M be the this value.
  2. Return ? CreateMapIterator(M, "value").

23.1.3.12Map.prototype [ @@iterator ] ( )#

The initial value of the @@iterator property is the same function object as the initial value of the entries property.

23.1.3.13Map.prototype [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "Map".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

23.1.4Properties of Map Instances#

Map instances are ordinary objects that inherit properties from the Map prototype. Map instances also have a [[MapData]] internal slot.

23.1.5Map Iterator Objects#

A Map Iterator is an object, that represents a specific iteration over some specific Map instance object. There is not a named constructor for Map Iterator objects. Instead, map iterator objects are created by calling certain methods of Map instance objects.

23.1.5.1CreateMapIterator Abstract Operation#

Several methods of Map objects return Iterator objects. The abstract operation CreateMapIterator with arguments map and kind is used to create such iterator objects. It performs the following steps:

  1. If Type(map) is not Object, throw a TypeError exception.
  2. If map does not have a [[MapData]] internal slot, throw a TypeError exception.
  3. Let iterator be ObjectCreate(%MapIteratorPrototype%, « [[Map]], [[MapNextIndex]], [[MapIterationKind]] »).
  4. Set iterator's [[Map]] internal slot to map.
  5. Set iterator's [[MapNextIndex]] internal slot to 0.
  6. Set iterator's [[MapIterationKind]] internal slot to kind.
  7. Return iterator.

23.1.5.2The %MapIteratorPrototype% Object#

All Map Iterator Objects inherit properties from the %MapIteratorPrototype% intrinsic object. The %MapIteratorPrototype% intrinsic object is an ordinary object and its [[Prototype]] internal slot is the %IteratorPrototype% intrinsic object. In addition, %MapIteratorPrototype% has the following properties:

23.1.5.2.1%MapIteratorPrototype%.next ( )#

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have all of the internal slots of a Map Iterator Instance (23.1.5.3), throw a TypeError exception.
  4. Let m be the value of the [[Map]] internal slot of O.
  5. Let index be the value of the [[MapNextIndex]] internal slot of O.
  6. Let itemKind be the value of the [[MapIterationKind]] internal slot of O.
  7. If m is undefined, return CreateIterResultObject(undefined, true).
  8. Assert: m has a [[MapData]] internal slot.
  9. Let entries be the List that is the value of the [[MapData]] internal slot of m.
  10. Repeat while index is less than the total number of elements of entries. The number of elements must be redetermined each time this method is evaluated.
    1. Let e be the Record {[[Key]], [[Value]]} that is the value of entries[index].
    2. Set index to index+1.
    3. Set the [[MapNextIndex]] internal slot of O to index.
    4. If e.[[Key]] is not empty, then
      1. If itemKind is "key", let result be e.[[Key]].
      2. Else if itemKind is "value", let result be e.[[Value]].
      3. Else,
        1. Assert: itemKind is "key+value".
        2. Let result be CreateArrayFromListe.[[Key]], e.[[Value]] »).
      4. Return CreateIterResultObject(result, false).
  11. Set the [[Map]] internal slot of O to undefined.
  12. Return CreateIterResultObject(undefined, true).

23.1.5.2.2%MapIteratorPrototype% [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "Map Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

23.1.5.3Properties of Map Iterator Instances#

Map Iterator instances are ordinary objects that inherit properties from the %MapIteratorPrototype% intrinsic object. Map Iterator instances are initially created with the internal slots described in Table 51.

Table 51: Internal Slots of Map Iterator Instances
Internal Slot Description
[[Map]] The Map object that is being iterated.
[[MapNextIndex]] The integer index of the next Map data element to be examined by this iterator.
[[MapIterationKind]] A String value that identifies what is to be returned for each element of the iteration. The possible values are: "key", "value", "key+value".

23.2Set Objects#

Set objects are collections of ECMAScript language values. A distinct value may only occur once as an element of a Set's collection. Distinct values are discriminated using the SameValueZero comparison algorithm.

Set objects must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structures used in this Set objects specification is only intended to describe the required observable semantics of Set objects. It is not intended to be a viable implementation model.

23.2.1The Set Constructor#

The Set constructor is the %Set% intrinsic object and the initial value of the Set property of the global object. When called as a constructor it creates and initializes a new Set object. Set is not intended to be called as a function and will throw an exception when called in that manner.

The Set constructor is designed to be subclassable. It may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified Set behaviour must include a super call to the Set constructor to create and initialize the subclass instance with the internal state necessary to support the Set.prototype built-in methods.

23.2.1.1Set ( [ iterable ] )#

When the Set function is called with optional argument iterable, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let set be ? OrdinaryCreateFromConstructor(NewTarget, "%SetPrototype%", « [[SetData]] »).
  3. Set set's [[SetData]] internal slot to a new empty List.
  4. If iterable is not present, let iterable be undefined.
  5. If iterable is either undefined or null, let iter be undefined.
  6. Else,
    1. Let adder be ? Get(set, "add").
    2. If IsCallable(adder) is false, throw a TypeError exception.
    3. Let iter be ? GetIterator(iterable).
  7. If iter is undefined, return set.
  8. Repeat
    1. Let next be ? IteratorStep(iter).
    2. If next is false, return set.
    3. Let nextValue be ? IteratorValue(next).
    4. Let status be Call(adder, set, « nextValue.[[Value]] »).
    5. If status is an abrupt completion, return ? IteratorClose(iter, status).

23.2.2Properties of the Set Constructor#

The value of the [[Prototype]] internal slot of the Set constructor is the intrinsic object %FunctionPrototype%.

The Set constructor has the following properties:

23.2.2.1Set.prototype#

The initial value of Set.prototype is the intrinsic %SetPrototype% object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.2.2.2get Set [ @@species ]#

Set[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Return the this value.

The value of the name property of this function is "get [Symbol.species]".

Note

Methods that create derived collection objects should call @@species to determine the constructor to use to create the derived objects. Subclass constructor may over-ride @@species to change the default constructor assignment.

23.2.3Properties of the Set Prototype Object#

The Set prototype object is the intrinsic object %SetPrototype%. The value of the [[Prototype]] internal slot of the Set prototype object is the intrinsic object %ObjectPrototype%. The Set prototype object is an ordinary object. It does not have a [[SetData]] internal slot.

23.2.3.1Set.prototype.add ( value )#

The following steps are taken:

  1. Let S be the this value.
  2. If Type(S) is not Object, throw a TypeError exception.
  3. If S does not have a [[SetData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of S's [[SetData]] internal slot.
  5. Repeat for each e that is an element of entries,
    1. If e is not empty and SameValueZero(e, value) is true, then
      1. Return S.
  6. If value is -0, let value be +0.
  7. Append value as the last element of entries.
  8. Return S.

23.2.3.2Set.prototype.clear ( )#

The following steps are taken:

  1. Let S be the this value.
  2. If Type(S) is not Object, throw a TypeError exception.
  3. If S does not have a [[SetData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of S's [[SetData]] internal slot.
  5. Repeat for each e that is an element of entries,
    1. Replace the element of entries whose value is e with an element whose value is empty.
  6. Return undefined.
Note

The existing [[SetData]] List is preserved because there may be existing Set Iterator objects that are suspended midway through iterating over that List.

23.2.3.3Set.prototype.constructor#

The initial value of Set.prototype.constructor is the intrinsic object %Set%.

23.2.3.4Set.prototype.delete ( value )#

The following steps are taken:

  1. Let S be the this value.
  2. If Type(S) is not Object, throw a TypeError exception.
  3. If S does not have a [[SetData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of S's [[SetData]] internal slot.
  5. Repeat for each e that is an element of entries,
    1. If e is not empty and SameValueZero(e, value) is true, then
      1. Replace the element of entries whose value is e with an element whose value is empty.
      2. Return true.
  6. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

23.2.3.5Set.prototype.entries ( )#

The following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateSetIterator(S, "key+value").
Note

For iteration purposes, a Set appears similar to a Map where each entry has the same value for its key and value.

23.2.3.6Set.prototype.forEach ( callbackfn [ , thisArg ] )#

When the forEach method is called with one or two arguments, the following steps are taken:

  1. Let S be the this value.
  2. If Type(S) is not Object, throw a TypeError exception.
  3. If S does not have a [[SetData]] internal slot, throw a TypeError exception.
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
  6. Let entries be the List that is the value of S's [[SetData]] internal slot.
  7. Repeat for each e that is an element of entries, in original insertion order
    1. If e is not empty, then
      1. Perform ? Call(callbackfn, T, « e, e, S »).
  8. Return undefined.
Note

callbackfn should be a function that accepts three arguments. forEach calls callbackfn once for each value present in the set object, in value insertion order. callbackfn is called only for values of the Set which actually exist; it is not called for keys that have been deleted from the set.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the first two arguments are a value contained in the Set. The same value is passed for both arguments. The Set object being traversed is passed as the third argument.

The callbackfn is called with three arguments to be consistent with the call back functions used by forEach methods for Map and Array. For Sets, each item value is considered to be both the key and the value.

forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

Each value is normally visited only once. However, a value will be revisited if it is deleted after it has been visited and then re-added before the forEach call completes. Values that are deleted after the call to forEach begins and before being visited are not visited unless the value is added again before the forEach call completes. New values added after the call to forEach begins are visited.

23.2.3.7Set.prototype.has ( value )#

The following steps are taken:

  1. Let S be the this value.
  2. If Type(S) is not Object, throw a TypeError exception.
  3. If S does not have a [[SetData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of S's [[SetData]] internal slot.
  5. Repeat for each e that is an element of entries,
    1. If e is not empty and SameValueZero(e, value) is true, return true.
  6. Return false.

23.2.3.8Set.prototype.keys ( )#

The initial value of the keys property is the same function object as the initial value of the values property.

Note

For iteration purposes, a Set appears similar to a Map where each entry has the same value for its key and value.

23.2.3.9get Set.prototype.size#

Set.prototype.size is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let S be the this value.
  2. If Type(S) is not Object, throw a TypeError exception.
  3. If S does not have a [[SetData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of S's [[SetData]] internal slot.
  5. Let count be 0.
  6. For each e that is an element of entries
    1. If e is not empty, set count to count+1.
  7. Return count.

23.2.3.10Set.prototype.values ( )#

The following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateSetIterator(S, "value").

23.2.3.11Set.prototype [ @@iterator ] ( )#

The initial value of the @@iterator property is the same function object as the initial value of the values property.

23.2.3.12Set.prototype [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "Set".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

23.2.4Properties of Set Instances#

Set instances are ordinary objects that inherit properties from the Set prototype. Set instances also have a [[SetData]] internal slot.

23.2.5Set Iterator Objects#

A Set Iterator is an ordinary object, with the structure defined below, that represents a specific iteration over some specific Set instance object. There is not a named constructor for Set Iterator objects. Instead, set iterator objects are created by calling certain methods of Set instance objects.

23.2.5.1CreateSetIterator Abstract Operation#

Several methods of Set objects return Iterator objects. The abstract operation CreateSetIterator with arguments set and kind is used to create such iterator objects. It performs the following steps:

  1. If Type(set) is not Object, throw a TypeError exception.
  2. If set does not have a [[SetData]] internal slot, throw a TypeError exception.
  3. Let iterator be ObjectCreate(%SetIteratorPrototype%, « [[IteratedSet]], [[SetNextIndex]], [[SetIterationKind]] »).
  4. Set iterator's [[IteratedSet]] internal slot to set.
  5. Set iterator's [[SetNextIndex]] internal slot to 0.
  6. Set iterator's [[SetIterationKind]] internal slot to kind.
  7. Return iterator.

23.2.5.2The %SetIteratorPrototype% Object#

All Set Iterator Objects inherit properties from the %SetIteratorPrototype% intrinsic object. The %SetIteratorPrototype% intrinsic object is an ordinary object and its [[Prototype]] internal slot is the %IteratorPrototype% intrinsic object. In addition, %SetIteratorPrototype% has the following properties:

23.2.5.2.1%SetIteratorPrototype%.next ( )#

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have all of the internal slots of a Set Iterator Instance (23.2.5.3), throw a TypeError exception.
  4. Let s be the value of the [[IteratedSet]] internal slot of O.
  5. Let index be the value of the [[SetNextIndex]] internal slot of O.
  6. Let itemKind be the value of the [[SetIterationKind]] internal slot of O.
  7. If s is undefined, return CreateIterResultObject(undefined, true).
  8. Assert: s has a [[SetData]] internal slot.
  9. Let entries be the List that is the value of the [[SetData]] internal slot of s.
  10. Repeat while index is less than the total number of elements of entries. The number of elements must be redetermined each time this method is evaluated.
    1. Let e be entries[index].
    2. Set index to index+1.
    3. Set the [[SetNextIndex]] internal slot of O to index.
    4. If e is not empty, then
      1. If itemKind is "key+value", then
        1. Return CreateIterResultObject(CreateArrayFromListe, e »), false).
      2. Return CreateIterResultObject(e, false).
  11. Set the [[IteratedSet]] internal slot of O to undefined.
  12. Return CreateIterResultObject(undefined, true).

23.2.5.2.2%SetIteratorPrototype% [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "Set Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

23.2.5.3Properties of Set Iterator Instances#

Set Iterator instances are ordinary objects that inherit properties from the %SetIteratorPrototype% intrinsic object. Set Iterator instances are initially created with the internal slots specified in Table 52.

Table 52: Internal Slots of Set Iterator Instances
Internal Slot Description
[[IteratedSet]] The Set object that is being iterated.
[[SetNextIndex]] The integer index of the next Set data element to be examined by this iterator
[[SetIterationKind]] A String value that identifies what is to be returned for each element of the iteration. The possible values are: "key", "value", "key+value". "key" and "value" have the same meaning.

23.3WeakMap Objects#

WeakMap objects are collections of key/value pairs where the keys are objects and values may be arbitrary ECMAScript language values. A WeakMap may be queried to see if it contains a key/value pair with a specific key, but no mechanism is provided for enumerating the objects it holds as keys. If an object that is being used as the key of a WeakMap key/value pair is only reachable by following a chain of references that start within that WeakMap, then that key/value pair is inaccessible and is automatically removed from the WeakMap. WeakMap implementations must detect and remove such key/value pairs and any associated resources.

An implementation may impose an arbitrarily determined latency between the time a key/value pair of a WeakMap becomes inaccessible and the time when the key/value pair is removed from the WeakMap. If this latency was observable to ECMAScript program, it would be a source of indeterminacy that could impact program execution. For that reason, an ECMAScript implementation must not provide any means to observe a key of a WeakMap that does not require the observer to present the observed key.

WeakMap objects must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of key/value pairs in the collection. The data structure used in this WeakMap objects specification are only intended to describe the required observable semantics of WeakMap objects. It is not intended to be a viable implementation model.

Note

WeakMap and WeakSets are intended to provide mechanisms for dynamically associating state with an object in a manner that does not “leak” memory resources if, in the absence of the WeakMap or WeakSet, the object otherwise became inaccessible and subject to resource reclamation by the implementation's garbage collection mechanisms. This characteristic can be achieved by using an inverted per-object mapping of weak map instances to keys. Alternatively each weak map may internally store its key to value mappings but this approach requires coordination between the WeakMap or WeakSet implementation and the garbage collector. The following references describe mechanism that may be useful to implementations of WeakMap and WeakSets:

Barry Hayes. 1997. Ephemerons: a new finalization mechanism. In Proceedings of the 12th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications (OOPSLA '97), A. Michael Berman (Ed.). 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

23.3.1The WeakMap Constructor#

The WeakMap constructor is the %WeakMap% intrinsic object and the initial value of the WeakMap property of the global object. When called as a constructor it creates and initializes a new WeakMap object. WeakMap is not intended to be called as a function and will throw an exception when called in that manner.

The WeakMap constructor is designed to be subclassable. It may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified WeakMap behaviour must include a super call to the WeakMap constructor to create and initialize the subclass instance with the internal state necessary to support the WeakMap.prototype built-in methods.

23.3.1.1WeakMap ( [ iterable ] )#

When the WeakMap function is called with optional argument iterable, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let map be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakMapPrototype%", « [[WeakMapData]] »).
  3. Set map's [[WeakMapData]] internal slot to a new empty List.
  4. If iterable is not present, let iterable be undefined.
  5. If iterable is either undefined or null, let iter be undefined.
  6. Else,
    1. Let adder be ? Get(map, "set").
    2. If IsCallable(adder) is false, throw a TypeError exception.
    3. Let iter be ? GetIterator(iterable).
  7. If iter is undefined, return map.
  8. Repeat
    1. Let next be ? IteratorStep(iter).
    2. If next is false, return map.
    3. Let nextItem be ? IteratorValue(next).
    4. If Type(nextItem) is not Object, then
      1. Let error be Completion{[[Type]]: throw, [[Value]]: a newly created TypeError object, [[Target]]: empty}.
      2. Return ? IteratorClose(iter, error).
    5. Let k be Get(nextItem, "0").
    6. If k is an abrupt completion, return ? IteratorClose(iter, k).
    7. Let v be Get(nextItem, "1").
    8. If v is an abrupt completion, return ? IteratorClose(iter, v).
    9. Let status be Call(adder, map, « k.[[Value]], v.[[Value]] »).
    10. If status is an abrupt completion, return ? IteratorClose(iter, status).
Note

If the parameter iterable is present, it is expected to be an object that implements an @@iterator method that returns an iterator object that produces a two element array-like object whose first element is a value that will be used as a WeakMap key and whose second element is the value to associate with that key.

23.3.2Properties of the WeakMap Constructor#

The value of the [[Prototype]] internal slot of the WeakMap constructor is the intrinsic object %FunctionPrototype%.

The WeakMap constructor has the following properties:

23.3.2.1WeakMap.prototype#

The initial value of WeakMap.prototype is the intrinsic object %WeakMapPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.3.3Properties of the WeakMap Prototype Object#

The WeakMap prototype object is the intrinsic object %WeakMapPrototype%. The value of the [[Prototype]] internal slot of the WeakMap prototype object is the intrinsic object %ObjectPrototype%. The WeakMap prototype object is an ordinary object. It does not have a [[WeakMapData]] internal slot.

23.3.3.1WeakMap.prototype.constructor#

The initial value of WeakMap.prototype.constructor is the intrinsic object %WeakMap%.

23.3.3.2WeakMap.prototype.delete ( key )#

The following steps are taken:

  1. Let M be the this value.
  2. If Type(M) is not Object, throw a TypeError exception.
  3. If M does not have a [[WeakMapData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of M's [[WeakMapData]] internal slot.
  5. If Type(key) is not Object, return false.
  6. Repeat for each Record {[[Key]], [[Value]]} p that is an element of entries,
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, then
      1. Set p.[[Key]] to empty.
      2. Set p.[[Value]] to empty.
      3. Return true.
  7. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

23.3.3.3WeakMap.prototype.get ( key )#

The following steps are taken:

  1. Let M be the this value.
  2. If Type(M) is not Object, throw a TypeError exception.
  3. If M does not have a [[WeakMapData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of M's [[WeakMapData]] internal slot.
  5. If Type(key) is not Object, return undefined.
  6. Repeat for each Record {[[Key]], [[Value]]} p that is an element of entries,
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
  7. Return undefined.

23.3.3.4WeakMap.prototype.has ( key )#

The following steps are taken:

  1. Let M be the this value.
  2. If Type(M) is not Object, throw a TypeError exception.
  3. If M does not have a [[WeakMapData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of M's [[WeakMapData]] internal slot.
  5. If Type(key) is not Object, return false.
  6. Repeat for each Record {[[Key]], [[Value]]} p that is an element of entries,
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return true.
  7. Return false.

23.3.3.5WeakMap.prototype.set ( key, value )#

The following steps are taken:

  1. Let M be the this value.
  2. If Type(M) is not Object, throw a TypeError exception.
  3. If M does not have a [[WeakMapData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of M's [[WeakMapData]] internal slot.
  5. If Type(key) is not Object, throw a TypeError exception.
  6. Repeat for each Record {[[Key]], [[Value]]} p that is an element of entries,
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, then
      1. Set p.[[Value]] to value.
      2. Return M.
  7. Let p be the Record {[[Key]]: key, [[Value]]: value}.
  8. Append p as the last element of entries.
  9. Return M.

23.3.3.6WeakMap.prototype [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "WeakMap".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

23.3.4Properties of WeakMap Instances#

WeakMap instances are ordinary objects that inherit properties from the WeakMap prototype. WeakMap instances also have a [[WeakMapData]] internal slot.

23.4WeakSet Objects#

WeakSet objects are collections of objects. A distinct object may only occur once as an element of a WeakSet's collection. A WeakSet may be queried to see if it contains a specific object, but no mechanism is provided for enumerating the objects it holds. If an object that is contained by a WeakSet is only reachable by following a chain of references that start within that WeakSet, then that object is inaccessible and is automatically removed from the WeakSet. WeakSet implementations must detect and remove such objects and any associated resources.

An implementation may impose an arbitrarily determined latency between the time an object contained in a WeakSet becomes inaccessible and the time when the object is removed from the WeakSet. If this latency was observable to ECMAScript program, it would be a source of indeterminacy that could impact program execution. For that reason, an ECMAScript implementation must not provide any means to determine if a WeakSet contains a particular object that does not require the observer to present the observed object.

WeakSet objects must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structure used in this WeakSet objects specification is only intended to describe the required observable semantics of WeakSet objects. It is not intended to be a viable implementation model.

Note

See the NOTE in 23.3.

23.4.1The WeakSet Constructor#

The WeakSet constructor is the %WeakSet% intrinsic object and the initial value of the WeakSet property of the global object. When called as a constructor it creates and initializes a new WeakSet object. WeakSet is not intended to be called as a function and will throw an exception when called in that manner.

The WeakSet constructor is designed to be subclassable. It may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified WeakSet behaviour must include a super call to the WeakSet constructor to create and initialize the subclass instance with the internal state necessary to support the WeakSet.prototype built-in methods.

23.4.1.1WeakSet ( [ iterable ] )#

When the WeakSet function is called with optional argument iterable, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let set be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakSetPrototype%", « [[WeakSetData]] »).
  3. Set set's [[WeakSetData]] internal slot to a new empty List.
  4. If iterable is not present, let iterable be undefined.
  5. If iterable is either undefined or null, let iter be undefined.
  6. Else,
    1. Let adder be ? Get(set, "add").
    2. If IsCallable(adder) is false, throw a TypeError exception.
    3. Let iter be ? GetIterator(iterable).
  7. If iter is undefined, return set.
  8. Repeat
    1. Let next be ? IteratorStep(iter).
    2. If next is false, return set.
    3. Let nextValue be ? IteratorValue(next).
    4. Let status be Call(adder, set, « nextValue »).
    5. If status is an abrupt completion, return ? IteratorClose(iter, status).

23.4.2Properties of the WeakSet Constructor#

The value of the [[Prototype]] internal slot of the WeakSet constructor is the intrinsic object %FunctionPrototype%.

The WeakSet constructor has the following properties:

23.4.2.1WeakSet.prototype#

The initial value of WeakSet.prototype is the intrinsic %WeakSetPrototype% object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.4.3Properties of the WeakSet Prototype Object#

The WeakSet prototype object is the intrinsic object %WeakSetPrototype%. The value of the [[Prototype]] internal slot of the WeakSet prototype object is the intrinsic object %ObjectPrototype%. The WeakSet prototype object is an ordinary object. It does not have a [[WeakSetData]] internal slot.

23.4.3.1WeakSet.prototype.add ( value )#

The following steps are taken:

  1. Let S be the this value.
  2. If Type(S) is not Object, throw a TypeError exception.
  3. If S does not have a [[WeakSetData]] internal slot, throw a TypeError exception.
  4. If Type(value) is not Object, throw a TypeError exception.
  5. Let entries be the List that is the value of S's [[WeakSetData]] internal slot.
  6. Repeat for each e that is an element of entries,
    1. If e is not empty and SameValue(e, value) is true, then
      1. Return S.
  7. Append value as the last element of entries.
  8. Return S.

23.4.3.2WeakSet.prototype.constructor#

The initial value of WeakSet.prototype.constructor is the %WeakSet% intrinsic object.

23.4.3.3WeakSet.prototype.delete ( value )#

The following steps are taken:

  1. Let S be the this value.
  2. If Type(S) is not Object, throw a TypeError exception.
  3. If S does not have a [[WeakSetData]] internal slot, throw a TypeError exception.
  4. If Type(value) is not Object, return false.
  5. Let entries be the List that is the value of S's [[WeakSetData]] internal slot.
  6. Repeat for each e that is an element of entries,
    1. If e is not empty and SameValue(e, value) is true, then
      1. Replace the element of entries whose value is e with an element whose value is empty.
      2. Return true.
  7. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

23.4.3.4WeakSet.prototype.has ( value )#

The following steps are taken:

  1. Let S be the this value.
  2. If Type(S) is not Object, throw a TypeError exception.
  3. If S does not have a [[WeakSetData]] internal slot, throw a TypeError exception.
  4. Let entries be the List that is the value of S's [[WeakSetData]] internal slot.
  5. If Type(value) is not Object, return false.
  6. Repeat for each e that is an element of entries,
    1. If e is not empty and SameValue(e, value) is true, return true.
  7. Return false.

23.4.3.5WeakSet.prototype [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "WeakSet".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

23.4.4Properties of WeakSet Instances#

WeakSet instances are ordinary objects that inherit properties from the WeakSet prototype. WeakSet instances also have a [[WeakSetData]] internal slot.

24Structured Data#

24.1ArrayBuffer Objects#

24.1.1Abstract Operations For ArrayBuffer Objects#

24.1.1.1AllocateArrayBuffer ( constructor, byteLength )#

The abstract operation AllocateArrayBuffer with arguments constructor and byteLength is used to create an ArrayBuffer object. It performs the following steps:

  1. Let obj be ? OrdinaryCreateFromConstructor(constructor, "%ArrayBufferPrototype%", « [[ArrayBufferData]], [[ArrayBufferByteLength]] »).
  2. Assert: byteLength is an integer value ≥ 0.
  3. Let block be ? CreateByteDataBlock(byteLength).
  4. Set obj's [[ArrayBufferData]] internal slot to block.
  5. Set obj's [[ArrayBufferByteLength]] internal slot to byteLength.
  6. Return obj.

24.1.1.2IsDetachedBuffer ( arrayBuffer )#

The abstract operation IsDetachedBuffer with argument arrayBuffer performs the following steps:

  1. Assert: Type(arrayBuffer) is Object and it has an [[ArrayBufferData]] internal slot.
  2. If arrayBuffer's [[ArrayBufferData]] internal slot is null, return true.
  3. Return false.

24.1.1.3DetachArrayBuffer ( arrayBuffer )#

The abstract operation DetachArrayBuffer with argument arrayBuffer performs the following steps:

  1. Assert: Type(arrayBuffer) is Object and it has [[ArrayBufferData]] and [[ArrayBufferByteLength]] internal slots.
  2. Set arrayBuffer's [[ArrayBufferData]] internal slot to null.
  3. Set arrayBuffer's [[ArrayBufferByteLength]] internal slot to 0.
  4. Return NormalCompletion(null).
Note

Detaching an ArrayBuffer instance disassociates the Data Block used as its backing store from the instance and sets the byte length of the buffer to 0. No operations defined by this specification use the DetachArrayBuffer abstract operation. However, an ECMAScript implementation or host environment may define such operations.

24.1.1.4CloneArrayBuffer ( srcBuffer, srcByteOffset [ , cloneConstructor ] )#

The abstract operation CloneArrayBuffer takes three parameters, an ArrayBuffer srcBuffer, an integer srcByteOffset and optionally a constructor function cloneConstructor. It creates a new ArrayBuffer whose data is a copy of srcBuffer's data starting at srcByteOffset. This operation performs the following steps:

  1. Assert: Type(srcBuffer) is Object and it has an [[ArrayBufferData]] internal slot.
  2. If cloneConstructor is not present, then
    1. Let cloneConstructor be ? SpeciesConstructor(srcBuffer, %ArrayBuffer%).
    2. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception.
  3. Else, Assert: IsConstructor(cloneConstructor) is true.
  4. Let srcLength be the value of srcBuffer's [[ArrayBufferByteLength]] internal slot.
  5. Assert: srcByteOffsetsrcLength.
  6. Let cloneLength be srcLength - srcByteOffset.
  7. Let srcBlock be the value of srcBuffer's [[ArrayBufferData]] internal slot.
  8. Let targetBuffer be ? AllocateArrayBuffer(cloneConstructor, cloneLength).
  9. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception.
  10. Let targetBlock be the value of targetBuffer's [[ArrayBufferData]] internal slot.
  11. Perform CopyDataBlockBytes(targetBlock, 0, srcBlock, srcByteOffset, cloneLength).
  12. Return targetBuffer.

24.1.1.5GetValueFromBuffer ( arrayBuffer, byteIndex, type [ , isLittleEndian ] )#

The abstract operation GetValueFromBuffer takes four parameters, an ArrayBuffer arrayBuffer, an integer byteIndex, a String type, and optionally a Boolean isLittleEndian. This operation performs the following steps:

  1. Assert: IsDetachedBuffer(arrayBuffer) is false.
  2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.
  3. Assert: byteIndex is an integer value ≥ 0.
  4. Let block be arrayBuffer's [[ArrayBufferData]] internal slot.
  5. Let elementSize be the Number value of the Element Size value specified in Table 50 for Element Type type.
  6. Let rawValue be a List of elementSize containing, in order, the elementSize sequence of bytes starting with block[byteIndex].
  7. If isLittleEndian is not present, set isLittleEndian to either true or false. The choice is implementation dependent and should be the alternative that is most efficient for the implementation. An implementation must use the same value each time this step is executed and the same value must be used for the corresponding step in the SetValueInBuffer abstract operation.
  8. If isLittleEndian is false, reverse the order of the elements of rawValue.
  9. If type is "Float32", then
    1. Let value be the byte elements of rawValue concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2008 binary32 value.
    2. If value is an IEEE 754-2008 binary32 NaN value, return the NaN Number value.
    3. Return the Number value that corresponds to value.
  10. If type is "Float64", then
    1. Let value be the byte elements of rawValue concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2008 binary64 value.
    2. If value is an IEEE 754-2008 binary64 NaN value, return the NaN Number value.
    3. Return the Number value that corresponds to value.
  11. If the first code unit of type is "U", then
    1. Let intValue be the byte elements of rawValue concatenated and interpreted as a bit string encoding of an unsigned little-endian binary number.
  12. Else,
    1. Let intValue be the byte elements of rawValue concatenated and interpreted as a bit string encoding of a binary little-endian 2's complement number of bit length elementSize × 8.
  13. Return the Number value that corresponds to intValue.

24.1.1.6SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ , isLittleEndian ] )#

The abstract operation SetValueInBuffer takes five parameters, an ArrayBuffer arrayBuffer, an integer byteIndex, a String type, a Number value, and optionally a Boolean isLittleEndian. This operation performs the following steps:

  1. Assert: IsDetachedBuffer(arrayBuffer) is false.
  2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.
  3. Assert: byteIndex is an integer value ≥ 0.
  4. Assert: Type(value) is Number.
  5. Let block be arrayBuffer's [[ArrayBufferData]] internal slot.
  6. Assert: block is not undefined.
  7. If isLittleEndian is not present, set isLittleEndian to either true or false. The choice is implementation dependent and should be the alternative that is most efficient for the implementation. An implementation must use the same value each time this step is executed and the same value must be used for the corresponding step in the GetValueFromBuffer abstract operation.
  8. If type is "Float32", then
    1. Set rawBytes to a List containing the 4 bytes that are the result of converting value to IEEE 754-2008 binary32 format using “Round to nearest, ties to even” rounding mode. If isLittleEndian is false, the bytes are arranged in big endian order. Otherwise, the bytes are arranged in little endian order. If value is NaN, rawValue may be set to any implementation chosen IEEE 754-2008 binary64 format Not-a-Number encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value.
  9. Else, if type is "Float64", then
    1. Set rawBytes to a List containing the 8 bytes that are the IEEE 754-2008 binary64 format encoding of value. If isLittleEndian is false, the bytes are arranged in big endian order. Otherwise, the bytes are arranged in little endian order. If value is NaN, rawValue may be set to any implementation chosen IEEE 754-2008 binary32 format Not-a-Number encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value.
  10. Else,
    1. Let n be the Number value of the Element Size specified in Table 50 for Element Type type.
    2. Let convOp be the abstract operation named in the Conversion Operation column in Table 50 for Element Type type.
    3. Let intValue be convOp(value).
    4. If intValue ≥ 0, then
      1. Let rawBytes be a List containing the n-byte binary encoding of intValue. If isLittleEndian is false, the bytes are ordered in big endian order. Otherwise, the bytes are ordered in little endian order.
    5. Else,
      1. Let rawBytes be a List containing the n-byte binary 2's complement encoding of intValue. If isLittleEndian is false, the bytes are ordered in big endian order. Otherwise, the bytes are ordered in little endian order.
  11. Store the individual bytes of rawBytes into block, in order, starting at block[byteIndex].
  12. Return NormalCompletion(undefined).

24.1.2The ArrayBuffer Constructor#

The ArrayBuffer constructor is the %ArrayBuffer% intrinsic object and the initial value of the ArrayBuffer property of the global object. When called as a constructor it creates and initializes a new ArrayBuffer object. ArrayBuffer is not intended to be called as a function and will throw an exception when called in that manner.

The ArrayBuffer constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified ArrayBuffer behaviour must include a super call to the ArrayBuffer constructor to create and initialize subclass instances with the internal state necessary to support the ArrayBuffer.prototype built-in methods.

24.1.2.1ArrayBuffer ( length )#

ArrayBuffer called with argument length performs the following steps:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let numberLength be ? ToNumber(length).
  3. Let byteLength be ToLength(numberLength).
  4. If SameValueZero(numberLength, byteLength) is false, throw a RangeError exception.
  5. Return ? AllocateArrayBuffer(NewTarget, byteLength).

24.1.3Properties of the ArrayBuffer Constructor#

The value of the [[Prototype]] internal slot of the ArrayBuffer constructor is the intrinsic object %FunctionPrototype%.

The ArrayBuffer constructor has the following properties:

24.1.3.1ArrayBuffer.isView ( arg )#

The isView function takes one argument arg, and performs, the following steps are taken:

  1. If Type(arg) is not Object, return false.
  2. If arg has a [[ViewedArrayBuffer]] internal slot, return true.
  3. Return false.

24.1.3.2ArrayBuffer.prototype#

The initial value of ArrayBuffer.prototype is the intrinsic object %ArrayBufferPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.1.3.3get ArrayBuffer [ @@species ]#

ArrayBuffer[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Return the this value.

The value of the name property of this function is "get [Symbol.species]".

Note

ArrayBuffer prototype methods normally use their this object's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its @@species property.

24.1.4Properties of the ArrayBuffer Prototype Object#

The ArrayBuffer prototype object is the intrinsic object %ArrayBufferPrototype%. The value of the [[Prototype]] internal slot of the ArrayBuffer prototype object is the intrinsic object %ObjectPrototype%. The ArrayBuffer prototype object is an ordinary object. It does not have an [[ArrayBufferData]] or [[ArrayBufferByteLength]] internal slot.

24.1.4.1get ArrayBuffer.prototype.byteLength#

ArrayBuffer.prototype.byteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception.
  4. If IsDetachedBuffer(O) is true, throw a TypeError exception.
  5. Let length be the value of O's [[ArrayBufferByteLength]] internal slot.
  6. Return length.

24.1.4.2ArrayBuffer.prototype.constructor#

The initial value of ArrayBuffer.prototype.constructor is the intrinsic object %ArrayBuffer%.

24.1.4.3ArrayBuffer.prototype.slice ( start, end )#

The following steps are taken:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception.
  4. If IsDetachedBuffer(O) is true, throw a TypeError exception.
  5. Let len be the value of O's [[ArrayBufferByteLength]] internal slot.
  6. Let relativeStart be ? ToInteger(start).
  7. If relativeStart < 0, let first be max((len + relativeStart), 0); else let first be min(relativeStart, len).
  8. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToInteger(end).
  9. If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let final be min(relativeEnd, len).
  10. Let newLen be max(final-first, 0).
  11. Let ctor be ? SpeciesConstructor(O, %ArrayBuffer%).
  12. Let new be ? Construct(ctor, « newLen »).
  13. If new does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception.
  14. If IsDetachedBuffer(new) is true, throw a TypeError exception.
  15. If SameValue(new, O) is true, throw a TypeError exception.
  16. If the value of new's [[ArrayBufferByteLength]] internal slot < newLen, throw a TypeError exception.
  17. NOTE: Side-effects of the above steps may have detached O.
  18. If IsDetachedBuffer(O) is true, throw a TypeError exception.
  19. Let fromBuf be the value of O's [[ArrayBufferData]] internal slot.
  20. Let toBuf be the value of new's [[ArrayBufferData]] internal slot.
  21. Perform CopyDataBlockBytes(toBuf, 0, fromBuf, first, newLen).
  22. Return new.

24.1.4.4ArrayBuffer.prototype [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "ArrayBuffer".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.1.5Properties of the ArrayBuffer Instances#

ArrayBuffer instances inherit properties from the ArrayBuffer prototype object. ArrayBuffer instances each have an [[ArrayBufferData]] internal slot and an [[ArrayBufferByteLength]] internal slot.

ArrayBuffer instances whose [[ArrayBufferData]] is null are considered to be detached and all operators to access or modify data contained in the ArrayBuffer instance will fail.

24.2DataView Objects#

24.2.1Abstract Operations For DataView Objects#

24.2.1.1GetViewValue ( view, requestIndex, isLittleEndian, type )#

The abstract operation GetViewValue with arguments view, requestIndex, isLittleEndian, and type is used by functions on DataView instances is to retrieve values from the view's buffer. It performs the following steps:

  1. If Type(view) is not Object, throw a TypeError exception.
  2. If view does not have a [[DataView]] internal slot, throw a TypeError exception.
  3. Let numberIndex be ? ToNumber(requestIndex).
  4. Let getIndex be ToInteger(numberIndex).
  5. If numberIndexgetIndex or getIndex < 0, throw a RangeError exception.
  6. Let isLittleEndian be ToBoolean(isLittleEndian).
  7. Let buffer be the value of view's [[ViewedArrayBuffer]] internal slot.
  8. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  9. Let viewOffset be the value of view's [[ByteOffset]] internal slot.
  10. Let viewSize be the value of view's [[ByteLength]] internal slot.
  11. Let elementSize be the Number value of the Element Size value specified in Table 50 for Element Type type.
  12. If getIndex + elementSize > viewSize, throw a RangeError exception.
  13. Let bufferIndex be getIndex + viewOffset.
  14. Return GetValueFromBuffer(buffer, bufferIndex, type, isLittleEndian).

24.2.1.2SetViewValue ( view, requestIndex, isLittleEndian, type, value )#

The abstract operation SetViewValue with arguments view, requestIndex, isLittleEndian, type, and value is used by functions on DataView instances to store values into the view's buffer. It performs the following steps:

  1. If Type(view) is not Object, throw a TypeError exception.
  2. If view does not have a [[DataView]] internal slot, throw a TypeError exception.
  3. Let numberIndex be ? ToNumber(requestIndex).
  4. Let getIndex be ToInteger(numberIndex).
  5. If numberIndexgetIndex or getIndex < 0, throw a RangeError exception.
  6. Let numberValue be ? ToNumber(value).
  7. Let isLittleEndian be ToBoolean(isLittleEndian).
  8. Let buffer be the value of view's [[ViewedArrayBuffer]] internal slot.
  9. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  10. Let viewOffset be the value of view's [[ByteOffset]] internal slot.
  11. Let viewSize be the value of view's [[ByteLength]] internal slot.
  12. Let elementSize be the Number value of the Element Size value specified in Table 50 for Element Type type.
  13. If getIndex + elementSize > viewSize, throw a RangeError exception.
  14. Let bufferIndex be getIndex + viewOffset.
  15. Return SetValueInBuffer(buffer, bufferIndex, type, numberValue, isLittleEndian).

24.2.2The DataView Constructor#

The DataView constructor is the %DataView% intrinsic object and the initial value of the DataView property of the global object. When called as a constructor it creates and initializes a new DataView object. DataView is not intended to be called as a function and will throw an exception when called in that manner.

The DataView constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified DataView behaviour must include a super call to the DataView constructor to create and initialize subclass instances with the internal state necessary to support the DataView.prototype built-in methods.

24.2.2.1DataView (buffer, byteOffset, byteLength )#

DataView called with arguments buffer, byteOffset, and byteLength performs the following steps:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If Type(buffer) is not Object, throw a TypeError exception.
  3. If buffer does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception.
  4. Let numberOffset be ? ToNumber(byteOffset).
  5. Let offset be ToInteger(numberOffset).
  6. If numberOffsetoffset or offset < 0, throw a RangeError exception.
  7. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  8. Let bufferByteLength be the value of buffer's [[ArrayBufferByteLength]] internal slot.
  9. If offset > bufferByteLength, throw a RangeError exception.
  10. If byteLength is undefined, then
    1. Let viewByteLength be bufferByteLength - offset.
  11. Else,
    1. Let viewByteLength be ? ToLength(byteLength).
    2. If offset+viewByteLength > bufferByteLength, throw a RangeError exception.
  12. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%DataViewPrototype%", « [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] »).
  13. Set O's [[DataView]] internal slot to true.
  14. Set O's [[ViewedArrayBuffer]] internal slot to buffer.
  15. Set O's [[ByteLength]] internal slot to viewByteLength.
  16. Set O's [[ByteOffset]] internal slot to offset.
  17. Return O.

24.2.3Properties of the DataView Constructor#

The value of the [[Prototype]] internal slot of the DataView constructor is the intrinsic object %FunctionPrototype%.

The DataView constructor has the following properties:

24.2.3.1DataView.prototype#

The initial value of DataView.prototype is the intrinsic object %DataViewPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.2.4Properties of the DataView Prototype Object#

The DataView prototype object is the intrinsic object %DataViewPrototype%. The value of the [[Prototype]] internal slot of the DataView prototype object is the intrinsic object %ObjectPrototype%. The DataView prototype object is an ordinary object. It does not have a [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], or [[ByteOffset]] internal slot.

24.2.4.1get DataView.prototype.buffer#

DataView.prototype.buffer is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception.
  4. Let buffer be the value of O's [[ViewedArrayBuffer]] internal slot.
  5. Return buffer.

24.2.4.2get DataView.prototype.byteLength#

DataView.prototype.byteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception.
  4. Let buffer be the value of O's [[ViewedArrayBuffer]] internal slot.
  5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  6. Let size be the value of O's [[ByteLength]] internal slot.
  7. Return size.

24.2.4.3get DataView.prototype.byteOffset#

DataView.prototype.byteOffset is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception.
  4. Let buffer be the value of O's [[ViewedArrayBuffer]] internal slot.
  5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  6. Let offset be the value of O's [[ByteOffset]] internal slot.
  7. Return offset.

24.2.4.4DataView.prototype.constructor#

The initial value of DataView.prototype.constructor is the intrinsic object %DataView%.

24.2.4.5DataView.prototype.getFloat32 ( byteOffset [ , littleEndian ] )#

When the getFloat32 method is called with argument byteOffset and optional argument littleEndian, the following steps are taken:

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, "Float32").

24.2.4.6DataView.prototype.getFloat64 ( byteOffset [ , littleEndian ] )#

When the getFloat64 method is called with argument byteOffset and optional argument littleEndian, the following steps are taken:

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, "Float64").

24.2.4.7DataView.prototype.getInt8 ( byteOffset )#

When the getInt8 method is called with argument byteOffset, the following steps are taken:

  1. Let v be the this value.
  2. Return ? GetViewValue(v, byteOffset, true, "Int8").

24.2.4.8DataView.prototype.getInt16 ( byteOffset [ , littleEndian ] )#

When the getInt16 method is called with argument byteOffset and optional argument littleEndian, the following steps are taken:

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, "Int16").

24.2.4.9DataView.prototype.getInt32 ( byteOffset [ , littleEndian ] )#

When the getInt32 method is called with argument byteOffset and optional argument littleEndian, the following steps are taken:

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be undefined.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, "Int32").

24.2.4.10DataView.prototype.getUint8 ( byteOffset )#

When the getUint8 method is called with argument byteOffset, the following steps are taken:

  1. Let v be the this value.
  2. Return ? GetViewValue(v, byteOffset, true, "Uint8").

24.2.4.11DataView.prototype.getUint16 ( byteOffset [ , littleEndian ] )#

When the getUint16 method is called with argument byteOffset and optional argument littleEndian, the following steps are taken:

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, "Uint16").

24.2.4.12DataView.prototype.getUint32 ( byteOffset [ , littleEndian ] )#

When the getUint32 method is called with argument byteOffset and optional argument littleEndian, the following steps are taken:

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, "Uint32").

24.2.4.13DataView.prototype.setFloat32 ( byteOffset, value [ , littleEndian ] )#

When the setFloat32 method is called with arguments byteOffset and value and optional argument littleEndian, the following steps are taken:

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, "Float32", value).

24.2.4.14DataView.prototype.setFloat64 ( byteOffset, value [ , littleEndian ] )#

When the setFloat64 method is called with arguments byteOffset and value and optional argument littleEndian, the following steps are taken:

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, "Float64", value).

24.2.4.15DataView.prototype.setInt8 ( byteOffset, value )#

When the setInt8 method is called with arguments byteOffset and value, the following steps are taken:

  1. Let v be the this value.
  2. Return ? SetViewValue(v, byteOffset, true, "Int8", value).

24.2.4.16DataView.prototype.setInt16 ( byteOffset, value [ , littleEndian ] )#

When the setInt16 method is called with arguments byteOffset and value and optional argument littleEndian, the following steps are taken:

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, "Int16", value).

24.2.4.17DataView.prototype.setInt32 ( byteOffset, value [ , littleEndian ] )#

When the setInt32 method is called with arguments byteOffset and value and optional argument littleEndian, the following steps are taken:

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, "Int32", value).

24.2.4.18DataView.prototype.setUint8 ( byteOffset, value )#

When the setUint8 method is called with arguments byteOffset and value, the following steps are taken:

  1. Let v be the this value.
  2. Return ? SetViewValue(v, byteOffset, true, "Uint8", value).

24.2.4.19DataView.prototype.setUint16 ( byteOffset, value [ , littleEndian ] )#

When the setUint16 method is called with arguments byteOffset and value and optional argument littleEndian, the following steps are taken:

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, "Uint16", value).

24.2.4.20DataView.prototype.setUint32 ( byteOffset, value [ , littleEndian ] )#

When the setUint32 method is called with arguments byteOffset and value and optional argument littleEndian, the following steps are taken:

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, "Uint32", value).

24.2.4.21DataView.prototype [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "DataView".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.2.5Properties of DataView Instances#

DataView instances are ordinary objects that inherit properties from the DataView prototype object. DataView instances each have [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], and [[ByteOffset]] internal slots.

Note

The value of the [[DataView]] internal slot is not used within this specification. The simple presence of that internal slot is used within the specification to identify objects created using the DataView constructor.

24.3The JSON Object#

The JSON object is the %JSON% intrinsic object and the initial value of the JSON property of the global object. The JSON object is a single ordinary object that contains two functions, parse and stringify, that are used to parse and construct JSON texts. The JSON Data Interchange Format is defined in ECMA-404. The JSON interchange format used in this specification is exactly that described by ECMA-404.

Conforming implementations of JSON.parse and JSON.stringify must support the exact interchange format described in the ECMA-404 specification without any deletions or extensions to the format.

The value of the [[Prototype]] internal slot of the JSON object is the intrinsic object %ObjectPrototype%. The value of the [[Extensible]] internal slot of the JSON object is set to true.

The JSON object does not have a [[Construct]] internal method; it is not possible to use the JSON object as a constructor with the new operator.

The JSON object does not have a [[Call]] internal method; it is not possible to invoke the JSON object as a function.

24.3.1JSON.parse ( text [ , reviver ] )#

The parse function parses a JSON text (a JSON-formatted String) and produces an ECMAScript value. The JSON format is a subset of the syntax for ECMAScript literals, Array Initializers and Object Initializers. After parsing, JSON objects are realized as ECMAScript objects. JSON arrays are realized as ECMAScript Array instances. JSON strings, numbers, booleans, and null are realized as ECMAScript Strings, Numbers, Booleans, and null.

The optional reviver parameter is a function that takes two parameters, key and value. It can filter and transform the results. It is called with each of the key/value pairs produced by the parse, and its return value is used instead of the original value. If it returns what it received, the structure is not modified. If it returns undefined then the property is deleted from the result.

  1. Let JText be ? ToString(text).
  2. Parse JText interpreted as UTF-16 encoded Unicode points (6.1.4) as a JSON text as specified in ECMA-404. Throw a SyntaxError exception if JText is not a valid JSON text as defined in that specification.
  3. Let scriptText be the result of concatenating "(", JText, and ");".
  4. Let completion be the result of parsing and evaluating scriptText as if it was the source text of an ECMAScript Script, but using the alternative definition of DoubleStringCharacter provided below. The extended PropertyDefinitionEvaluation semantics defined in B.3.1 must not be used during the evaluation.
  5. Let unfiltered be completion.[[Value]].
  6. Assert: unfiltered will be either a primitive value or an object that is defined by either an ArrayLiteral or an ObjectLiteral.
  7. If IsCallable(reviver) is true, then
    1. Let root be ObjectCreate(%ObjectPrototype%).
    2. Let rootName be the empty String.
    3. Let status be CreateDataProperty(root, rootName, unfiltered).
    4. Assert: status is true.
    5. Return ? InternalizeJSONProperty(root, rootName).
  8. Else,
    1. Return unfiltered.

The length property of the parse function is 2.

JSON allows Unicode code units 0x2028 (LINE SEPARATOR) and 0x2029 (PARAGRAPH SEPARATOR) to directly appear in String literals without using an escape sequence. This is enabled by using the following alternative definition of DoubleStringCharacter when parsing scriptText in step 4:

DoubleStringCharacter::SourceCharacterbut not one of " or \ or U+0000 through U+001F \EscapeSequence Note

The syntax of a valid JSON text is a subset of the ECMAScript PrimaryExpression syntax. Hence a valid JSON text is also a valid PrimaryExpression. Step 2 above verifies that JText conforms to that subset. When scriptText is parsed and evaluated as a Script the result will be either a String, Number, Boolean, or Null primitive value or an Object defined as if by an ArrayLiteral or ObjectLiteral.

24.3.1.1Runtime Semantics: InternalizeJSONProperty( holder, name)#

The abstract operation InternalizeJSONProperty is a recursive abstract operation that takes two parameters: a holder object and the String name of a property in that object. InternalizeJSONProperty uses the value of reviver that was originally passed to the above parse function.

  1. Let val be ? Get(holder, name).
  2. If Type(val) is Object, then
    1. Let isArray be ? IsArray(val).
    2. If isArray is true, then
      1. Set I to 0.
      2. Let len be ? ToLength(? Get(val, "length")).
      3. Repeat while I < len,
        1. Let newElement be ? InternalizeJSONProperty(val, ! ToString(I)).
        2. If newElement is undefined, then
          1. Perform ? val.[[Delete]](! ToString(I)).
        3. Else,
          1. Perform ? CreateDataProperty(val, ! ToString(I), newElement).
          2. NOTE This algorithm intentionally does not throw an exception if CreateDataProperty returns false.
        4. Add 1 to I.
    3. Else,
      1. Let keys be ? EnumerableOwnNames(val).
      2. For each String P in keys do,
        1. Let newElement be ? InternalizeJSONProperty(val, P).
        2. If newElement is undefined, then
          1. Perform ? val.[[Delete]](P).
        3. Else,
          1. Perform ? CreateDataProperty(val, P, newElement).
          2. NOTE This algorithm intentionally does not throw an exception if CreateDataProperty returns false.
  3. Return ? Call(reviver, holder, « name, val »).

It is not permitted for a conforming implementation of JSON.parse to extend the JSON grammars. If an implementation wishes to support a modified or extended JSON interchange format it must do so by defining a different parse function.

Note

In the case where there are duplicate name Strings within an object, lexically preceding values for the same key shall be overwritten.

24.3.2JSON.stringify ( value [ , replacer [ , space ] ] )#

The stringify function returns a String in UTF-16 encoded JSON format representing an ECMAScript value. It can take three parameters. The value parameter is an ECMAScript value, which is usually an object or array, although it can also be a String, Boolean, Number or null. The optional replacer parameter is either a function that alters the way objects and arrays are stringified, or an array of Strings and Numbers that acts as a white list for selecting the object properties that will be stringified. The optional space parameter is a String or Number that allows the result to have white space injected into it to improve human readability.

These are the steps in stringifying an object:

  1. Let stack be a new empty List.
  2. Let indent be the empty String.
  3. Let PropertyList and ReplacerFunction be undefined.
  4. If Type(replacer) is Object, then
    1. If IsCallable(replacer) is true, then
      1. Let ReplacerFunction be replacer.
    2. Else,
      1. Let isArray be ? IsArray(replacer).
      2. If isArray is true, then
        1. Let PropertyList be a new empty List.
        2. Let len be ? ToLength(? Get(replacer, "length")).
        3. Let k be 0.
        4. Repeat while k<len,
          1. Let v be ? Get(replacer, ! ToString(k)).
          2. Let item be undefined.
          3. If Type(v) is String, let item be v.
          4. Else if Type(v) is Number, let item be ! ToString(v).
          5. Else if Type(v) is Object, then
            1. If v has a [[StringData]] or [[NumberData]] internal slot, let item be ? ToString(v).
          6. If item is not undefined and item is not currently an element of PropertyList, then
            1. Append item to the end of PropertyList.
          7. Let k be k+1.
  5. If Type(space) is Object, then
    1. If space has a [[NumberData]] internal slot, then
      1. Let space be ? ToNumber(space).
    2. Else if space has a [[StringData]] internal slot, then
      1. Let space be ? ToString(space).
  6. If Type(space) is Number, then
    1. Let space be min(10, ToInteger(space)).
    2. Set gap to a String containing space occurrences of code unit 0x0020 (SPACE). This will be the empty String if space is less than 1.
  7. Else if Type(space) is String, then
    1. If the number of elements in space is 10 or less, set gap to space; otherwise set gap to a String consisting of the first 10 elements of space.
  8. Else,
    1. Set gap to the empty String.
  9. Let wrapper be ObjectCreate(%ObjectPrototype%).
  10. Let status be CreateDataProperty(wrapper, the empty String, value).
  11. Assert: status is true.
  12. Return ? SerializeJSONProperty(the empty String, wrapper).

The length property of the stringify function is 3.

Note 1

JSON structures are allowed to be nested to any depth, but they must be acyclic. If value is or contains a cyclic structure, then the stringify function must throw a TypeError exception. This is an example of a value that cannot be stringified:


a = [];
a[0] = a;
my_text = JSON.stringify(a); // This must throw a TypeError.
        
Note 2

Symbolic primitive values are rendered as follows:

  • The null value is rendered in JSON text as the String null.
  • The undefined value is not rendered.
  • The true value is rendered in JSON text as the String true.
  • The false value is rendered in JSON text as the String false.
Note 3

String values are wrapped in QUOTATION MARK (") code units. The code units " and \ are escaped with \ prefixes. Control characters code units are replaced with escape sequences \uHHHH, or with the shorter forms, \b (BACKSPACE), \f (FORM FEED), \n (LINE FEED), \r (CARRIAGE RETURN), \t (CHARACTER TABULATION).

Note 4

Finite numbers are stringified as if by calling ToString(number). NaN and Infinity regardless of sign are represented as the String null.

Note 5

Values that do not have a JSON representation (such as undefined and functions) do not produce a String. Instead they produce the undefined value. In arrays these values are represented as the String null. In objects an unrepresentable value causes the property to be excluded from stringification.

Note 6

An object is rendered as U+007B (LEFT CURLY BRACKET) followed by zero or more properties, separated with a U+002C (COMMA), closed with a U+007D (RIGHT CURLY BRACKET). A property is a quoted String representing the key or property name, a U+003A (COLON), and then the stringified property value. An array is rendered as an opening U+005B (LEFT SQUARE BRACKET followed by zero or more values, separated with a U+002C (COMMA), closed with a U+005D (RIGHT SQUARE BRACKET).

24.3.2.1Runtime Semantics: SerializeJSONProperty ( key, holder )#

The abstract operation SerializeJSONProperty with arguments key, and holder has access to ReplacerFunction from the invocation of the stringify method. Its algorithm is as follows:

  1. Let value be ? Get(holder, key).
  2. If Type(value) is Object, then
    1. Let toJSON be ? Get(value, "toJSON").
    2. If IsCallable(toJSON) is true, then
      1. Let value be ? Call(toJSON, value, « key »).
  3. If ReplacerFunction is not undefined, then
    1. Let value be ? Call(ReplacerFunction, holder, « key, value »).
  4. If Type(value) is Object, then
    1. If value has a [[NumberData]] internal slot, then
      1. Let value be ? ToNumber(value).
    2. Else if value has a [[StringData]] internal slot, then
      1. Let value be ? ToString(value).
    3. Else if value has a [[BooleanData]] internal slot, then
      1. Let value be the value of the [[BooleanData]] internal slot of value.
  5. If value is null, return "null".
  6. If value is true, return "true".
  7. If value is false, return "false".
  8. If Type(value) is String, return QuoteJSONString(value).
  9. If Type(value) is Number, then
    1. If value is finite, return ! ToString(value).
    2. Else, return "null".
  10. If Type(value) is Object and IsCallable(value) is false, then
    1. Let isArray be ? IsArray(value).
    2. If isArray is true, return ? SerializeJSONArray(value).
    3. Else, return ? SerializeJSONObject(value).
  11. Return undefined.

24.3.2.2Runtime Semantics: QuoteJSONString ( value )#

The abstract operation QuoteJSONString with argument value wraps a String value in QUOTATION MARK code units and escapes certain other code units within it.

  1. Let product be code unit 0x0022 (QUOTATION MARK).
  2. For each code unit C in value
    1. If C is 0x0022 (QUOTATION MARK) or 0x005C (REVERSE SOLIDUS), then
      1. Let product be the concatenation of product and code unit 0x005C (REVERSE SOLIDUS).
      2. Let product be the concatenation of product and C.
    2. Else if C is 0x0008 (BACKSPACE), 0x000C (FORM FEED), 0x000A (LINE FEED), 0x000D (CARRIAGE RETURN), or 0x0009 (CHARACTER TABULATION), then
      1. Let product be the concatenation of product and code unit 0x005C (REVERSE SOLIDUS).
      2. Let abbrev be the String value corresponding to the value of C as follows:
        BACKSPACE "b"
        FORM FEED (FF) "f"
        LINE FEED (LF) "n"
        CARRIAGE RETURN (CR) "r"
        CHARACTER TABULATION "t"
      3. Let product be the concatenation of product and abbrev.
    3. Else if C has a code unit value less than 0x0020 (SPACE), then
      1. Let product be the concatenation of product and code unit 0x005C (REVERSE SOLIDUS).
      2. Let product be the concatenation of product and "u".
      3. Let hex be the string result of converting the numeric code unit value of C to a String of four hexadecimal digits. Alphabetic hexadecimal digits are presented as lowercase Latin letters.
      4. Let product be the concatenation of product and hex.
    4. Else,
      1. Let product be the concatenation of product and C.
  3. Let product be the concatenation of product and code unit 0x0022 (QUOTATION MARK).
  4. Return product.

24.3.2.3Runtime Semantics: SerializeJSONObject ( value )#

The abstract operation SerializeJSONObject with argument value serializes an object. It has access to the stack, indent, gap, and PropertyList values of the current invocation of the stringify method.

  1. If stack contains value, throw a TypeError exception because the structure is cyclical.
  2. Append value to stack.
  3. Let stepback be indent.
  4. Let indent be the concatenation of indent and gap.
  5. If PropertyList is not undefined, then
    1. Let K be PropertyList.
  6. Else,
    1. Let K be ? EnumerableOwnNames(value).
  7. Let partial be a new empty List.
  8. For each element P of K,
    1. Let strP be ? SerializeJSONProperty(P, value).
    2. If strP is not undefined, then
      1. Let member be QuoteJSONString(P).
      2. Let member be the concatenation of member and the string ":".
      3. If gap is not the empty String, then
        1. Let member be the concatenation of member and code unit 0x0020 (SPACE).
      4. Let member be the concatenation of member and strP.
      5. Append member to partial.
  9. If partial is empty, then
    1. Let final be "{}".
  10. Else,
    1. If gap is the empty String, then
      1. Let properties be a String formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with code unit 0x002C (COMMA). A comma is not inserted either before the first String or after the last String.
      2. Let final be the result of concatenating "{", properties, and "}".
    2. Else gap is not the empty String
      1. Let separator be the result of concatenating code unit 0x002C (COMMA), code unit 0x000A (LINE FEED), and indent.
      2. Let properties be a String formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with separator. The separator String is not inserted either before the first String or after the last String.
      3. Let final be the result of concatenating "{", code unit 0x000A (LINE FEED), indent, properties, code unit 0x000A (LINE FEED), stepback, and "}".
  11. Remove the last element of stack.
  12. Let indent be stepback.
  13. Return final.

24.3.2.4Runtime Semantics: SerializeJSONArray ( value )#

The abstract operation SerializeJSONArray with argument value serializes an array. It has access to the stack, indent, and gap values of the current invocation of the stringify method.

  1. If stack contains value, throw a TypeError exception because the structure is cyclical.
  2. Append value to stack.
  3. Let stepback be indent.
  4. Let indent be the concatenation of indent and gap.
  5. Let partial be a new empty List.
  6. Let len be ? ToLength(? Get(value, "length")).
  7. Let index be 0.
  8. Repeat while index < len
    1. Let strP be ? SerializeJSONProperty(! ToString(index), value).
    2. If strP is undefined, then
      1. Append "null" to partial.
    3. Else,
      1. Append strP to partial.
    4. Increment index by 1.
  9. If partial is empty, then
    1. Let final be "[]".
  10. Else,
    1. If gap is the empty String, then
      1. Let properties be a String formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with code unit 0x002C (COMMA). A comma is not inserted either before the first String or after the last String.
      2. Let final be the result of concatenating "[", properties, and "]".
    2. Else,
      1. Let separator be the result of concatenating code unit 0x002C (COMMA), code unit 0x000A (LINE FEED), and indent.
      2. Let properties be a String formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with separator. The separator String is not inserted either before the first String or after the last String.
      3. Let final be the result of concatenating "[", code unit 0x000A (LINE FEED), indent, properties, code unit 0x000A (LINE FEED), stepback, and "]".
  11. Remove the last element of stack.
  12. Let indent be stepback.
  13. Return final.
Note

The representation of arrays includes only the elements between zero and array.length - 1 inclusive. Properties whose keys are not array indexes are excluded from the stringification. An array is stringified as an opening LEFT SQUARE BRACKET, elements separated by COMMA, and a closing RIGHT SQUARE BRACKET.

24.3.3JSON [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "JSON".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25Control Abstraction Objects(控制抽象对象)#

25.1Iteration(循环)#

25.1.1Common Iteration Interfaces(常用迭代接口)#

An interface is a set of property keys whose associated values match a specific specification. Any object that provides all the properties as described by an interface's specification conforms to that interface. An interface is not represented by a distinct object. There may be many separately implemented objects that conform to any interface. An individual object may conform to multiple interfaces.

接口是一组属性键,其关联值与特定规范匹配。 提供接口规范描述的所有属性的任何对象都符合该接口。 接口不由不同的对象表示。 可能有许多单独实现的对象符合任何接口。 单个对象可以符合多个接口。

25.1.1.1The Iterable Interface#

The Iterable interface includes the property described in Table 53:

Iterable接口包括表53中描述的属性:

Table 53: Iterable Interface Required Properties(可迭代接口必需属性)
Property Value Requirements
@@iterator A function that returns an Iterator object.
一个返回Iterator对象的函数。
The returned object must conform to the Iterator interface.
返回的对象必须符合Iterator接口。

25.1.1.2The Iterator Interface#

An object that implements the Iterator interface must include the property in Table 54. Such objects may also implement the properties in Table 55.

实现Iterator接口的对象必须包含表54中的属性。此类对象也可以实现表55中的属性。

Table 54: Iterator Interface Required Properties(迭代器接口必需属性)
Property Value Requirements
next A function that returns an IteratorResult object.
一个返回IteratorResult对象的函数。
The returned object must conform to the IteratorResult interface. If a previous call to the next method of an Iterator has returned an IteratorResult object whose done property is true, then all subsequent calls to the next method of that object should also return an IteratorResult object whose done property is true. However, this requirement is not enforced.
返回的对象必须符合IteratorResult接口。 如果先前对Iterator的下一个方法的调用返回了其done属性为true的IteratorResult对象,则对该对象的下一个方法的所有后续调用也应返回其done属性为true的IteratorResult对象。 但是,此要求未得到强制执行。
Note 1

Arguments may be passed to the next function but their interpretation and validity is dependent upon the target Iterator. The for-of statement and other common users of Iterators do not pass any arguments, so Iterator objects that expect to be used in such a manner must be prepared to deal with being called with no arguments.

参数可以传递给next函数,但它们的解释和有效性取决于目标迭代器。 for-of语句和迭代器的其他常见用法不传递任何参数,因此期望以这种方式使用的Iterator对象必须准备好处理没有参数的调用。

Table 55: Iterator Interface Optional Properties(Iterator接口可选属性)
Property Value Requirements
return A function that returns an IteratorResult object.
一个返回IteratorResult对象的函数。
The returned object must conform to the IteratorResult interface. Invoking this method notifies the Iterator object that the caller does not intend to make any more next method calls to the Iterator. The returned IteratorResult object will typically have a done property whose value is true, and a value property with the value passed as the argument of the return method. However, this requirement is not enforced.
返回的对象必须符合IteratorResult接口。 调用此方法通知Iterator对象调用者不打算再对Iterator进行下一次方法调用。 返回的IteratorResult对象通常具有一个值为true的done属性,以及一个value属性,其值作为return方法的参数传递。 但是,此要求未得到强制执行。
throw A function that returns an IteratorResult object. The returned object must conform to the IteratorResult interface. Invoking this method notifies the Iterator object that the caller has detected an error condition. The argument may be used to identify the error condition and typically will be an exception object. A typical response is to throw the value passed as the argument. If the method does not throw, the returned IteratorResult object will typically have a done property whose value is true.
返回的对象必须符合IteratorResult接口。 调用此方法会通知Iterator对象调用方已检测到错误情况。 该参数可用于识别错误条件,并且通常是异常对象。 典型的响应是抛出作为参数传递的值。 如果方法没有抛出,则返回的IteratorResult对象通常会有一个值为true的done属性。
Note 2

Typically callers of these methods should check for their existence before invoking them. Certain ECMAScript language features including for-of, yield*, and array destructuring call these methods after performing an existence check. Most ECMAScript library functions that accept Iterable objects as arguments also conditionally call them.

通常,这些方法的调用者应在调用它们之前检查它们的存在。 某些ECMAScript语言功能(包括for-of,yield *和数组解构)在执行存在检查后调用这些方法。 大多数接受Iterable对象作为参数的ECMAScript库函数也有条件地调用它们。

25.1.1.3The IteratorResult Interface#

The IteratorResult interface includes the properties listed in Table 56(IteratorResult接口包括表56中列出的属性:):

Table 56: IteratorResult Interface Properties
Property Value Requirements
done Either true or false. This is the result status of an iterator next method call. If the end of the iterator was reached done is true. If the end was not reached done is false and a value is available. If a done property (either own or inherited) does not exist, it is consider to have the value false.
这是迭代器next方法调用的结果状态。 如果到达迭代器的末尾,则为true。 如果未达到结束,则为false并且值可用。 如果不存在done属性(自己的或继承的),则认为值为false。
value Any ECMAScript language value. If done is false, this is the current iteration element value. If done is true, this is the return value of the iterator, if it supplied one. If the iterator does not have a return value, value is undefined. In that case, the value property may be absent from the conforming object if it does not inherit an explicit value property.
如果done为false,则这是当前迭代元素值。 如果done为true,则这是迭代器的返回值,如果它提供了一个。 如果迭代器没有返回值,则值为undefined。 在这种情况下,如果不继承显式值属性,则可以在符合对象中不存在value属性。

25.1.2The %IteratorPrototype% Object#

The value of the [[Prototype]] internal slot of the %IteratorPrototype% object is the intrinsic object %ObjectPrototype%. The %IteratorPrototype% object is an ordinary object. The initial value of the [[Extensible]] internal slot of the %IteratorPrototype% object is true.

%IteratorPrototype%对象的[[Prototype]]内部槽的值是内部对象%ObjectPrototype%。 %IteratorPrototype%对象是普通对象。 %IteratorPrototype%对象的[[Extensible]]内部插槽的初始值为true。

Note

All objects defined in this specification that implement the Iterator interface also inherit from %IteratorPrototype%. ECMAScript code may also define objects that inherit from %IteratorPrototype%.The %IteratorPrototype% object provides a place where additional methods that are applicable to all iterator objects may be added.

本规范中定义的实现Iterator接口的所有对象也都继承自%IteratorPrototype%。 ECMAScript代码还可以定义从%IteratorPrototype%继承的对象。%IteratorPrototype%对象提供了一个可以添加适用于所有迭代器对象的其他方法的位置。

The following expression is one way that ECMAScript code can access the %IteratorPrototype% object:

以下表达式是ECMAScript代码可以访问%IteratorPrototype%对象的一种方式:

Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))

25.1.2.1%IteratorPrototype% [ @@iterator ] ( )#

The following steps are taken:

  1. Return the this value.

The value of the name property of this function is "[Symbol.iterator]".

此函数的name属性的值为“[Symbol.iterator]”。

25.2GeneratorFunction Objects#

Generator Function objects are functions that are usually created by evaluating GeneratorDeclaration, GeneratorExpression, and GeneratorMethod syntactic productions. They may also be created by calling the %GeneratorFunction% intrinsic.

生成器函数对象是通常通过执行GeneratorDeclaration,GeneratorExpression和GeneratorMethod语法生成来创建的函数。 它们也可以通过调用%GeneratorFunction%内在函数来创建。

Figure 2 (Informative): Generator Objects Relationships(图2(参考信息):生成器对象关系)
A staggering variety of boxes and arrows.

25.2.1The GeneratorFunction Constructor#

The GeneratorFunction constructor is the %GeneratorFunction% intrinsic. When GeneratorFunction is called as a function rather than as a constructor, it creates and initializes a new GeneratorFunction object. Thus the function call GeneratorFunction (…) is equivalent to the object creation expression new GeneratorFunction (…) with the same arguments.

GeneratorFunction构造函数是%GeneratorFunction%内在函数。 当GeneratorFunction作为函数而不是构造函数调用时,它会创建并初始化一个新的GeneratorFunction对象。 因此函数调用GeneratorFunction(...)等效于具有相同参数的对象创建表达式new GeneratorFunction(...)。

GeneratorFunction is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified GeneratorFunction behaviour must include a super call to the GeneratorFunction constructor to create and initialize subclass instances with the internal slots necessary for built-in GeneratorFunction behaviour. All ECMAScript syntactic forms for defining generator function objects create direct instances of GeneratorFunction. There is no syntactic means to create instances of GeneratorFunction subclasses.

GeneratorFunction被设计为可子类化。 它可以用作类定义的extends子句的值。 打算继承指定的GeneratorFunction行为的子类构造函数必须包含对GeneratorFunction构造函数的super调用,以使用内置GeneratorFunction行为所需的内部插槽创建和初始化子类实例。 用于定义生成器函数对象的所有ECMAScript语法形式都创建了GeneratorFunction的直接实例。 创建GeneratorFunction子类的实例没有语法手段。

25.2.1.1GeneratorFunction (p1, p2, … , pn, body)#

The last argument specifies the body (executable code) of a generator function; any preceding arguments specify formal parameters.

When the GeneratorFunction function is called with some arguments p1, p2, … , pn, body (where n might be 0, that is, there are no “p” arguments, and where body might also not be provided), the following steps are taken:

最后一个参数指定生成器函数的主体(可执行代码); 任何前面的参数指定形式参数。当使用一些参数p1,p2,...,pn,body(其中n可能为0,即没有“p”参数,并且也可能未提供body)调用GeneratorFunction函数时,步骤如下:

  1. Let C be the active function object.
  2. Let args be the argumentsList that was passed to this function by [[Call]] or [[Construct]].
  3. Return ? CreateDynamicFunction(C, NewTarget, "generator", args).
Note

See NOTE for 19.2.1.1.

25.2.2Properties of the GeneratorFunction Constructor#

The GeneratorFunction constructor is a standard built-in function object that inherits from the Function constructor. The value of the [[Prototype]] internal slot of the GeneratorFunction constructor is the intrinsic object %Function%.

The value of the [[Extensible]] internal slot of the GeneratorFunction constructor is true.

The value of the name property of the GeneratorFunction is "GeneratorFunction".

The GeneratorFunction constructor has the following properties:

GeneratorFunction构造函数是一个标准的内置函数对象,它继承自Function构造函数。 GeneratorFunction构造函数的[[Prototype]]内部槽的值是内部对象%Function%。
GeneratorFunction构造函数的[[Extensible]]内部插槽的值为true。
GeneratorFunction的name属性值是“GeneratorFunction”。
GeneratorFunction构造函数具有以下属性:

25.2.2.1GeneratorFunction.length#

This is a data property with a value of 1. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.2.2GeneratorFunction.prototype#

The initial value of GeneratorFunction.prototype is the intrinsic object %Generator%.

GeneratorFunction.prototype的初始值是内部对象%Generator%。

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

25.2.3Properties of the GeneratorFunction Prototype Object(GeneratorFunction原型对象的属性)#

The GeneratorFunction prototype object is an ordinary object. It is not a function object and does not have an [[ECMAScriptCode]] internal slot or any other of the internal slots listed in Table 27 or Table 57. In addition to being the value of the prototype property of the %GeneratorFunction% intrinsic, it is the %Generator% intrinsic (see Figure 2).

GeneratorFunction原型对象是一个普通对象。 它不是一个函数对象,并且没有[27]或表57中列出的[[ECMAScriptCode]]内部插槽或任何其他内部插槽。除了是%GeneratorFunction%内在函数的prototype属性的值之外, 它是%Generator%(见图2)。

The value of the [[Prototype]] internal slot of the GeneratorFunction prototype object is the %FunctionPrototype% intrinsic object. The initial value of the [[Extensible]] internal slot of the GeneratorFunction prototype object is true.

GeneratorFunction原型对象的[[Prototype]]内部槽的值是%FunctionPrototype%内部对象。 GeneratorFunction原型对象的[[Extensible]]内部插槽的初始值为true。

25.2.3.1GeneratorFunction.prototype.constructor#

The initial value of GeneratorFunction.prototype.constructor is the intrinsic object %GeneratorFunction%.

GeneratorFunction.prototype.constructor的初始值是内部对象%GeneratorFunction%。

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.3.2GeneratorFunction.prototype.prototype#

The value of GeneratorFunction.prototype.prototype is the %GeneratorPrototype% intrinsic object.

GeneratorFunction.prototype.constructor的初始值是内部对象%GeneratorFunction%。

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.3.3GeneratorFunction.prototype [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "GeneratorFunction".

@@ toStringTag属性的初始值是String值“GeneratorFunction”。

function* mygen() {} Object.prototype.toString.call(mygen); // "[object GeneratorFunction]"

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.4GeneratorFunction Instances#

Every GeneratorFunction instance is an ECMAScript function object and has the internal slots listed in Table 27. The value of the [[FunctionKind]] internal slot for all such instances is "generator".

Each GeneratorFunction instance has the following own properties:

每个GeneratorFunction实例都是ECMAScript函数对象,并具有表27中列出的内部插槽。所有此类实例的[[FunctionKind]]内部插槽的值为“generator”。
每个GeneratorFunction实例都具有以下属性:

25.2.4.1length#

The value of the length property is an integer that indicates the typical number of arguments expected by the GeneratorFunction. However, the language permits the function to be invoked with some other number of arguments. The behaviour of a GeneratorFunction when invoked on a number of arguments other than the number specified by its length property depends on the function.

length属性的值是一个整数,表示GeneratorFunction形参数量。 但是,该语言允许使用其他数量的参数调用该函数。 当在除了由length属性指定的个数之外的参数上调用时,GeneratorFunction的行为取决于函数。

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.4.2name#

The specification for the name property of Function instances given in 19.2.4.2 also applies to GeneratorFunction instances.

19.2.4.2中给出的Function实例的name属性规范也适用于GeneratorFunction实例。

25.2.4.3prototype#

Whenever a GeneratorFunction instance is created another ordinary object is also created and is the initial value of the generator function's prototype property. The value of the prototype property is used to initialize the [[Prototype]] internal slot of a newly created Generator object when the generator function object is invoked using [[Call]].

每当创建一个GeneratorFunction实例时,也会创建另一个普通对象,它是生成器函数的prototype属性的初始值。 当使用[[Call]]调用生成器函数对象时,prototype属性的值用于初始化新创建的Generator对象的[[Prototype]]内部槽。

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Note

Unlike function instances, the object that is the value of the a GeneratorFunction's prototype property does not have a constructor property whose value is the GeneratorFunction instance.

与函数实例不同,作为GeneratorFunction的prototype属性值的对象没有值为GeneratorFunction实例的构造函数属性

25.3Generator Objects#

A Generator object is an instance of a generator function and conforms to both the Iterator and Iterable interfaces.

Generator instances directly inherit properties from the object that is the value of the prototype property of the Generator function that created the instance. Generator instances indirectly inherit properties from the Generator Prototype intrinsic, %GeneratorPrototype%.

Generator对象是生成器函数的实例,并且符合Iterator和Iterable接口。
Generator实例直接从对象继承属性,该属性是创建实例的Generator函数的prototype属性的值。 Generator实例间接地从Generator Prototype内在函数%GeneratorPrototype%继承属性。

25.3.1Properties of Generator Prototype#

The Generator prototype object is the %GeneratorPrototype% intrinsic. It is also the initial value of the prototype property of the %Generator% intrinsic (the GeneratorFunction.prototype).

The Generator prototype is an ordinary object. It is not a Generator instance and does not have a [[GeneratorState]] internal slot.

The value of the [[Prototype]] internal slot of the Generator prototype object is the intrinsic object %IteratorPrototype%. The initial value of the [[Extensible]] internal slot of the Generator prototype object is true.

All Generator instances indirectly inherit properties of the Generator prototype object.

Generator原型对象是内置%GeneratorPrototype%。 它也是%Generator%内置(GeneratorFunction.prototype)的prototype属性的初始值。Generator原型是一个普通的对象。 它不是Generator实例,也没有[[GeneratorState]]内部插槽。Generator原型对象的[[Prototype]]内部槽的值是内部对象%IteratorPrototype%。 Generator原型对象的[[Extensible]]内部插槽的初始值为true。
所有Generator实例间接继承Generator原型对象的属性。

25.3.1.1Generator.prototype.constructor#

The initial value of Generator.prototype.constructor is the intrinsic object %Generator%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.3.1.2Generator.prototype.next ( value )#

The next method performs the following steps:

  1. Let g be the this value.
  2. Return ? GeneratorResume(g, value).

25.3.1.3Generator.prototype.return ( value )#

The return method performs the following steps:

  1. Let g be the this value.
  2. Let C be Completion{[[Type]]: return, [[Value]]: value, [[Target]]: empty}.
  3. Return ? GeneratorResumeAbrupt(g, C).

25.3.1.4Generator.prototype.throw ( exception )#

The throw method performs the following steps:

  1. Let g be the this value.
  2. Let C be Completion{[[Type]]: throw, [[Value]]: exception, [[Target]]: empty}.
  3. Return ? GeneratorResumeAbrupt(g, C).

25.3.1.5Generator.prototype [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "Generator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.3.2Properties of Generator Instances#

Generator instances are initially created with the internal slots described in Table 57.

最初使用表57中描述的内部插槽创建生成器实例。

Table 57: Internal Slots of Generator Instances
Internal Slot Description
[[GeneratorState]] The current execution state of the generator. The possible values are: undefined, "suspendedStart", "suspendedYield", "executing", and "completed".
生成器的当前执行状态。 可能的值包括:undefined,“suspendedStart”,“suspendedYield”,“execution”和“completed”。
[[GeneratorContext]] The execution context that is used when executing the code of this generator.
执行此生成器代码时使用的执行上下文。

25.3.3Generator Abstract Operations#

25.3.3.1GeneratorStart (generator, generatorBody)#

The abstract operation GeneratorStart with arguments generator and generatorBody performs the following steps:

  1. Assert: The value of generator's [[GeneratorState]] internal slot is undefined.
  2. Let genContext be the running execution context.
  3. Set the Generator component of genContext to generator.
  4. Set the code evaluation state of genContext such that when evaluation is resumed for that execution context the following steps will be performed:
    1. Let result be the result of evaluating generatorBody.
    2. Assert: If we return here, the generator either threw an exception or performed either an implicit or explicit return.
    3. Remove genContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
    4. Set generator's [[GeneratorState]] internal slot to "completed".
    5. Once a generator enters the "completed" state it never leaves it and its associated execution context is never resumed. Any execution state associated with generator can be discarded at this point.
    6. If result is a normal completion, let resultValue be undefined.
    7. Else,
      1. If result.[[Type]] is return, let resultValue be result.[[Value]].
      2. Else, return Completion(result).
    8. Return CreateIterResultObject(resultValue, true).
  5. Set generator's [[GeneratorContext]] internal slot to genContext.
  6. Set generator's [[GeneratorState]] internal slot to "suspendedStart".
  7. Return NormalCompletion(undefined).

25.3.3.2GeneratorValidate ( generator )#

The abstract operation GeneratorValidate with argument generator performs the following steps:

  1. If Type(generator) is not Object, throw a TypeError exception.
  2. If generator does not have a [[GeneratorState]] internal slot, throw a TypeError exception.
  3. Assert: generator also has a [[GeneratorContext]] internal slot.
  4. Let state be the value of generator's [[GeneratorState]] internal slot.
  5. If state is "executing", throw a TypeError exception.
  6. Return state.

25.3.3.3GeneratorResume ( generator, value )#

The abstract operation GeneratorResume with arguments generator and value performs the following steps:

  1. Let state be ? GeneratorValidate(generator).
  2. If state is "completed", return CreateIterResultObject(undefined, true).
  3. Assert: state is either "suspendedStart" or "suspendedYield".
  4. Let genContext be the value of generator's [[GeneratorContext]] internal slot.
  5. Let methodContext be the running execution context.
  6. Suspend methodContext.
  7. Set generator's [[GeneratorState]] internal slot to "executing".
  8. Push genContext onto the execution context stack; genContext is now the running execution context.
  9. Resume the suspended evaluation of genContext using NormalCompletion(value) as the result of the operation that suspended it. Let result be the value returned by the resumed computation.
  10. Assert: When we return here, genContext has already been removed from the execution context stack and methodContext is the currently running execution context.
  11. Return Completion(result).

25.3.3.4GeneratorResumeAbrupt (generator, abruptCompletion)#

The abstract operation GeneratorResumeAbrupt with arguments generator and abruptCompletion performs the following steps:

  1. Let state be ? GeneratorValidate(generator).
  2. If state is "suspendedStart", then
    1. Set generator's [[GeneratorState]] internal slot to "completed".
    2. Once a generator enters the "completed" state it never leaves it and its associated execution context is never resumed. Any execution state associated with generator can be discarded at this point.
    3. Let state be "completed".
  3. If state is "completed", then
    1. If abruptCompletion.[[Type]] is return, then
      1. Return CreateIterResultObject(abruptCompletion.[[Value]], true).
    2. Return Completion(abruptCompletion).
  4. Assert: state is "suspendedYield".
  5. Let genContext be the value of generator's [[GeneratorContext]] internal slot.
  6. Let methodContext be the running execution context.
  7. Suspend methodContext.
  8. Set generator's [[GeneratorState]] internal slot to "executing".
  9. Push genContext onto the execution context stack; genContext is now the running execution context.
  10. Resume the suspended evaluation of genContext using abruptCompletion as the result of the operation that suspended it. Let result be the completion record returned by the resumed computation.
  11. Assert: When we return here, genContext has already been removed from the execution context stack and methodContext is the currently running execution context.
  12. Return Completion(result).

25.3.3.5GeneratorYield ( iterNextObj )#

The abstract operation GeneratorYield with argument iterNextObj performs the following steps:

  1. Assert: iterNextObj is an Object that implements the IteratorResult interface.
  2. Let genContext be the running execution context.
  3. Assert: genContext is the execution context of a generator.
  4. Let generator be the value of the Generator component of genContext.
  5. Set the value of generator's [[GeneratorState]] internal slot to "suspendedYield".
  6. Remove genContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
  7. Set the code evaluation state of genContext such that when evaluation is resumed with a Completion resumptionValue the following steps will be performed:
    1. Return resumptionValue.
    2. NOTE: This returns to the evaluation of the YieldExpression production that originally called this abstract operation.
  8. Return NormalCompletion(iterNextObj).
  9. NOTE: This returns to the evaluation of the operation that had most previously resumed evaluation of genContext.

25.4Promise Objects#

A Promise is an object that is used as a placeholder for the eventual results of a deferred (and possibly asynchronous) computation.

Promise是一个占位符对象,用于记录延迟(可能是异步)计算的最终结果。

Any Promise object is in one of three mutually exclusive states: fulfilled, rejected, and pending:

任何Promise对象都处于三种互斥状态之一fulfilled, rejected, and pending

A promise is said to be settled if it is not pending, i.e. if it is either fulfilled or rejected.

如果一个promise状态是fulfilled或rejected,则可以说这个promise是状态确定了

A promise is resolved if it is settled or if it has been “locked in” to match the state of another promise. Attempting to resolve or reject a resolved promise has no effect. A promise is unresolved if it is not resolved. An unresolved promise is always in the pending state. A resolved promise may be pending, fulfilled or rejected.

如果一个promise被确定或者它被“锁定”以匹配另一个promise的状态,则该承诺得到解决。 尝试解决或拒绝已解决的promise无效。 如果未解决,则promise未得到解决。 未解决的promise始终处于暂挂状态。 已解决的promise可能pending, fulfilled 或 rejected。

25.4.1Promise Abstract Operations(Promise抽象操作)#

25.4.1.1PromiseCapability Records(Promise能力记录)#

A PromiseCapability is a Record value used to encapsulate a promise object along with the functions that are capable of resolving or rejecting that promise object. PromiseCapability records are produced by the NewPromiseCapability abstract operation.

PromiseCapability Records have the fields listed in Table 58.

PromiseCapability是一个Record值,用于封装promise对象以及能够解析或拒绝该promise对象的函数。 PromiseCapability记录由NewPromiseCapability抽象操作生成。PromiseCapability Records具有表58中列出的字段。

Table 58: PromiseCapability Record Fields
Field Name Value Meaning
[[Promise]] An object An object that is usable as a promise. 可用作promise的对象。
[[Resolve]] A function object The function that is used to resolve the given promise object. 用于解析给定promise对象的函数。
[[Reject]] A function object The function that is used to reject the given promise object. 用于拒绝给定promise对象的函数。

25.4.1.1.1IfAbruptRejectPromise ( value, capability ) (如果突然拒绝promise)#

IfAbruptRejectPromise is a short hand for a sequence of algorithm steps that use a PromiseCapability record. An algorithm step of the form:

IfAbruptRejectPromise是使用PromiseCapability记录的一系列算法步骤的简写。 算法形式步骤:

  1. IfAbruptRejectPromise(value, capability).

means the same thing as:

意思是:

  1. If value is an abrupt completion, then
    1. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »).
    2. Return capability.[[Promise]].
  2. Else if value is a Completion Record, let value be value.[[Value]].

25.4.1.2PromiseReaction Records(Promise反应记录)#

The PromiseReaction is a Record value used to store information about how a promise should react when it becomes resolved or rejected with a given value. PromiseReaction records are created by the PerformPromiseThen abstract operation, and are used by a PromiseReactionJob.

PromiseReaction records have the fields listed in Table 59.

PromiseReaction是一个Record值,用于存储有关promise在使用给定值解析或拒绝时应如何反应的信息。 PromiseReaction记录由PerformPromiseThen抽象操作创建,并由PromiseReactionJob使用。 PromiseReaction记录具有表59中列出的字段。

Table 59: PromiseReaction Record Fields
Field Name Value Meaning
[[Capabilities]] A PromiseCapability record The capabilities of the promise for which this record provides a reaction handler. 此记录提供反应处理器的promise的功能。
[[Handler]] A function object or a String 函数对象或String The function that should be applied to the incoming value, and whose return value will govern what happens to the derived promise. If [[Handler]] is "Identity" it is equivalent to a function that simply returns its first argument. If [[Handler]] is "Thrower" it is equivalent to a function that throws its first argument as an exception. 应用于传入值的函数,其返回值将控制派生的promise所发生的情况。 如果[[Handler]]是“Identity”,它等同于一个只返回其第一个参数的函数。 如果[[Handler]]是“Thrower”,它等同于将其第一个参数作为异常抛出的函数。

25.4.1.3CreateResolvingFunctions ( promise )#

When CreateResolvingFunctions is performed with argument promise, the following steps are taken:

使用参数promise执行CreateResolvingFunctions时,将执行以下步骤:

  1. Let alreadyResolved be a new Record { [[Value]]: false }.
  2. Let resolve be a new built-in function object as defined in Promise Resolve Functions (25.4.1.3.2).
  3. Set the [[Promise]] internal slot of resolve to promise.
  4. Set the [[AlreadyResolved]] internal slot of resolve to alreadyResolved.
  5. Let reject be a new built-in function object as defined in Promise Reject Functions (25.4.1.3.1).
  6. Set the [[Promise]] internal slot of reject to promise.
  7. Set the [[AlreadyResolved]] internal slot of reject to alreadyResolved.
  8. Return a new Record { [[Resolve]]: resolve, [[Reject]]: reject }.

25.4.1.3.1Promise Reject Functions#

A promise reject function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]] internal slots.

When a promise reject function F is called with argument reason, the following steps are taken:

promise reject 函数是一个匿名内置函数,它具有[[Promise]]和[[AlreadyResolved]]内部插槽。当使用参数原因调用promise拒绝函数F时,将执行以下步骤:

  1. Assert: F has a [[Promise]] internal slot whose value is an Object.
  2. Let promise be the value of F's [[Promise]] internal slot.
  3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal slot.
  4. If alreadyResolved.[[Value]] is true, return undefined.
  5. Set alreadyResolved.[[Value]] to true.
  6. Return RejectPromise(promise, reason).

The length property of a promise reject function is 1.

25.4.1.3.2Promise Resolve Functions#

A promise resolve function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]] internal slots.

When a promise resolve function F is called with argument resolution, the following steps are taken:

promise resolve函数是一个匿名内置函数,具有[[Promise]]和[[AlreadyResolved]]内部插槽。
当使用参数解析调用promise resolve函数F时,将执行以下步骤:

  1. Assert: F has a [[Promise]] internal slot whose value is an Object.
  2. Let promise be the value of F's [[Promise]] internal slot.
  3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal slot.
  4. If alreadyResolved.[[Value]] is true, return undefined.
  5. Set alreadyResolved.[[Value]] to true.
  6. If SameValue(resolution, promise) is true, then
    1. Let selfResolutionError be a newly created TypeError object.
    2. Return RejectPromise(promise, selfResolutionError).
  7. If Type(resolution) is not Object, then
    1. Return FulfillPromise(promise, resolution).
  8. Let then be Get(resolution, "then").
  9. If then is an abrupt completion, then
    1. Return RejectPromise(promise, then.[[Value]]).
  10. Let thenAction be then.[[Value]].
  11. If IsCallable(thenAction) is false, then
    1. Return FulfillPromise(promise, resolution).
  12. Perform EnqueueJob("PromiseJobs", PromiseResolveThenableJob, « promise, resolution, thenAction »).
  13. Return undefined.

The length property of a promise resolve function is 1.

25.4.1.4FulfillPromise ( promise, value)#

When the FulfillPromise abstract operation is called with arguments promise and value, the following steps are taken:

使用参数promise和value调用FulfillPromise抽象操作时,将执行以下步骤:

  1. Assert: the value of promise's [[PromiseState]] internal slot is "pending".
  2. Let reactions be the value of promise's [[PromiseFulfillReactions]] internal slot.
  3. Set the value of promise's [[PromiseResult]] internal slot to value.
  4. Set the value of promise's [[PromiseFulfillReactions]] internal slot to undefined.
  5. Set the value of promise's [[PromiseRejectReactions]] internal slot to undefined.
  6. Set the value of promise's [[PromiseState]] internal slot to "fulfilled".
  7. Return TriggerPromiseReactions(reactions, value).

25.4.1.5NewPromiseCapability ( C )#

The abstract operation NewPromiseCapability takes a constructor function, and attempts to use that constructor function in the fashion of the built-in Promise constructor to create a Promise object and extract its resolve and reject functions. The promise plus the resolve and reject functions are used to initialize a new PromiseCapability record which is returned as the value of this abstract operation.

抽象操作NewPromiseCapability接受构造函数,并尝试以内置Promise构造函数的方式使用该构造函数来创建Promise对象并提取其解析和拒绝函数。 promise以及resolve和reject函数用于初始化一个新的PromiseCapability记录,该记录作为此抽象操作的值返回。

  1. If IsConstructor(C) is false, throw a TypeError exception.
  2. NOTE C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 25.4.3.1).
  3. Let promiseCapability be a new PromiseCapability { [[Promise]]: undefined, [[Resolve]]: undefined, [[Reject]]: undefined }.
  4. Let executor be a new built-in function object as defined in GetCapabilitiesExecutor Functions (25.4.1.5.1).
  5. Set the [[Capability]] internal slot of executor to promiseCapability.
  6. Let promise be ? Construct(C, « executor »).
  7. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
  8. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
  9. Set promiseCapability.[[Promise]] to promise.
  10. Return promiseCapability.
Note

This abstract operation supports Promise subclassing, as it is generic on any constructor that calls a passed executor function argument in the same way as the Promise constructor. It is used to generalize static methods of the Promise constructor to any subclass.

这个抽象操作支持Promise子类化,因为它在任何构造函数上是通用的,它以与Promise构造函数相同的方式调用传递的executor函数参数。 它用于将Promise构造函数的静态方法概括为任何子类。

25.4.1.5.1GetCapabilitiesExecutor Functions#

A GetCapabilitiesExecutor function is an anonymous built-in function that has a [[Capability]] internal slot.

When a GetCapabilitiesExecutor function F is called with arguments resolve and reject, the following steps are taken:

GetCapabilitiesExecutor函数是一个匿名内置函数,具有[[Capability]]内部插槽。
当使用参数resolve和reject调用GetCapabilitiesExecutor函数F时,将执行以下步骤:

  1. Assert: F has a [[Capability]] internal slot whose value is a PromiseCapability Record.
  2. Let promiseCapability be the value of F's [[Capability]] internal slot.
  3. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
  4. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
  5. Set promiseCapability.[[Resolve]] to resolve.
  6. Set promiseCapability.[[Reject]] to reject.
  7. Return undefined.

The length property of a GetCapabilitiesExecutor function is 2.

25.4.1.6IsPromise ( x )#

The abstract operation IsPromise checks for the promise brand on an object.

抽象操作IsPromise检查对象上的promise标签

  1. If Type(x) is not Object, return false.
  2. If x does not have a [[PromiseState]] internal slot, return false.
  3. Return true.

25.4.1.7RejectPromise ( promise, reason )#

When the RejectPromise abstract operation is called with arguments promise and reason, the following steps are taken:

使用参数promise和reason调用RejectPromise抽象操作时,将执行以下步骤:

  1. Assert: the value of promise's [[PromiseState]] internal slot is "pending".
  2. Let reactions be the value of promise's [[PromiseRejectReactions]] internal slot.
  3. Set the value of promise's [[PromiseResult]] internal slot to reason.
  4. Set the value of promise's [[PromiseFulfillReactions]] internal slot to undefined.
  5. Set the value of promise's [[PromiseRejectReactions]] internal slot to undefined.
  6. Set the value of promise's [[PromiseState]] internal slot to "rejected".
  7. If the value of promise's [[PromiseIsHandled]] internal slot is false, perform HostPromiseRejectionTracker(promise, "reject").
  8. Return TriggerPromiseReactions(reactions, reason).

25.4.1.8TriggerPromiseReactions ( reactions, argument )#

The abstract operation TriggerPromiseReactions takes a collection of PromiseReactionRecords and enqueues a new Job for each record. Each such Job processes the [[Handler]] of the PromiseReactionRecord, and if the [[Handler]] is a function calls it passing the given argument.

抽象操作TriggerPromiseReactions获取PromiseReactionRecords的集合,并为每条记录排队一个新Job。 每个这样的Job处理PromiseReactionRecord的[[Handler]],如果[[Handler]]是一个函数,则调用它传递给定的参数。

  1. Repeat for each reaction in reactions, in original insertion order
    1. Perform EnqueueJob("PromiseJobs", PromiseReactionJob, « reaction, argument »).
  2. Return undefined.

25.4.1.9HostPromiseRejectionTracker ( promise, operation ) (promise宿主rejection跟踪器)#

HostPromiseRejectionTracker is an implementation-defined abstract operation that allows host environments to track promise rejections.

An implementation of HostPromiseRejectionTracker must complete normally in all cases. The default implementation of HostPromiseRejectionTracker is to do nothing.

HostPromiseRejectionTracker是一个实现定义的抽象操作,允许主机环境跟踪promise rejections。HostPromiseRejectionTracker的实现必须在所有情况下正常完成。 HostPromiseRejectionTracker的默认实现是什么都不做。

Note 1

HostPromiseRejectionTracker is called in two scenarios:

在两种情况下调用HostPromiseRejectionTracker:

  • When a promise is rejected without any handlers, it is called with its operation argument set to "reject".
  • When a handler is added to a rejected promise for the first time, it is called with its operation argument set to "handle".

A typical implementation of HostPromiseRejectionTracker might try to notify developers of unhandled rejections, while also being careful to notify them if such previous notifications are later invalidated by new handlers being attached.

HostPromiseRejectionTracker的典型实现可能会尝试通知开发人员未处理的拒绝,同时还要小心通知他们,如果此类稍后附加的新处理程序,先前的通知无效。

Note 2

If operation is "handle", an implementation should not hold a reference to promise in a way that would interfere with garbage collection. An implementation may hold a reference to promise if operation is "reject", since it is expected that rejections will be rare and not on hot code paths.

如果操作是“handle”,则实现不应以对干扰垃圾收集的方式持有对promise的引用。 如果操作是“拒绝”,则实现可以保留对promise的引用,因为预期拒绝将是罕见的而不是在热代码路径上。

25.4.2Promise Jobs#

25.4.2.1PromiseReactionJob ( reaction, argument )#

The job PromiseReactionJob with parameters reaction and argument applies the appropriate handler to the incoming value, and uses the handler's return value to resolve or reject the derived promise associated with that handler.

具有参数reaction和argument的作业PromiseReactionJob将适当的处理程序应用于传入值,并使用处理程序的返回值来解析或拒绝与该处理程序关联的派生promise。

  1. Assert: reaction is a PromiseReaction Record.
  2. Let promiseCapability be reaction.[[Capabilities]].
  3. Let handler be reaction.[[Handler]].
  4. If handler is "Identity", let handlerResult be NormalCompletion(argument).
  5. Else if handler is "Thrower", let handlerResult be Completion{[[Type]]: throw, [[Value]]: argument, [[Target]]: empty}.
  6. Else, let handlerResult be Call(handler, undefined, « argument »).
  7. If handlerResult is an abrupt completion, then
    1. Let status be Call(promiseCapability.[[Reject]], undefined, « handlerResult.[[Value]] »).
    2. NextJob Completion(status).
  8. Let status be Call(promiseCapability.[[Resolve]], undefined, « handlerResult.[[Value]] »).
  9. NextJob Completion(status).

25.4.2.2PromiseResolveThenableJob ( promiseToResolve, thenable, then)#

The job PromiseResolveThenableJob with parameters promiseToResolve, thenable, and then performs the following steps:

  1. Let resolvingFunctions be CreateResolvingFunctions(promiseToResolve).
  2. Let thenCallResult be Call(then, thenable, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »).
  3. If thenCallResult is an abrupt completion, then
    1. Let status be Call(resolvingFunctions.[[Reject]], undefined, « thenCallResult.[[Value]] »).
    2. NextJob Completion(status).
  4. NextJob Completion(thenCallResult).
Note

This Job uses the supplied thenable and its then method to resolve the given promise. This process must take place as a Job to ensure that the evaluation of the then method occurs after evaluation of any surrounding code has completed.

此Job使用提供的thenable及其then方法来解析给定的promise。 此过程必须作为job进行,以确保在执行任何周围代码完成后对then方法进行执行。

25.4.3The Promise Constructor(Promise构造函数)#

The Promise constructor is the %Promise% intrinsic object and the initial value of the Promise property of the global object. When called as a constructor it creates and initializes a new Promise object. Promise is not intended to be called as a function and will throw an exception when called in that manner.

The Promise constructor is designed to be subclassable. It may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified Promise behaviour must include a super call to the Promise constructor to create and initialize the subclass instance with the internal state necessary to support the Promise and Promise.prototype built-in methods.

Promise构造函数是%Promise%内部对象和全局对象的Promise属性的初始值。 当作为构造函数调用时,它会创建并初始化一个新的Promise对象。 Promise不打算作为函数调用,并且在以这种方式调用时会抛出异常。Promise构造函数设计为可子类化。 它可以用作类定义的extends子句中的值。 打算继承指定的Promise行为的子类构造函数必须包含对Promise构造函数的super调用,以使用支持Promise和Promise.prototype内置方法所需的内部状态创建和初始化子类实例。

继承例子:

class SubProTip extends Promise { constructor(executor, tip) { super(executor); console.log(tip); } } let subt = new SubProTip((resolve, reject) => {resolve(1);}, 2); subt.then(value => {console.log(value);})

25.4.3.1Promise ( executor )#

When the Promise function is called with argument executor, the following steps are taken:

使用参数executor调用Promise函数时,将执行以下步骤:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If IsCallable(executor) is false, throw a TypeError exception.
  3. Let promise be ? OrdinaryCreateFromConstructor(NewTarget, "%PromisePrototype%", « [[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]], [[PromiseIsHandled]] »).
  4. Set promise's [[PromiseState]] internal slot to "pending".
  5. Set promise's [[PromiseFulfillReactions]] internal slot to a new empty List.
  6. Set promise's [[PromiseRejectReactions]] internal slot to a new empty List.
  7. Set promise's [[PromiseIsHandled]] internal slot to false.
  8. Let resolvingFunctions be CreateResolvingFunctions(promise).
  9. Let completion be Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »).
  10. If completion is an abrupt completion, then
    1. Perform ? Call(resolvingFunctions.[[Reject]], undefined, « completion.[[Value]] »).
  11. Return promise.
Note

The executor argument must be a function object. It is called for initiating and reporting completion of the possibly deferred action represented by this Promise object. The executor is called with two arguments: resolve and reject. These are functions that may be used by the executor function to report eventual completion or failure of the deferred computation. Returning from the executor function does not mean that the deferred action has been completed but only that the request to eventually perform the deferred action has been accepted.

The resolve function that is passed to an executor function accepts a single argument. The executor code may eventually call the resolve function to indicate that it wishes to resolve the associated Promise object. The argument passed to the resolve function represents the eventual value of the deferred action and can be either the actual fulfillment value or another Promise object which will provide the value if it is fulfilled.

The reject function that is passed to an executor function accepts a single argument. The executor code may eventually call the reject function to indicate that the associated Promise is rejected and will never be fulfilled. The argument passed to the reject function is used as the rejection value of the promise. Typically it will be an Error object.

The resolve and reject functions passed to an executor function by the Promise constructor have the capability to actually resolve and reject the associated promise. Subclasses may have different constructor behaviour that passes in customized values for resolve and reject.

executor参数必须是函数对象。它被调用以初始化和记录由此Promise对象表示的可能延迟的操作的完成。使用两个参数调用执行程序:resolve和reject。这些函数可由执行程序函数用于报告延迟计算的最终完成或失败。从执行程序函数返回并不意味着延迟操作已经完成,而是仅表示已接受最终执行延迟操作的请求。
传递给executor函数的resolve函数接受单个参数。执行程序代码最终可以调用resolve函数来指示它希望resolve关联的Promise对象。传递给resolve函数的参数表示延迟操作的最终值,可以是实际的值,也可以是另一个如果是fulfilled,它将提供值的Promise对象。
传递给executor函数的reject函数接受单个参数。执行程序代码最终可以调用reject函数来指示相关的Promise被rejected并且永远不会是fullfilled。传递给reject函数的参数用作promise的拒绝值。通常它将是一个Error对象。
Promise构造函数传递给执行函数的resolve和reject函数具有实际resolve和reject相关promise的能力。子类可能具有不同的构造函数行为,这些行为函数传递自定义值以进行resolve和reject。

25.4.4Properties of the Promise Constructor#

The value of the [[Prototype]] internal slot of the Promise constructor is the intrinsic object %FunctionPrototype%.

The Promise constructor has the following properties:

Promise构造函数的[[Prototype]]内部槽的值是内部对象%FunctionPrototype%。
Promise构造函数具有以下属性:

25.4.4.1Promise.all ( iterable )#

The all function returns a new promise which is fulfilled with an array of fulfillment values for the passed promises, or rejects with the reason of the first passed promise that rejects. It resolves all elements of the passed iterable to promises as it runs this algorithm.

all函数返回一个新的promise,它通过传递的promise的一个数组来fulfilled实现,或者rejects第一个rejects promise的原因。 它在运行此算法时将传递的iterable的所有元素解析为promises。

  1. Let C be the this value.
  2. If Type(C) is not Object, throw a TypeError exception.
  3. Let promiseCapability be ? NewPromiseCapability(C).
  4. Let iterator be GetIterator(iterable).
  5. IfAbruptRejectPromise(iterator, promiseCapability).
  6. Let iteratorRecord be Record {[[Iterator]]: iterator, [[Done]]: false}.
  7. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
  8. If result is an abrupt completion, then
    1. If iteratorRecord.[[Done]] is false, let result be IteratorClose(iterator, result).
    2. IfAbruptRejectPromise(result, promiseCapability).
  9. Return Completion(result).
resolve: let p1 = new Promise((resolve, reject) => { setTimeout(() => { resolve(1); }, 3000); }); let p2 = new Promise((resolve, reject) => { setTimeout(() => { resolve(2); }, 4000); }); Promise.all([p1, p2]).then(res => { console.log(res); }, (err) => { console.log(err); }); 输出:[1,2] reject: let p4 = new Promise((resolve, reject) => { setTimeout(() => { resolve(1); }, 3000); }); let p5 = new Promise((resolve, reject) => { setTimeout(() => { reject(2); }, 4000); }); Promise.all([p4, p5]).then(res => { console.log(res); }, (err) => { console.log(err); }); 输出:2 Note

The all function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

all函数要求其this值为构造函数,该函数支持Promise构造函数的参数约定。

25.4.4.1.1Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability)#

When the PerformPromiseAll abstract operation is called with arguments iteratorRecord, constructor, and resultCapability, the following steps are taken:

  1. Assert: constructor is a constructor function.
  2. Assert: resultCapability is a PromiseCapability record.
  3. Let values be a new empty List.
  4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
  5. Let index be 0.
  6. Repeat
    1. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, then
      1. Set iteratorRecord.[[Done]] to true.
      2. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
      3. If remainingElementsCount.[[Value]] is 0, then
        1. Let valuesArray be CreateArrayFromList(values).
        2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
      4. Return resultCapability.[[Promise]].
    5. Let nextValue be IteratorValue(next).
    6. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
    7. ReturnIfAbrupt(nextValue).
    8. Append undefined to values.
    9. Let nextPromise be ? Invoke(constructor, "resolve", « nextValue »).
    10. Let resolveElement be a new built-in function object as defined in Promise.all Resolve Element Functions.
    11. Set the [[AlreadyCalled]] internal slot of resolveElement to a new Record {[[Value]]: false }.
    12. Set the [[Index]] internal slot of resolveElement to index.
    13. Set the [[Values]] internal slot of resolveElement to values.
    14. Set the [[Capabilities]] internal slot of resolveElement to resultCapability.
    15. Set the [[RemainingElements]] internal slot of resolveElement to remainingElementsCount.
    16. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] + 1.
    17. Perform ? Invoke(nextPromise, "then", « resolveElement, resultCapability.[[Reject]] »).
    18. Set index to index + 1.

25.4.4.1.2Promise.all Resolve Element Functions#

A Promise.all resolve element function is an anonymous built-in function that is used to resolve a specific Promise.all element. Each Promise.all resolve element function has [[Index]], [[Values]], [[Capabilities]], [[RemainingElements]], and [[AlreadyCalled]] internal slots.

When a Promise.all resolve element function F is called with argument x, the following steps are taken:

  1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
  2. If alreadyCalled.[[Value]] is true, return undefined.
  3. Set alreadyCalled.[[Value]] to true.
  4. Let index be the value of F's [[Index]] internal slot.
  5. Let values be the value of F's [[Values]] internal slot.
  6. Let promiseCapability be the value of F's [[Capabilities]] internal slot.
  7. Let remainingElementsCount be the value of F's [[RemainingElements]] internal slot.
  8. Set values[index] to x.
  9. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
  10. If remainingElementsCount.[[Value]] is 0, then
    1. Let valuesArray be CreateArrayFromList(values).
    2. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
  11. Return undefined.

The length property of a Promise.all resolve element function is 1.

25.4.4.2Promise.prototype#

The initial value of Promise.prototype is the intrinsic object %PromisePrototype%.

Promise.prototype的初始值是内部对象%PromisePrototype%。

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

25.4.4.3Promise.race ( iterable )#

The race function returns a new promise which is settled in the same way as the first passed promise to settle. It resolves all elements of the passed iterable to promises as it runs this algorithm.

race函数返回一个新的promise,其结算方式与第一个设定的promise结算方式相同。 它在运行此算法时将传递的iterable的所有元素解析为promises。

  1. Let C be the this value.
  2. If Type(C) is not Object, throw a TypeError exception.
  3. Let promiseCapability be ? NewPromiseCapability(C).
  4. Let iterator be GetIterator(iterable).
  5. IfAbruptRejectPromise(iterator, promiseCapability).
  6. Let iteratorRecord be Record {[[Iterator]]: iterator, [[Done]]: false}.
  7. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
  8. If result is an abrupt completion, then
    1. If iteratorRecord.[[Done]] is false, let result be IteratorClose(iterator, result).
    2. IfAbruptRejectPromise(result, promiseCapability).
  9. Return Completion(result).
Note 1

If the iterable argument is empty or if none of the promises in iterable ever settle then the pending promise returned by this method will never be settled.

Note 2

The race function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor. It also expects that its this value provides a resolve method.

25.4.4.3.1Runtime Semantics: PerformPromiseRace ( iteratorRecord, promiseCapability, C )#

When the PerformPromiseRace abstract operation is called with arguments iteratorRecord, promiseCapability, and C, the following steps are taken:

  1. Repeat
    1. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, then
      1. Set iteratorRecord.[[Done]] to true.
      2. Return promiseCapability.[[Promise]].
    5. Let nextValue be IteratorValue(next).
    6. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
    7. ReturnIfAbrupt(nextValue).
    8. Let nextPromise be ? Invoke(C, "resolve", « nextValue »).
    9. Perform ? Invoke(nextPromise, "then", « promiseCapability.[[Resolve]], promiseCapability.[[Reject]] »).

25.4.4.4Promise.reject ( r )#

The reject function returns a new promise rejected with the passed argument.

reject函数返回一个使用传递的参数作为拒绝状态的新promise。

  1. Let C be the this value.
  2. If Type(C) is not Object, throw a TypeError exception.
  3. Let promiseCapability be ? NewPromiseCapability(C).
  4. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »).
  5. Return promiseCapability.[[Promise]].
Note

The reject function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

reject函数希望它的this值是一个构造函数,它支持Promise构造函数的参数约定。

// 示例 let rejectP = Promise.reject('rejected!'); rejectP.then(null, err => {console.log(err);}); // 输出 'rejected!'

25.4.4.5Promise.resolve ( x )#

The resolve function returns either a new promise resolved with the passed argument, or the argument itself if the argument is a promise produced by this constructor.

resolve函数返回使用传递的参数resolve的新promise,如果参数是此构造函数生成的promise,则返回参数本身。

  1. Let C be the this value.
  2. If Type(C) is not Object, throw a TypeError exception.
  3. If IsPromise(x) is true, then
    1. Let xConstructor be ? Get(x, "constructor").
    2. If SameValue(xConstructor, C) is true, return x.
  4. Let promiseCapability be ? NewPromiseCapability(C).
  5. Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »).
  6. Return promiseCapability.[[Promise]].
Note

The resolve function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

resolve函数希望它的this值是一个构造函数,它支持Promise构造函数的参数约定。

25.4.4.6get Promise [ @@species ]#

Promise[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

Promise [@@ species]是一个访问器属性,其set访问器函数未定义。 它的get访问器函数执行以下步骤:

  1. Return the this value.

The value of the name property of this function is "get [Symbol.species]".

此函数的name属性的值为“get [Symbol.species]”。

Note

Promise prototype methods normally use their this object's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its @@species property.

Promise原型方法通常使用它们的this对象的构造函数来创建衍生对象。 但是,子类构造函数可以通过重新定义其@@ species属性来覆盖该默认行为。

class Ps extends Promise { static get [Symbol.species]() { return Promise; } } let ps1 = new Ps(() => {}, null); ps1 instanceof Ps; // true ps1.then(() => {}) instanceof Ps // false // 调用then的衍生对象构造函数指向了Promise

25.4.5Properties of the Promise Prototype Object(Promise原型对象的属性)#

The Promise prototype object is the intrinsic object %PromisePrototype%. The value of the [[Prototype]] internal slot of the Promise prototype object is the intrinsic object %ObjectPrototype%. The Promise prototype object is an ordinary object. It does not have a [[PromiseState]] internal slot or any of the other internal slots of Promise instances.

Promise原型对象是内部对象%PromisePrototype%。 Promise原型对象的[[Prototype]]内部槽的值是内部对象%ObjectPrototype%。 Promise原型对象是一个普通的对象。 它没有[[PromiseState]]内部插槽或Promise实例的任何其他内部插槽。

25.4.5.1Promise.prototype.catch ( onRejected )#

When the catch method is called with argument onRejected, the following steps are taken:

  1. Let promise be the this value.
  2. Return ? Invoke(promise, "then", « undefined, onRejected »).

其实就是then方法then(fun, undefined)的简写

25.4.5.2Promise.prototype.constructor#

The initial value of Promise.prototype.constructor is the intrinsic object %Promise%.

Promise.prototype.constructor的初始值是内部对象%Promise%。

25.4.5.3Promise.prototype.then ( onFulfilled, onRejected )#

When the then method is called with arguments onFulfilled and onRejected, the following steps are taken:

  1. Let promise be the this value.
  2. If IsPromise(promise) is false, throw a TypeError exception.
  3. Let C be ? SpeciesConstructor(promise, %Promise%).
  4. Let resultCapability be ? NewPromiseCapability(C).
  5. Return PerformPromiseThen(promise, onFulfilled, onRejected, resultCapability).
let pro2 = new Promise((resolve, reject) => { setTimeout(() => { resolve(1); }, 5000); }); pro2.then(res => { console.log(res); }, undefined);

25.4.5.3.1PerformPromiseThen ( promise, onFulfilled, onRejected, resultCapability )#

The abstract operation PerformPromiseThen performs the “then” operation on promise using onFulfilled and onRejected as its settlement actions. The result is resultCapability's promise.

抽象操作PerformPromiseThen使用onFulfilled和onRejected作为其结算操作,对promise进行“then”操作。 结果是resultCapability的promise。

  1. Assert: IsPromise(promise) is true.
  2. Assert: resultCapability is a PromiseCapability record.
  3. If IsCallable(onFulfilled) is false, then
    1. Let onFulfilled be "Identity".
  4. If IsCallable(onRejected) is false, then
    1. Let onRejected be "Thrower".
  5. Let fulfillReaction be the PromiseReaction { [[Capabilities]]: resultCapability, [[Handler]]: onFulfilled }.
  6. Let rejectReaction be the PromiseReaction { [[Capabilities]]: resultCapability, [[Handler]]: onRejected}.
  7. If the value of promise's [[PromiseState]] internal slot is "pending", then
    1. Append fulfillReaction as the last element of the List that is the value of promise's [[PromiseFulfillReactions]] internal slot.
    2. Append rejectReaction as the last element of the List that is the value of promise's [[PromiseRejectReactions]] internal slot.
  8. Else if the value of promise's [[PromiseState]] internal slot is "fulfilled", then
    1. Let value be the value of promise's [[PromiseResult]] internal slot.
    2. Perform EnqueueJob("PromiseJobs", PromiseReactionJob, « fulfillReaction, value »).
  9. Else,
    1. Assert: The value of promise's [[PromiseState]] internal slot is "rejected".
    2. Let reason be the value of promise's [[PromiseResult]] internal slot.
    3. If the value of promise's [[PromiseIsHandled]] internal slot is false, perform HostPromiseRejectionTracker(promise, "handle").
    4. Perform EnqueueJob("PromiseJobs", PromiseReactionJob, « rejectReaction, reason »).
  10. Set promise's [[PromiseIsHandled]] internal slot to true.
  11. Return resultCapability.[[Promise]].

25.4.5.4Promise.prototype [ @@toStringTag ]#

The initial value of the @@toStringTag property is the String value "Promise".

@@ toStringTag属性的初始值是String值“Promise”。

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

pro2.toString() // "[object Promise]"

25.4.6Properties of Promise Instances#

Promise instances are ordinary objects that inherit properties from the Promise prototype object (the intrinsic, %PromisePrototype%). Promise instances are initially created with the internal slots described in Table 60.

Promise实例是从Promise原型对象(内在的%PromisePrototype%)继承属性的普通对象。 最初使用表60中描述的内部插槽创建Promise实例。

Table 60: Internal Slots of Promise Instances
Internal Slot Description
[[PromiseState]] A String value that governs how a promise will react to incoming calls to its then method. The possible values are: "pending", "fulfilled", and "rejected".
一个String值,用于控制promise对其then方法的传入调用的响应方式。 可能的值包括: "pending", "fulfilled", "rejected".
[[PromiseResult]] The value with which the promise has been fulfilled or rejected, if any. Only meaningful if [[PromiseState]] is not "pending".
promise fulfilled或rejected的值(如果有)。 只有在[[PromiseState]]不是“pending”时才有意义。
[[PromiseFulfillReactions]] A List of PromiseReaction records to be processed when/if the promise transitions from the "pending" state to the "fulfilled" state.
当/如果promise从“pending”状态转换到“fulfilled”状态时要处理的PromiseReaction记录列表。
[[PromiseRejectReactions]] A List of PromiseReaction records to be processed when/if the promise transitions from the "pending" state to the "rejected" state.
当/如果promise从“pending”状态转换为“reject”状态时要处理的PromiseReaction记录列表。
[[PromiseIsHandled]] A boolean indicating whether the promise has ever had a fulfillment or rejection handler; used in unhandled rejection tracking.
一个布尔值,表示promise是否曾经有过fulfilled或reject处理程序; 用于未处理的rejection跟踪。

26Reflection#

26.1The Reflect Object#

The Reflect object is the %Reflect% intrinsic object and the initial value of the Reflect property of the global object. The Reflect object is an ordinary object.

The value of the [[Prototype]] internal slot of the Reflect object is the intrinsic object %ObjectPrototype%.

The Reflect object is not a function object. It does not have a [[Construct]] internal method; it is not possible to use the Reflect object as a constructor with the new operator. The Reflect object also does not have a [[Call]] internal method; it is not possible to invoke the Reflect object as a function.

26.1.1Reflect.apply ( target, thisArgument, argumentsList )#

When the apply function is called with arguments target, thisArgument, and argumentsList, the following steps are taken:

  1. If IsCallable(target) is false, throw a TypeError exception.
  2. Let args be ? CreateListFromArrayLike(argumentsList).
  3. Perform PrepareForTailCall().
  4. Return ? Call(target, thisArgument, args).

26.1.2Reflect.construct ( target, argumentsList [ , newTarget ] )#

When the construct function is called with arguments target, argumentsList, and newTarget, the following steps are taken:

  1. If IsConstructor(target) is false, throw a TypeError exception.
  2. If newTarget is not present, let newTarget be target.
  3. Else, if IsConstructor(newTarget) is false, throw a TypeError exception.
  4. Let args be ? CreateListFromArrayLike(argumentsList).
  5. Return ? Construct(target, args, newTarget).

26.1.3Reflect.defineProperty ( target, propertyKey, attributes )#

When the defineProperty function is called with arguments target, propertyKey, and attributes, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. Let desc be ? ToPropertyDescriptor(attributes).
  4. Return ? target.[[DefineOwnProperty]](key, desc).

26.1.4Reflect.deleteProperty ( target, propertyKey )#

When the deleteProperty function is called with arguments target and propertyKey, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. Return ? target.[[Delete]](key).

26.1.5Reflect.get ( target, propertyKey [ , receiver ])#

When the get function is called with arguments target, propertyKey, and receiver, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. If receiver is not present, then
    1. Let receiver be target.
  4. Return ? target.[[Get]](key, receiver).

26.1.6Reflect.getOwnPropertyDescriptor ( target, propertyKey )#

When the getOwnPropertyDescriptor function is called with arguments target and propertyKey, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. Let desc be ? target.[[GetOwnProperty]](key).
  4. Return FromPropertyDescriptor(desc).

26.1.7Reflect.getPrototypeOf ( target )#

When the getPrototypeOf function is called with argument target, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. Return ? target.[[GetPrototypeOf]]().

26.1.8Reflect.has ( target, propertyKey )#

When the has function is called with arguments target and propertyKey, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. Return ? target.[[HasProperty]](key).

26.1.9Reflect.isExtensible (target)#

When the isExtensible function is called with argument target, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. Return ? target.[[IsExtensible]]().

26.1.10Reflect.ownKeys ( target )#

When the ownKeys function is called with argument target, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. Let keys be ? target.[[OwnPropertyKeys]]().
  3. Return CreateArrayFromList(keys).

26.1.11Reflect.preventExtensions ( target )#

When the preventExtensions function is called with argument target, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. Return ? target.[[PreventExtensions]]().

26.1.12Reflect.set ( target, propertyKey, V [ , receiver ] )#

When the set function is called with arguments target, V, propertyKey, and receiver, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. If receiver is not present, then
    1. Let receiver be target.
  4. Return ? target.[[Set]](key, V, receiver).

26.1.13Reflect.setPrototypeOf ( target, proto )#

When the setPrototypeOf function is called with arguments target and proto, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. If Type(proto) is not Object and proto is not null, throw a TypeError exception.
  3. Return ? target.[[SetPrototypeOf]](proto).

26.2Proxy Objects#

26.2.1The Proxy Constructor#

The Proxy constructor is the %Proxy% intrinsic object and the initial value of the Proxy property of the global object. When called as a constructor it creates and initializes a new proxy exotic object. Proxy is not intended to be called as a function and will throw an exception when called in that manner.

26.2.1.1Proxy ( target, handler )#

When Proxy is called with arguments target and handler performs the following steps:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Return ? ProxyCreate(target, handler).

26.2.2Properties of the Proxy Constructor#

The value of the [[Prototype]] internal slot of the Proxy constructor is the intrinsic object %FunctionPrototype%.

The Proxy constructor does not have a prototype property because proxy exotic objects do not have a [[Prototype]] internal slot that requires initialization.

The Proxy constructor has the following properties:

26.2.2.1Proxy.revocable ( target, handler )#

The Proxy.revocable function is used to create a revocable Proxy object. When Proxy.revocable is called with arguments target and handler, the following steps are taken:

  1. Let p be ? ProxyCreate(target, handler).
  2. Let revoker be a new built-in function object as defined in 26.2.2.1.1.
  3. Set the [[RevocableProxy]] internal slot of revoker to p.
  4. Let result be ObjectCreate(%ObjectPrototype%).
  5. Perform CreateDataProperty(result, "proxy", p).
  6. Perform CreateDataProperty(result, "revoke", revoker).
  7. Return result.

26.2.2.1.1Proxy Revocation Functions#

A Proxy revocation function is an anonymous function that has the ability to invalidate a specific Proxy object.

Each Proxy revocation function has a [[RevocableProxy]] internal slot.

When a Proxy revocation function, F, is called, the following steps are taken:

  1. Let p be the value of F's [[RevocableProxy]] internal slot.
  2. If p is null, return undefined.
  3. Set the value of F's [[RevocableProxy]] internal slot to null.
  4. Assert: p is a Proxy object.
  5. Set the [[ProxyTarget]] internal slot of p to null.
  6. Set the [[ProxyHandler]] internal slot of p to null.
  7. Return undefined.

The length property of a Proxy revocation function is 0.

26.3Module Namespace Objects#

A Module Namespace Object is a module namespace exotic object that provides runtime property-based access to a module's exported bindings. There is no constructor function for Module Namespace Objects. Instead, such an object is created for each module that is imported by an ImportDeclaration that includes a NameSpaceImport.

In addition to the properties specified in 9.4.6 each Module Namespace Object has the following own properties:

26.3.1@@toStringTag#

The initial value of the @@toStringTag property is the String value "Module".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

26.3.2[ @@iterator ] ( )#

When the @@iterator method is called with no arguments, the following steps are taken:

  1. Let N be the this value.
  2. If N is not a module namespace exotic object, throw a TypeError exception.
  3. Let exports be the value of N's [[Exports]] internal slot.
  4. Return ! CreateListIterator(exports).

The value of the name property of this function is "[Symbol.iterator]".

AGrammar Summary#

A.1Lexical Grammar#

SourceCharacter::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 WhiteSpace::<TAB> <VT> <FF> <SP> <NBSP> <ZWNBSP> <USP> LineTerminator::<LF> <CR> <LS> <PS> LineTerminatorSequence::<LF> <CR>[lookahead ≠ <LF>] <LS> <PS> <CR><LF> Comment::MultiLineComment SingleLineComment MultiLineComment::/*MultiLineCommentCharsopt*/ MultiLineCommentChars::MultiLineNotAsteriskCharMultiLineCommentCharsopt *PostAsteriskCommentCharsopt PostAsteriskCommentChars::MultiLineNotForwardSlashOrAsteriskCharMultiLineCommentCharsopt *PostAsteriskCommentCharsopt MultiLineNotAsteriskChar::SourceCharacterbut not * MultiLineNotForwardSlashOrAsteriskChar::SourceCharacterbut not one of / or * SingleLineComment:://SingleLineCommentCharsopt SingleLineCommentChars::SingleLineCommentCharSingleLineCommentCharsopt SingleLineCommentChar::SourceCharacterbut not LineTerminator CommonToken::IdentifierName Punctuator NumericLiteral StringLiteral Template IdentifierName::IdentifierStart IdentifierNameIdentifierPart IdentifierStart::UnicodeIDStart $ _ \UnicodeEscapeSequence IdentifierPart::UnicodeIDContinue $ _ \UnicodeEscapeSequence <ZWNJ> <ZWJ> UnicodeIDStart::any Unicode code point with the Unicode property “ID_Start” UnicodeIDContinue::any Unicode code point with the Unicode property “ID_Continue” ReservedWord::Keyword FutureReservedWord NullLiteral BooleanLiteral Keyword::one ofbreakdointypeofcaseelseinstanceofvarcatchexportnewvoidclassextendsreturnwhileconstfinallysuperwithcontinueforswitchyielddebuggerfunctionthisdefaultifthrowdeleteimporttry FutureReservedWord::enum await

await is only treated as a FutureReservedWord when Module is the goal symbol of the syntactic grammar.

The following tokens are also considered to be FutureReservedWords when parsing strict mode code:

implements  package  protected
interface  private  public

 

Punctuator::one of{()[]....;,<><=>===!====!==+-*%++--<<>>>>>&|^!~&&||?:=+=-=*=%=<<=>>=>>>=&=|=^==>****= DivPunctuator::/ /= RightBracePunctuator::} NullLiteral::null BooleanLiteral::true false NumericLiteral::DecimalLiteral BinaryIntegerLiteral OctalIntegerLiteral HexIntegerLiteral DecimalLiteral::DecimalIntegerLiteral.DecimalDigitsoptExponentPartopt .DecimalDigitsExponentPartopt DecimalIntegerLiteralExponentPartopt DecimalIntegerLiteral::0 NonZeroDigitDecimalDigitsopt DecimalDigits::DecimalDigit DecimalDigitsDecimalDigit DecimalDigit::one of0123456789 NonZeroDigit::one of123456789 ExponentPart::ExponentIndicatorSignedInteger ExponentIndicator::one ofeE SignedInteger::DecimalDigits +DecimalDigits -DecimalDigits BinaryIntegerLiteral::0bBinaryDigits 0BBinaryDigits BinaryDigits::BinaryDigit BinaryDigitsBinaryDigit BinaryDigit::one of01 OctalIntegerLiteral::0oOctalDigits 0OOctalDigits OctalDigits::OctalDigit OctalDigitsOctalDigit OctalDigit::one of01234567 HexIntegerLiteral::0xHexDigits 0XHexDigits HexDigits::HexDigit HexDigitsHexDigit HexDigit::one of0123456789abcdefABCDEF StringLiteral::"DoubleStringCharactersopt" 'SingleStringCharactersopt' DoubleStringCharacters::DoubleStringCharacterDoubleStringCharactersopt SingleStringCharacters::SingleStringCharacterSingleStringCharactersopt DoubleStringCharacter::SourceCharacterbut not one of " or \ or LineTerminator \EscapeSequence LineContinuation SingleStringCharacter::SourceCharacterbut not one of ' or \ or LineTerminator \EscapeSequence LineContinuation LineContinuation::\LineTerminatorSequence EscapeSequence::CharacterEscapeSequence 0[lookahead ∉ DecimalDigit] HexEscapeSequence UnicodeEscapeSequence CharacterEscapeSequence::SingleEscapeCharacter NonEscapeCharacter SingleEscapeCharacter::one of'"\bfnrtv NonEscapeCharacter::SourceCharacterbut not one of EscapeCharacter or LineTerminator EscapeCharacter::SingleEscapeCharacter DecimalDigit x u HexEscapeSequence::xHexDigitHexDigit UnicodeEscapeSequence::uHex4Digits u{HexDigits} Hex4Digits::HexDigitHexDigitHexDigitHexDigit RegularExpressionLiteral::/RegularExpressionBody/RegularExpressionFlags RegularExpressionBody::RegularExpressionFirstCharRegularExpressionChars RegularExpressionChars::[empty] RegularExpressionCharsRegularExpressionChar RegularExpressionFirstChar::RegularExpressionNonTerminatorbut not one of * or \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionChar::RegularExpressionNonTerminatorbut not one of \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionBackslashSequence::\RegularExpressionNonTerminator RegularExpressionNonTerminator::SourceCharacterbut not LineTerminator RegularExpressionClass::[RegularExpressionClassChars] RegularExpressionClassChars::[empty] RegularExpressionClassCharsRegularExpressionClassChar RegularExpressionClassChar::RegularExpressionNonTerminatorbut not one of ] or \ RegularExpressionBackslashSequence RegularExpressionFlags::[empty] RegularExpressionFlagsIdentifierPart Template::NoSubstitutionTemplate TemplateHead NoSubstitutionTemplate::`TemplateCharactersopt` TemplateHead::`TemplateCharactersopt${ TemplateSubstitutionTail::TemplateMiddle TemplateTail TemplateMiddle::}TemplateCharactersopt${ TemplateTail::}TemplateCharactersopt` TemplateCharacters::TemplateCharacterTemplateCharactersopt TemplateCharacter::$[lookahead ≠ {] \EscapeSequence LineContinuation LineTerminatorSequence SourceCharacterbut not one of ` or \ or $ or LineTerminator

A.2Expressions#

IdentifierReference[Yield]:Identifier [~Yield]yield BindingIdentifier[Yield]:Identifier [~Yield]yield Identifier:IdentifierNamebut not ReservedWord LabelIdentifier[Yield]:Identifier [~Yield]yield PrimaryExpression[Yield]:this IdentifierReference[?Yield] Literal ArrayLiteral[?Yield] ObjectLiteral[?Yield] FunctionExpression ClassExpression[?Yield] GeneratorExpression RegularExpressionLiteral TemplateLiteral[?Yield] CoverParenthesizedExpressionAndArrowParameterList[?Yield] CoverParenthesizedExpressionAndArrowParameterList[Yield]:(Expression[In, ?Yield]) () (...BindingIdentifier[?Yield]) (...BindingPattern[?Yield]) (Expression[In, ?Yield],...BindingIdentifier[?Yield]) (Expression[In, ?Yield],...BindingPattern[?Yield])

When processing the production PrimaryExpression[Yield]:CoverParenthesizedExpressionAndArrowParameterList[?Yield] the interpretation of CoverParenthesizedExpressionAndArrowParameterList is refined using the following grammar:

ParenthesizedExpression[Yield]:(Expression[In, ?Yield])

 

Literal:NullLiteral BooleanLiteral NumericLiteral StringLiteral ArrayLiteral[Yield]:[Elisionopt] [ElementList[?Yield]] [ElementList[?Yield],Elisionopt] ElementList[Yield]:ElisionoptAssignmentExpression[In, ?Yield] ElisionoptSpreadElement[?Yield] ElementList[?Yield],ElisionoptAssignmentExpression[In, ?Yield] ElementList[?Yield],ElisionoptSpreadElement[?Yield] Elision:, Elision, SpreadElement[Yield]:...AssignmentExpression[In, ?Yield] ObjectLiteral[Yield]:{} {PropertyDefinitionList[?Yield]} {PropertyDefinitionList[?Yield],} PropertyDefinitionList[Yield]:PropertyDefinition[?Yield] PropertyDefinitionList[?Yield],PropertyDefinition[?Yield] PropertyDefinition[Yield]:IdentifierReference[?Yield] CoverInitializedName[?Yield] PropertyName[?Yield]:AssignmentExpression[In, ?Yield] MethodDefinition[?Yield] PropertyName[Yield]:LiteralPropertyName ComputedPropertyName[?Yield] LiteralPropertyName:IdentifierName StringLiteral NumericLiteral ComputedPropertyName[Yield]:[AssignmentExpression[In, ?Yield]] CoverInitializedName[Yield]:IdentifierReference[?Yield]Initializer[In, ?Yield] Initializer[In, Yield]:=AssignmentExpression[?In, ?Yield] TemplateLiteral[Yield]:NoSubstitutionTemplate TemplateHeadExpression[In, ?Yield]TemplateSpans[?Yield] TemplateSpans[Yield]:TemplateTail TemplateMiddleList[?Yield]TemplateTail TemplateMiddleList[Yield]:TemplateMiddleExpression[In, ?Yield] TemplateMiddleList[?Yield]TemplateMiddleExpression[In, ?Yield] MemberExpression[Yield]:PrimaryExpression[?Yield] MemberExpression[?Yield][Expression[In, ?Yield]] MemberExpression[?Yield].IdentifierName MemberExpression[?Yield]TemplateLiteral[?Yield] SuperProperty[?Yield] MetaProperty newMemberExpression[?Yield]Arguments[?Yield] SuperProperty[Yield]:super[Expression[In, ?Yield]] super.IdentifierName MetaProperty:NewTarget NewTarget:new.target NewExpression[Yield]:MemberExpression[?Yield] newNewExpression[?Yield] CallExpression[Yield]:MemberExpression[?Yield]Arguments[?Yield] SuperCall[?Yield] CallExpression[?Yield]Arguments[?Yield] CallExpression[?Yield][Expression[In, ?Yield]] CallExpression[?Yield].IdentifierName CallExpression[?Yield]TemplateLiteral[?Yield] SuperCall[Yield]:superArguments[?Yield] Arguments[Yield]:() (ArgumentList[?Yield]) ArgumentList[Yield]:AssignmentExpression[In, ?Yield] ...AssignmentExpression[In, ?Yield] ArgumentList[?Yield],AssignmentExpression[In, ?Yield] ArgumentList[?Yield],...AssignmentExpression[In, ?Yield] LeftHandSideExpression[Yield]:NewExpression[?Yield] CallExpression[?Yield] UpdateExpression[Yield]:LeftHandSideExpression[?Yield][no LineTerminator here]++ LeftHandSideExpression[?Yield][no LineTerminator here]-- UnaryExpression[Yield]:UpdateExpression[?Yield] deleteUnaryExpression[?Yield] voidUnaryExpression[?Yield] typeofUnaryExpression[?Yield] +UnaryExpression[?Yield] -UnaryExpression[?Yield] ~UnaryExpression[?Yield] !UnaryExpression[?Yield] ExponentiationExpression[Yield]:UnaryExpression[?Yield] UpdateExpression[?Yield]**ExponentiationExpression[?Yield] MultiplicativeExpression[Yield]:ExponentiationExpression[?Yield] MultiplicativeExpression[?Yield]MultiplicativeOperatorExponentiationExpression[?Yield] MultiplicativeOperator:one of*/% AdditiveExpression[Yield]:MultiplicativeExpression[?Yield] AdditiveExpression[?Yield]+MultiplicativeExpression[?Yield] AdditiveExpression[?Yield]-MultiplicativeExpression[?Yield] ShiftExpression[Yield]:AdditiveExpression[?Yield] ShiftExpression[?Yield]<<AdditiveExpression[?Yield] ShiftExpression[?Yield]>>AdditiveExpression[?Yield] ShiftExpression[?Yield]>>>AdditiveExpression[?Yield] RelationalExpression[In, Yield]:ShiftExpression[?Yield] RelationalExpression[?In, ?Yield]<ShiftExpression[?Yield] RelationalExpression[?In, ?Yield]>ShiftExpression[?Yield] RelationalExpression[?In, ?Yield]<=ShiftExpression[?Yield] RelationalExpression[?In, ?Yield]>=ShiftExpression[?Yield] RelationalExpression[?In, ?Yield]instanceofShiftExpression[?Yield] [+In]RelationalExpression[In, ?Yield]inShiftExpression[?Yield] EqualityExpression[In, Yield]:RelationalExpression[?In, ?Yield] EqualityExpression[?In, ?Yield]==RelationalExpression[?In, ?Yield] EqualityExpression[?In, ?Yield]!=RelationalExpression[?In, ?Yield] EqualityExpression[?In, ?Yield]===RelationalExpression[?In, ?Yield] EqualityExpression[?In, ?Yield]!==RelationalExpression[?In, ?Yield] BitwiseANDExpression[In, Yield]:EqualityExpression[?In, ?Yield] BitwiseANDExpression[?In, ?Yield]&EqualityExpression[?In, ?Yield] BitwiseXORExpression[In, Yield]:BitwiseANDExpression[?In, ?Yield] BitwiseXORExpression[?In, ?Yield]^BitwiseANDExpression[?In, ?Yield] BitwiseORExpression[In, Yield]:BitwiseXORExpression[?In, ?Yield] BitwiseORExpression[?In, ?Yield]|BitwiseXORExpression[?In, ?Yield] LogicalANDExpression[In, Yield]:BitwiseORExpression[?In, ?Yield] LogicalANDExpression[?In, ?Yield]&&BitwiseORExpression[?In, ?Yield] LogicalORExpression[In, Yield]:LogicalANDExpression[?In, ?Yield] LogicalORExpression[?In, ?Yield]||LogicalANDExpression[?In, ?Yield] ConditionalExpression[In, Yield]:LogicalORExpression[?In, ?Yield] LogicalORExpression[?In, ?Yield]?AssignmentExpression[In, ?Yield]:AssignmentExpression[?In, ?Yield] AssignmentExpression[In, Yield]:ConditionalExpression[?In, ?Yield] [+Yield]YieldExpression[?In] ArrowFunction[?In, ?Yield] LeftHandSideExpression[?Yield]=AssignmentExpression[?In, ?Yield] LeftHandSideExpression[?Yield]AssignmentOperatorAssignmentExpression[?In, ?Yield]

In certain circumstances when processing the production AssignmentExpression[In, Yield]:LeftHandSideExpression[?Yield]=AssignmentExpression[?In, ?Yield] the following grammar is used to refine the interpretation of LeftHandSideExpression:

AssignmentPattern[Yield]:ObjectAssignmentPattern[?Yield] ArrayAssignmentPattern[?Yield] ObjectAssignmentPattern[Yield]:{} {AssignmentPropertyList[?Yield]} {AssignmentPropertyList[?Yield],} ArrayAssignmentPattern[Yield]:[ElisionoptAssignmentRestElement[?Yield]opt] [AssignmentElementList[?Yield]] [AssignmentElementList[?Yield],ElisionoptAssignmentRestElement[?Yield]opt] AssignmentPropertyList[Yield]:AssignmentProperty[?Yield] AssignmentPropertyList[?Yield],AssignmentProperty[?Yield] AssignmentElementList[Yield]:AssignmentElisionElement[?Yield] AssignmentElementList[?Yield],AssignmentElisionElement[?Yield] AssignmentElisionElement[Yield]:ElisionoptAssignmentElement[?Yield] AssignmentProperty[Yield]:IdentifierReference[?Yield]Initializer[In, ?Yield]opt PropertyName[?Yield]:AssignmentElement[?Yield] AssignmentElement[Yield]:DestructuringAssignmentTarget[?Yield]Initializer[In, ?Yield]opt AssignmentRestElement[Yield]:...DestructuringAssignmentTarget[?Yield] DestructuringAssignmentTarget[Yield]:LeftHandSideExpression[?Yield]

 

AssignmentOperator:one of*=/=%=+=-=<<=>>=>>>=&=^=|=**= Expression[In, Yield]:AssignmentExpression[?In, ?Yield] Expression[?In, ?Yield],AssignmentExpression[?In, ?Yield]

A.3Statements(声明)#

Statement[Yield, Return]:BlockStatement[?Yield, ?Return] VariableStatement[?Yield] EmptyStatement ExpressionStatement[?Yield] IfStatement[?Yield, ?Return] BreakableStatement[?Yield, ?Return] ContinueStatement[?Yield] BreakStatement[?Yield] [+Return]ReturnStatement[?Yield] WithStatement[?Yield, ?Return] LabelledStatement[?Yield, ?Return] ThrowStatement[?Yield] TryStatement[?Yield, ?Return] DebuggerStatement Declaration[Yield]:HoistableDeclaration[?Yield] ClassDeclaration[?Yield] LexicalDeclaration[In, ?Yield] HoistableDeclaration[Yield, Default]:FunctionDeclaration[?Yield, ?Default] GeneratorDeclaration[?Yield, ?Default] BreakableStatement[Yield, Return]:IterationStatement[?Yield, ?Return] SwitchStatement[?Yield, ?Return] BlockStatement[Yield, Return]:Block[?Yield, ?Return] Block:{StatementList} StatementList[Yield, Return]:StatementListItem[?Yield, ?Return] StatementList[?Yield, ?Return]StatementListItem[?Yield, ?Return] StatementListItem[Yield, Return]:Statement[?Yield, ?Return] Declaration[?Yield] LexicalDeclaration[In, Yield]:LetOrConstBindingList[?In, ?Yield]; LetOrConst:let const BindingList[In, Yield]:LexicalBinding[?In, ?Yield] BindingList[?In, ?Yield],LexicalBinding[?In, ?Yield] LexicalBinding[In, Yield]:BindingIdentifier[?Yield]Initializer[?In, ?Yield]opt BindingPattern[?Yield]Initializer[?In, ?Yield] VariableStatement[Yield]:varVariableDeclarationList[In, ?Yield]; VariableDeclarationList[In, Yield]:VariableDeclaration[?In, ?Yield] VariableDeclarationList[?In, ?Yield],VariableDeclaration[?In, ?Yield] VariableDeclaration[In, Yield]:BindingIdentifier[?Yield]Initializer[?In, ?Yield]opt BindingPattern[?Yield]Initializer[?In, ?Yield] BindingPattern[Yield]:ObjectBindingPattern[?Yield] ArrayBindingPattern[?Yield] ObjectBindingPattern[Yield]:{} {BindingPropertyList[?Yield]} {BindingPropertyList[?Yield],} ArrayBindingPattern[Yield]:[ElisionoptBindingRestElement[?Yield]opt] [BindingElementList[?Yield]] [BindingElementList[?Yield],ElisionoptBindingRestElement[?Yield]opt] BindingPropertyList[Yield]:BindingProperty[?Yield] BindingPropertyList[?Yield],BindingProperty[?Yield] BindingElementList[Yield]:BindingElisionElement[?Yield] BindingElementList[?Yield],BindingElisionElement[?Yield] BindingElisionElement[Yield]:ElisionoptBindingElement[?Yield] BindingProperty[Yield]:SingleNameBinding[?Yield] PropertyName[?Yield]:BindingElement[?Yield] BindingElement[Yield]:SingleNameBinding[?Yield] BindingPattern[?Yield]Initializer[In, ?Yield]opt SingleNameBinding[Yield]:BindingIdentifier[?Yield]Initializer[In, ?Yield]opt BindingRestElement[Yield]:...BindingIdentifier[?Yield] ...BindingPattern[?Yield] EmptyStatement:; ExpressionStatement[Yield]:[lookahead ∉ { {, function, class, let [ }]Expression[In, ?Yield]; IfStatement[Yield, Return]:if(Expression[In, ?Yield])Statement[?Yield, ?Return]elseStatement[?Yield, ?Return] if(Expression[In, ?Yield])Statement[?Yield, ?Return] IterationStatement[Yield, Return]:doStatement[?Yield, ?Return]while(Expression[In, ?Yield]); while(Expression[In, ?Yield])Statement[?Yield, ?Return] for([lookahead ∉ { let [ }]Expression[?Yield]opt;Expression[In, ?Yield]opt;Expression[In, ?Yield]opt)Statement[?Yield, ?Return] for(varVariableDeclarationList[?Yield];Expression[In, ?Yield]opt;Expression[In, ?Yield]opt)Statement[?Yield, ?Return] for(LexicalDeclaration[?Yield]Expression[In, ?Yield]opt;Expression[In, ?Yield]opt)Statement[?Yield, ?Return] for([lookahead ∉ { let [ }]LeftHandSideExpression[?Yield]inExpression[In, ?Yield])Statement[?Yield, ?Return] for(varForBinding[?Yield]inExpression[In, ?Yield])Statement[?Yield, ?Return] for(ForDeclaration[?Yield]inExpression[In, ?Yield])Statement[?Yield, ?Return] for([lookahead ≠ let]LeftHandSideExpression[?Yield]ofAssignmentExpression[In, ?Yield])Statement[?Yield, ?Return] for(varForBinding[?Yield]ofAssignmentExpression[In, ?Yield])Statement[?Yield, ?Return] for(ForDeclaration[?Yield]ofAssignmentExpression[In, ?Yield])Statement[?Yield, ?Return] ForDeclaration[Yield]:LetOrConstForBinding[?Yield] ForBinding[Yield]:BindingIdentifier[?Yield] BindingPattern[?Yield] ContinueStatement[Yield]:continue; continue[no LineTerminator here]LabelIdentifier[?Yield]; BreakStatement[Yield]:break; break[no LineTerminator here]LabelIdentifier[?Yield]; ReturnStatement[Yield]:return; return[no LineTerminator here]Expression[In, ?Yield]; WithStatement[Yield, Return]:with(Expression[In, ?Yield])Statement[?Yield, ?Return] SwitchStatement[Yield, Return]:switch(Expression[In, ?Yield])CaseBlock[?Yield, ?Return] CaseBlock[Yield, Return]:{CaseClauses[?Yield, ?Return]opt} {CaseClauses[?Yield, ?Return]optDefaultClause[?Yield, ?Return]CaseClauses[?Yield, ?Return]opt} CaseClauses[Yield, Return]:CaseClause[?Yield, ?Return] CaseClauses[?Yield, ?Return]CaseClause[?Yield, ?Return] CaseClause[Yield, Return]:caseExpression[In, ?Yield]:StatementList[?Yield, ?Return]opt DefaultClause[Yield, Return]:default:StatementList[?Yield, ?Return]opt LabelledStatement[Yield, Return]:LabelIdentifier[?Yield]:LabelledItem[?Yield, ?Return] LabelledItem[Yield, Return]:Statement[?Yield, ?Return] FunctionDeclaration[?Yield] ThrowStatement[Yield]:throw[no LineTerminator here]Expression[In, ?Yield]; TryStatement[Yield, Return]:tryBlock[?Yield, ?Return]Catch[?Yield, ?Return] tryBlock[?Yield, ?Return]Finally[?Yield, ?Return] tryBlock[?Yield, ?Return]Catch[?Yield, ?Return]Finally[?Yield, ?Return] Catch[Yield, Return]:catch(CatchParameter[?Yield])Block[?Yield, ?Return] Finally[Yield, Return]:finallyBlock[?Yield, ?Return] CatchParameter[Yield]:BindingIdentifier[?Yield] BindingPattern[?Yield] DebuggerStatement:debugger;

A.4Functions and Classes#

FunctionDeclaration[Yield, Default]:functionBindingIdentifier[?Yield](FormalParameters){FunctionBody} [+Default]function(FormalParameters){FunctionBody} FunctionExpression:functionBindingIdentifieropt(FormalParameters){FunctionBody} StrictFormalParameters[Yield]:FormalParameters[?Yield] FormalParameters[Yield]:[empty] FormalParameterList[?Yield] FormalParameterList[Yield]:FunctionRestParameter[?Yield] FormalsList[?Yield] FormalsList[?Yield],FunctionRestParameter[?Yield] FormalsList[Yield]:FormalParameter[?Yield] FormalsList[?Yield],FormalParameter[?Yield] FunctionRestParameter[Yield]:BindingRestElement[?Yield] FormalParameter[Yield]:BindingElement[?Yield] FunctionBody[Yield]:FunctionStatementList[?Yield] FunctionStatementList[Yield]:StatementList[?Yield, Return]opt ArrowFunction[In, Yield]:ArrowParameters[?Yield][no LineTerminator here]=>ConciseBody[?In] ArrowParameters[Yield]:BindingIdentifier[?Yield] CoverParenthesizedExpressionAndArrowParameterList[?Yield] ConciseBody[In]:[lookahead ≠ {]AssignmentExpression[?In] {FunctionBody}

When the production ArrowParameters[Yield]:CoverParenthesizedExpressionAndArrowParameterList[?Yield] is recognized the following grammar is used to refine the interpretation of CoverParenthesizedExpressionAndArrowParameterList:

ArrowFormalParameters[Yield]:(StrictFormalParameters[?Yield])

 

MethodDefinition[Yield]:PropertyName[?Yield](StrictFormalParameters){FunctionBody} GeneratorMethod[?Yield] getPropertyName[?Yield](){FunctionBody} setPropertyName[?Yield](PropertySetParameterList){FunctionBody} PropertySetParameterList:FormalParameter GeneratorMethod[Yield]:*PropertyName[?Yield](StrictFormalParameters[Yield]){GeneratorBody} GeneratorDeclaration[Yield, Default]:function*BindingIdentifier[?Yield](FormalParameters[Yield]){GeneratorBody} [+Default]function*(FormalParameters[Yield]){GeneratorBody} GeneratorExpression:function*BindingIdentifier[Yield]opt(FormalParameters[Yield]){GeneratorBody} GeneratorBody:FunctionBody[Yield] YieldExpression[In]:yield[no LineTerminator here]*AssignmentExpression[?In, Yield] yield[no LineTerminator here]AssignmentExpression[?In, Yield] ClassDeclaration[Yield, Default]:classBindingIdentifier[?Yield]ClassTail[?Yield] [+Default]classClassTail[?Yield] ClassExpression[Yield]:classBindingIdentifier[?Yield]optClassTail[?Yield] ClassTail[Yield]:ClassHeritage[?Yield]opt{ClassBody[?Yield]opt} ClassHeritage[Yield]:extendsLeftHandSideExpression[?Yield] ClassBody[Yield]:ClassElementList[?Yield] ClassElementList[Yield]:ClassElement[?Yield] ClassElementList[?Yield]ClassElement[?Yield] ClassElement[Yield]:MethodDefinition[?Yield] staticMethodDefinition[?Yield] ;

A.5Scripts and Modules#

Script:ScriptBodyopt ScriptBody:StatementList Module:ModuleBodyopt ModuleBody:ModuleItemList ModuleItemList:ModuleItem ModuleItemListModuleItem ModuleItem:ImportDeclaration ExportDeclaration StatementListItem ImportDeclaration:importImportClauseFromClause; importModuleSpecifier; ImportClause:ImportedDefaultBinding NameSpaceImport NamedImports ImportedDefaultBinding,NameSpaceImport ImportedDefaultBinding,NamedImports ImportedDefaultBinding:ImportedBinding NameSpaceImport:*asImportedBinding NamedImports:{} {ImportsList} {ImportsList,} FromClause:fromModuleSpecifier ImportsList:ImportSpecifier ImportsList,ImportSpecifier ImportSpecifier:ImportedBinding IdentifierNameasImportedBinding ModuleSpecifier:StringLiteral ImportedBinding:BindingIdentifier ExportDeclaration:export*FromClause; exportExportClauseFromClause; exportExportClause; exportVariableStatement exportDeclaration exportdefaultHoistableDeclaration[Default] exportdefaultClassDeclaration[Default] exportdefault[lookahead ∉ { function, class }]AssignmentExpression[In]; ExportClause:{} {ExportsList} {ExportsList,} ExportsList:ExportSpecifier ExportsList,ExportSpecifier ExportSpecifier:IdentifierName IdentifierNameasIdentifierName

A.6Number Conversions#

StringNumericLiteral:::StrWhiteSpaceopt StrWhiteSpaceoptStrNumericLiteralStrWhiteSpaceopt StrWhiteSpace:::StrWhiteSpaceCharStrWhiteSpaceopt StrWhiteSpaceChar:::WhiteSpace LineTerminator StrNumericLiteral:::StrDecimalLiteral BinaryIntegerLiteral OctalIntegerLiteral HexIntegerLiteral StrDecimalLiteral:::StrUnsignedDecimalLiteral +StrUnsignedDecimalLiteral -StrUnsignedDecimalLiteral StrUnsignedDecimalLiteral:::Infinity DecimalDigits.DecimalDigitsoptExponentPartopt .DecimalDigitsExponentPartopt DecimalDigitsExponentPartopt DecimalDigits::DecimalDigit DecimalDigitsDecimalDigit DecimalDigit::one of0123456789 ExponentPart::ExponentIndicatorSignedInteger ExponentIndicator::one ofeE SignedInteger::DecimalDigits +DecimalDigits -DecimalDigits HexIntegerLiteral::0xHexDigits 0XHexDigits HexDigit::one of0123456789abcdefABCDEF

All grammar symbols not explicitly defined by the StringNumericLiteral grammar have the definitions used in the Lexical Grammar for numeric literals.

A.7Universal Resource Identifier Character Classes#

uri:::uriCharactersopt uriCharacters:::uriCharacteruriCharactersopt uriCharacter:::uriReserved uriUnescaped uriEscaped uriReserved:::one of;/?:@&=+$, uriUnescaped:::uriAlpha DecimalDigit uriMark uriEscaped:::%HexDigitHexDigit uriAlpha:::one ofabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ uriMark:::one of-_.!~*'()

A.8Regular Expressions#

Pattern[U]::Disjunction[?U] Disjunction[U]::Alternative[?U] Alternative[?U]|Disjunction[?U] Alternative[U]::[empty] Alternative[?U]Term[?U] Term[U]::Assertion[?U] Atom[?U] Atom[?U]Quantifier Assertion[U]::^ $ \b \B (?=Disjunction[?U]) (?!Disjunction[?U]) Quantifier::QuantifierPrefix QuantifierPrefix? QuantifierPrefix::* + ? {DecimalDigits} {DecimalDigits,} {DecimalDigits,DecimalDigits} Atom[U]::PatternCharacter . \AtomEscape[?U] CharacterClass[?U] (Disjunction[?U]) (?:Disjunction[?U]) SyntaxCharacter::one of^$\.*+?()[]{}| PatternCharacter::SourceCharacterbut not SyntaxCharacter AtomEscape[U]::DecimalEscape CharacterEscape[?U] CharacterClassEscape CharacterEscape[U]::ControlEscape cControlLetter HexEscapeSequence RegExpUnicodeEscapeSequence[?U] IdentityEscape[?U] ControlEscape::one offnrtv ControlLetter::one ofabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ RegExpUnicodeEscapeSequence[U]::[+U]uLeadSurrogate\uTrailSurrogate [+U]uLeadSurrogate [+U]uTrailSurrogate [+U]uNonSurrogate [~U]uHex4Digits [+U]u{HexDigits}

Each \u TrailSurrogate for which the choice of associated u LeadSurrogate is ambiguous shall be associated with the nearest possible u LeadSurrogate that would otherwise have no corresponding \u TrailSurrogate.

 

LeadSurrogate::Hex4Digitsbut only if the SV of Hex4Digits is in the inclusive range 0xD800 to 0xDBFF TrailSurrogate::Hex4Digitsbut only if the SV of Hex4Digits is in the inclusive range 0xDC00 to 0xDFFF NonSurrogate::Hex4Digitsbut only if the SV of Hex4Digits is not in the inclusive range 0xD800 to 0xDFFF IdentityEscape[U]::[+U]SyntaxCharacter [+U]/ [~U]SourceCharacterbut not UnicodeIDContinue DecimalEscape::DecimalIntegerLiteral[lookahead ∉ DecimalDigit] CharacterClassEscape::one ofdDsSwW CharacterClass[U]::[[lookahead ∉ { ^ }]ClassRanges[?U]] [^ClassRanges[?U]] ClassRanges[U]::[empty] NonemptyClassRanges[?U] NonemptyClassRanges[U]::ClassAtom[?U] ClassAtom[?U]NonemptyClassRangesNoDash[?U] ClassAtom[?U]-ClassAtom[?U]ClassRanges[?U] NonemptyClassRangesNoDash[U]::ClassAtom[?U] ClassAtomNoDash[?U]NonemptyClassRangesNoDash[?U] ClassAtomNoDash[?U]-ClassAtom[?U]ClassRanges[?U] ClassAtom[U]::- ClassAtomNoDash[?U] ClassAtomNoDash[U]::SourceCharacterbut not one of \ or ] or - \ClassEscape[?U] ClassEscape[U]::DecimalEscape b [+U]- CharacterEscape[?U] CharacterClassEscape

BAdditional ECMAScript Features for Web Browsers#

The ECMAScript language syntax and semantics defined in this annex are required when the ECMAScript host is a web browser. The content of this annex is normative but optional if the ECMAScript host is not a web browser.

Note

This annex describes various legacy features and other characteristics of web browser based ECMAScript implementations. All of the language features and behaviours specified in this annex have one or more undesirable characteristics and in the absence of legacy usage would be removed from this specification. However, the usage of these features by large numbers of existing web pages means that web browsers must continue to support them. The specifications in this annex define the requirements for interoperable implementations of these legacy features.

These features are not considered part of the core ECMAScript language. Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code. ECMAScript implementations are discouraged from implementing these features unless the implementation is part of a web browser or is required to run the same legacy ECMAScript code that web browsers encounter.

B.1Additional Syntax#

B.1.1Numeric Literals#

The syntax and semantics of 11.8.3 is extended as follows except that this extension is not allowed for strict mode code:

Syntax

NumericLiteral::DecimalLiteral BinaryIntegerLiteral OctalIntegerLiteral HexIntegerLiteral LegacyOctalIntegerLiteral LegacyOctalIntegerLiteral::0OctalDigit LegacyOctalIntegerLiteralOctalDigit DecimalIntegerLiteral::0 NonZeroDigitDecimalDigitsopt NonOctalDecimalIntegerLiteral NonOctalDecimalIntegerLiteral::0NonOctalDigit LegacyOctalLikeDecimalIntegerLiteralNonOctalDigit NonOctalDecimalIntegerLiteralDecimalDigit LegacyOctalLikeDecimalIntegerLiteral::0OctalDigit LegacyOctalLikeDecimalIntegerLiteralOctalDigit NonOctalDigit::one of89

B.1.1.1Static Semantics#

B.1.2String Literals#

The syntax and semantics of 11.8.4 is extended as follows except that this extension is not allowed for strict mode code:

Syntax

EscapeSequence::CharacterEscapeSequence LegacyOctalEscapeSequence HexEscapeSequence UnicodeEscapeSequence LegacyOctalEscapeSequence::OctalDigit[lookahead ∉ OctalDigit] ZeroToThreeOctalDigit[lookahead ∉ OctalDigit] FourToSevenOctalDigit ZeroToThreeOctalDigitOctalDigit ZeroToThree::one of0123 FourToSeven::one of4567

This definition of EscapeSequence is not used in strict mode or when parsing TemplateCharacter.

B.1.2.1Static Semantics#

B.1.3HTML-like Comments#

The syntax and semantics of 11.4 is extended as follows except that this extension is not allowed when parsing source code using the goal symbol Module:

Syntax

Comment::MultiLineComment SingleLineComment SingleLineHTMLOpenComment SingleLineHTMLCloseComment SingleLineDelimitedComment MultiLineComment::/*FirstCommentLineoptLineTerminatorMultiLineCommentCharsopt*/HTMLCloseCommentopt FirstCommentLine::SingleLineDelimitedCommentChars SingleLineHTMLOpenComment::<!--SingleLineCommentCharsopt SingleLineHTMLCloseComment::LineTerminatorSequenceHTMLCloseComment SingleLineDelimitedComment::/*SingleLineDelimitedCommentCharsopt*/ HTMLCloseComment::WhiteSpaceSequenceoptSingleLineDelimitedCommentSequenceopt-->SingleLineCommentCharsopt SingleLineDelimitedCommentChars::SingleLineNotAsteriskCharSingleLineDelimitedCommentCharsopt *SingleLinePostAsteriskCommentCharsopt SingleLineNotAsteriskChar::SourceCharacterbut not one of * or LineTerminator SingleLinePostAsteriskCommentChars::SingleLineNotForwardSlashOrAsteriskCharSingleLineDelimitedCommentCharsopt *SingleLinePostAsteriskCommentCharsopt SingleLineNotForwardSlashOrAsteriskChar::SourceCharacterbut not one of / or * or LineTerminator WhiteSpaceSequence::WhiteSpaceWhiteSpaceSequenceopt SingleLineDelimitedCommentSequence::SingleLineDelimitedCommentWhiteSpaceSequenceoptSingleLineDelimitedCommentSequenceopt

Similar to a MultiLineComment that contains a line terminator code point, a SingleLineHTMLCloseComment is considered to be a LineTerminator for purposes of parsing by the syntactic grammar.

B.1.4Regular Expressions Patterns#

The syntax of 21.2.1 is modified and extended as follows. These changes introduce ambiguities that are broken by the ordering of grammar productions and by contextual information. When parsing using the following grammar, each alternative is considered only if previous production alternatives do not match.

This alternative pattern grammar and semantics only changes the syntax and semantics of BMP patterns. The following grammar extensions include productions parameterized with the [U] parameter. However, none of these extensions change the syntax of Unicode patterns recognized when parsing with the [U] parameter present on the goal symbol.

Syntax

Term[U]::[+U]Assertion[U] [+U]Atom[U] [+U]Atom[U]Quantifier [~U]QuantifiableAssertionQuantifier [~U]Assertion [~U]ExtendedAtomQuantifier [~U]ExtendedAtom Assertion[U]::^ $ \b \B [+U](?=Disjunction[U]) [+U](?!Disjunction[U]) [~U]QuantifiableAssertion QuantifiableAssertion::(?=Disjunction) (?!Disjunction) ExtendedAtom::. \AtomEscape CharacterClass (Disjunction) (?:Disjunction) InvalidBracedQuantifier ExtendedPatternCharacter InvalidBracedQuantifier::{DecimalDigits} {DecimalDigits,} {DecimalDigits,DecimalDigits} ExtendedPatternCharacter::SourceCharacterbut not one of ^$.*+?()[| AtomEscape[U]::[+U]DecimalEscape [+U]CharacterEscape[U] [+U]CharacterClassEscape [~U]DecimalEscapebut only if the integer value of DecimalEscape is <= _NcapturingParens_ [~U]CharacterClassEscape [~U]CharacterEscape CharacterEscape[U]::ControlEscape cControlLetter HexEscapeSequence RegExpUnicodeEscapeSequence[?U] [~U]LegacyOctalEscapeSequence IdentityEscape[?U] IdentityEscape[U]::[+U]SyntaxCharacter [+U]/ [~U]SourceCharacterbut not c NonemptyClassRanges[U]::ClassAtom[?U] ClassAtom[?U]NonemptyClassRangesNoDash[?U] [+U]ClassAtom[U]-ClassAtom[U]ClassRanges[U] [~U]ClassAtomInRange-ClassAtomInRangeClassRanges NonemptyClassRangesNoDash[U]::ClassAtom[?U] ClassAtomNoDash[?U]NonemptyClassRangesNoDash[?U] [+U]ClassAtomNoDash[U]-ClassAtom[U]ClassRanges[U] [~U]ClassAtomNoDashInRange-ClassAtomInRangeClassRanges ClassAtom[U]::- ClassAtomNoDash[?U] ClassAtomNoDash[U]::\ClassEscape[?U] SourceCharacterbut not one of ] or - ClassAtomInRange::- ClassAtomNoDashInRange ClassAtomNoDashInRange::\ClassEscape SourceCharacterbut not one of ] or - ClassEscape[U]::b [+U]DecimalEscape [+U]CharacterEscape[U] [+U]CharacterClassEscape [+U]- [~U]DecimalEscapebut only if the integer value of DecimalEscape is 0 [~U]CharacterClassEscape [~U]cClassControlLetter [~U]CharacterEscape ClassControlLetter::DecimalDigit _ Note

When the same left hand sides occurs with both [+U] and [~U] guards it is to control the disambiguation priority.

B.1.4.1Pattern Semantics#

The semantics of 21.2.2 is extended as follows:

Within 21.2.2.5 reference to “ Atom::(Disjunction) ” are to be interpreted as meaning “ Atom::(Disjunction) ” or “ ExtendedAtom::(Disjunction) ”.

Term (21.2.2.5) includes the following additional evaluation rules:

The production Term::QuantifiableAssertionQuantifier evaluates the same as the production Term::AtomQuantifier but with QuantifiableAssertion substituted for Atom.

The production Term::ExtendedAtomQuantifier evaluates the same as the production Term::AtomQuantifier but with ExtendedAtom substituted for Atom.

The production Term::ExtendedAtom evaluates the same as the production Term::Atom but with ExtendedAtom substituted for Atom.

Assertion (21.2.2.6) includes the following additional evaluation rule:

The production Assertion::QuantifiableAssertion evaluates by evaluating QuantifiableAssertion to obtain a Matcher and returning that Matcher.

Assertion (21.2.2.6) evaluation rules for the Assertion::(?=Disjunction) and Assertion::(?!Disjunction) productions are also used for the QuantifiableAssertion productions, but with QuantifiableAssertion substituted for Assertion.

Atom (21.2.2.8) evaluation rules for the Atom productions except for Atom::PatternCharacter are also used for the ExtendedAtom productions, but with ExtendedAtom substituted for Atom. The following evaluation rules are also added:

The production ExtendedAtom::InvalidBracedQuantifier evaluates as follows:

  1. Throw a SyntaxError exception.

The production ExtendedAtom::ExtendedPatternCharacter evaluates as follows:

  1. Let ch be the character represented by ExtendedPatternCharacter.
  2. Let A be a one-element CharSet containing the character ch.
  3. Call CharacterSetMatcher(A, false) and return its Matcher result.

CharacterEscape (21.2.2.10) includes the following additional evaluation rule:

The production CharacterEscape::LegacyOctalEscapeSequence evaluates by evaluating the SV of the LegacyOctalEscapeSequence (see B.1.2) and returning its character result.

NonemptyClassRanges (21.2.2.15) includes the following additional evaluation rule:

The production NonemptyClassRanges::ClassAtomInRange-ClassAtomInRangeClassRanges evaluates as follows:

  1. Evaluate the first ClassAtomInRange to obtain a CharSet A.
  2. Evaluate the second ClassAtomInRange to obtain a CharSet B.
  3. Evaluate ClassRanges to obtain a CharSet C.
  4. Call CharacterRangeOrUnion(A, B) and let D be the resulting CharSet.
  5. Return the union of CharSets D and C.

NonemptyClassRangesNoDash (21.2.2.16) includes the following additional evaluation rule:

The production NonemptyClassRangesNoDash::ClassAtomNoDashInRange-ClassAtomInRangeClassRanges evaluates as follows:

  1. Evaluate ClassAtomNoDashInRange to obtain a CharSet A.
  2. Evaluate ClassAtomInRange to obtain a CharSet B.
  3. Evaluate ClassRanges to obtain a CharSet C.
  4. Call CharacterRangeOrUnion(A, B) and let D be the resulting CharSet.
  5. Return the union of CharSets D and C.

ClassAtom (21.2.2.17) includes the following additional evaluation rules:

The production ClassAtomInRange::- evaluates by returning the CharSet containing the one character -.

The production ClassAtomInRange::ClassAtomNoDashInRange evaluates by evaluating ClassAtomNoDashInRange to obtain a CharSet and returning that CharSet.

ClassAtomNoDash (21.2.2.18) includes the following additional evaluation rules:

The production ClassAtomNoDash::SourceCharacterbut not one of ] or - evaluates by returning a one-element CharSet containing the character represented by SourceCharacter.

The production ClassAtomNoDashInRange::\ClassEscape evaluates by evaluating ClassEscape to obtain a CharSet and returning that CharSet.

The production ClassAtomNoDashInRange::SourceCharacterbut not one of ] or - evaluates by returning a one-element CharSet containing the character represented by SourceCharacter.

ClassEscape (21.2.2.19) includes the following additional evaluation rules:

The production ClassEscape::DecimalEscapebut only if … evaluates as follows:

  1. Evaluate DecimalEscape to obtain an EscapeValue E.
  2. Assert: E is a character.
  3. Let ch be E's character.
  4. Return the one-element CharSet containing the character ch.

The production ClassEscape::cClassControlLetter evaluates as follows:

  1. Let ch be the character matched by ClassControlLetter.
  2. Let i be ch's character value.
  3. Let j be the remainder of dividing i by 32.
  4. Return the character whose character value is j.

B.1.4.1.1Runtime Semantics: CharacterRangeOrUnion Abstract Operation#

The abstract operation CharacterRangeOrUnion takes two CharSet parameters A and B and performs the following steps:

  1. If A does not contain exactly one character or B does not contain exactly one character, then
    1. Let C be the CharSet containing the single character - U+002D (HYPHEN-MINUS).
    2. Return the union of CharSets A, B and C.
  2. Return CharacterRange(A, B).

B.2Additional Built-in Properties#

When the ECMAScript host is a web browser the following additional properties of the standard built-in objects are defined.

B.2.1Additional Properties of the Global Object#

The entries in Table 61 are added to Table 7.

Table 61: Additional Well-known Intrinsic Objects
Intrinsic Name Global Name ECMAScript Language Association
%escape% escape The escape function (B.2.1.1)
%unescape% unescape The unescape function (B.2.1.2)

B.2.1.1escape (string)#

The escape function is a property of the global object. It computes a new version of a String value in which certain code units have been replaced by a hexadecimal escape sequence.

For those code units being replaced whose value is 0x00FF or less, a two-digit escape sequence of the form %xx is used. For those characters being replaced whose code unit value is greater than 0x00FF, a four-digit escape sequence of the form %uxxxx is used.

The escape function is the %escape% intrinsic object. When the escape function is called with one argument string, the following steps are taken:

  1. Let string be ? ToString(string).
  2. Let length be the number of code units in string.
  3. Let R be the empty string.
  4. Let k be 0.
  5. Repeat, while k < length,
    1. Let char be the code unit (represented as a 16-bit unsigned integer) at index k within string.
    2. If char is one of the code units in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./", then
      1. Let S be a String containing the single code unit char.
    3. Else if char ≥ 256, then
      1. Let S be a String containing six code units "%uwxyz" where wxyz are the code units of the four hexadecimal digits encoding the value of char.
    4. Else, char < 256
      1. Let S be a String containing three code units "%xy" where xy are the code units of two hexadecimal digits encoding the value of char.
    5. Let R be a new String value computed by concatenating the previous value of R and S.
    6. Increase k by 1.
  6. Return R.
Note

The encoding is partly based on the encoding described in RFC 1738, but the entire encoding specified in this standard is described above without regard to the contents of RFC 1738. This encoding does not reflect changes to RFC 1738 made by RFC 3986.

B.2.1.2unescape (string)#

The unescape function is a property of the global object. It computes a new version of a String value in which each escape sequence of the sort that might be introduced by the escape function is replaced with the code unit that it represents.

The unescape function is the %unescape% intrinsic object. When the unescape function is called with one argument string, the following steps are taken:

  1. Let string be ? ToString(string).
  2. Let length be the number of code units in string.
  3. Let R be the empty String.
  4. Let k be 0.
  5. Repeat, while klength
    1. Let c be the code unit at index k within string.
    2. If c is %, then
      1. If klength-6 and the code unit at index k+1 within string is u and the four code units at indices k+2, k+3, k+4, and k+5 within string are all hexadecimal digits, then
        1. Let c be the code unit whose value is the integer represented by the four hexadecimal digits at indices k+2, k+3, k+4, and k+5 within string.
        2. Increase k by 5.
      2. Else if klength-3 and the two code units at indices k+1 and k+2 within string are both hexadecimal digits, then
        1. Let c be the code unit whose value is the integer represented by two zeroes plus the two hexadecimal digits at indices k+1 and k+2 within string.
        2. Increase k by 2.
    3. Let R be a new String value computed by concatenating the previous value of R and c.
    4. Increase k by 1.
  6. Return R.

B.2.2Additional Properties of the Object.prototype Object#

B.2.2.1Object.prototype.__proto__#

Object.prototype.__proto__ is an accessor property with attributes { [[Enumerable]]: false, [[Configurable]]: true }. The [[Get]] and [[Set]] attributes are defined as follows:

B.2.2.1.1get Object.prototype.__proto__#

The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps:

  1. Let O be ? ToObject(this value).
  2. Return ? O.[[GetPrototypeOf]]().

B.2.2.1.2set Object.prototype.__proto__#

The value of the [[Set]] attribute is a built-in function that takes an argument proto. It performs the following steps:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If Type(proto) is neither Object nor Null, return undefined.
  3. If Type(O) is not Object, return undefined.
  4. Let status be ? O.[[SetPrototypeOf]](proto).
  5. If status is false, throw a TypeError exception.
  6. Return undefined.

B.2.3Additional Properties of the String.prototype Object#

B.2.3.1String.prototype.substr (start, length)#

The substr method takes two arguments, start and length, and returns a substring of the result of converting the this object to a String, starting from index start and running for length code units (or through the end of the String if length is undefined). If start is negative, it is treated as sourceLength+start where sourceLength is the length of the String. The result is a String value, not a String object. The following steps are taken:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let intStart be ? ToInteger(start).
  4. If length is undefined, let end be +∞; otherwise let end be ? ToInteger(length).
  5. Let size be the number of code units in S.
  6. If intStart < 0, let intStart be max(size + intStart, 0).
  7. Let resultLength be min(max(end, 0), size - intStart).
  8. If resultLength ≤ 0, return the empty String "".
  9. Return a String containing resultLength consecutive code units from S beginning with the code unit at index intStart.
Note

The substr function is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

B.2.3.2String.prototype.anchor ( name )#

When the anchor method is called with argument name, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "a", "name", name).

B.2.3.2.1Runtime Semantics: CreateHTML ( string, tag, attribute, value )#

The abstract operation CreateHTML is called with arguments string, tag, attribute, and value. The arguments tag and attribute must be String values. The following steps are taken:

  1. Let str be ? RequireObjectCoercible(string).
  2. Let S be ? ToString(str).
  3. Let p1 be the String value that is the concatenation of "<" and tag.
  4. If attribute is not the empty String, then
    1. Let V be ? ToString(value).
    2. Let escapedV be the String value that is the same as V except that each occurrence of the code unit 0x0022 (QUOTATION MARK) in V has been replaced with the six code unit sequence "&quot;".
    3. Let p1 be the String value that is the concatenation of the following String values:
      • The String value of p1
      • Code unit 0x0020 (SPACE)
      • The String value of attribute
      • Code unit 0x003D (EQUALS SIGN)
      • Code unit 0x0022 (QUOTATION MARK)
      • The String value of escapedV
      • Code unit 0x0022 (QUOTATION MARK)
  5. Let p2 be the String value that is the concatenation of p1 and ">".
  6. Let p3 be the String value that is the concatenation of p2 and S.
  7. Let p4 be the String value that is the concatenation of p3, "</", tag, and ">".
  8. Return p4.

B.2.3.3String.prototype.big ()#

When the big method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "big", "", "").

B.2.3.4String.prototype.blink ()#

When the blink method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "blink", "", "").

B.2.3.5String.prototype.bold ()#

When the bold method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "b", "", "").

B.2.3.6String.prototype.fixed ()#

When the fixed method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "tt", "", "").

B.2.3.7String.prototype.fontcolor ( color )#

When the fontcolor method is called with argument color, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "font", "color", color).

B.2.3.8String.prototype.fontsize ( size )#

When the fontsize method is called with argument size, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "font", "size", size).

B.2.3.9String.prototype.italics ()#

When the italics method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "i", "", "").

B.2.3.10String.prototype.link ( url )#

When the link method is called with argument url, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "a", "href", url).

B.2.3.11String.prototype.small ()#

When the small method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "small", "", "").

B.2.3.12String.prototype.strike ()#

When the strike method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "strike", "", "").

B.2.3.13String.prototype.sub ()#

When the sub method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "sub", "", "").

B.2.3.14String.prototype.sup ()#

When the sup method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "sup", "", "").

B.2.4Additional Properties of the Date.prototype Object#

B.2.4.1Date.prototype.getYear ( )#

Note

The getFullYear method is preferred for nearly all purposes, because it avoids the “year 2000 problem.”

When the getYear method is called with no arguments, the following steps are taken:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, return NaN.
  3. Return YearFromTime(LocalTime(t)) - 1900.

B.2.4.2Date.prototype.setYear (year)#

Note

The setFullYear method is preferred for nearly all purposes, because it avoids the “year 2000 problem.”

When the setYear method is called with one argument year, the following steps are taken:

  1. Let t be ? thisTimeValue(this value).
  2. If t is NaN, let t be +0; otherwise, let t be LocalTime(t).
  3. Let y be ? ToNumber(year).
  4. If y is NaN, set the [[DateValue]] internal slot of this Date object to NaN and return NaN.
  5. If y is not NaN and 0 ≤ ToInteger(y) ≤ 99, let yyyy be ToInteger(y) + 1900.
  6. Else, let yyyy be y.
  7. Let d be MakeDay(yyyy, MonthFromTime(t), DateFromTime(t)).
  8. Let date be UTC(MakeDate(d, TimeWithinDay(t))).
  9. Set the [[DateValue]] internal slot of this Date object to TimeClip(date).
  10. Return the value of the [[DateValue]] internal slot of this Date object.

B.2.4.3Date.prototype.toGMTString ( )#

Note

The property toUTCString is preferred. The toGMTString property is provided principally for compatibility with old code. It is recommended that the toUTCString property be used in new ECMAScript code.

The function object that is the initial value of Date.prototype.toGMTString is the same function object that is the initial value of Date.prototype.toUTCString.

B.2.5Additional Properties of the RegExp.prototype Object#

B.2.5.1RegExp.prototype.compile (pattern, flags )#

When the compile method is called with arguments pattern and flags, the following steps are taken:

  1. Let O be the this value.
  2. If Type(O) is not Object or Type(O) is Object and O does not have a [[RegExpMatcher]] internal slot, then
    1. Throw a TypeError exception.
  3. If Type(pattern) is Object and pattern has a [[RegExpMatcher]] internal slot, then
    1. If flags is not undefined, throw a TypeError exception.
    2. Let P be the value of pattern's [[OriginalSource]] internal slot.
    3. Let F be the value of pattern's [[OriginalFlags]] internal slot.
  4. Else,
    1. Let P be pattern.
    2. Let F be flags.
  5. Return ? RegExpInitialize(O, P, F).
Note

The compile method completely reinitializes the this object RegExp with a new pattern and flags. An implementation may interpret use of this method as an assertion that the resulting RegExp object will be used multiple times and hence is a candidate for extra optimization.

B.3Other Additional Features#

B.3.1__proto__ Property Names in Object Initializers#

The following Early Error rule is added to those in 12.2.6.1. When ObjectLiteral appears in a context where ObjectAssignmentPattern is required the Early Error rule is not applied. In addition, it is not applied when initially parsing a CoverParenthesizedExpressionAndArrowParameterList.

ObjectLiteral:{PropertyDefinitionList} ObjectLiteral:{PropertyDefinitionList,} Note

The List returned by PropertyNameList does not include string literal property names defined as using a ComputedPropertyName.

In 12.2.6.9 the PropertyDefinitionEvaluation algorithm for the production
PropertyDefinition:PropertyName:AssignmentExpression
is replaced with the following definition:

PropertyDefinition:PropertyName:AssignmentExpression
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. Let exprValueRef be the result of evaluating AssignmentExpression.
  4. Let propValue be ? GetValue(exprValueRef).
  5. If propKey is the String value "__proto__" and if IsComputedPropertyKey(propKey) is false, then
    1. If Type(propValue) is either Object or Null, then
      1. Return object.[[SetPrototypeOf]](propValue).
    2. Return NormalCompletion(empty).
  6. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
    1. Let hasNameProperty be ? HasOwnProperty(propValue, "name").
    2. If hasNameProperty is false, perform SetFunctionName(propValue, propKey).
  7. Assert: enumerable is true.
  8. Return CreateDataPropertyOrThrow(object, propKey, propValue).

B.3.2Labelled Function Declarations#

Prior to ECMAScript 2015, the specification of LabelledStatement did not allow for the association of a statement label with a FunctionDeclaration. However, a labelled FunctionDeclaration was an allowable extension for non-strict code and most browser-hosted ECMAScript implementations supported that extension. In ECMAScript 2015, the grammar productions for LabelledStatement permits use of FunctionDeclaration as a LabelledItem but 13.13.1 includes an Early Error rule that produces a Syntax Error if that occurs. For web browser compatibility, that rule is modified with the addition of the highlighted text:

LabelledItem:FunctionDeclaration
  • It is a Syntax Error if any strict mode source code matches this rule.

B.3.3Block-Level Function Declarations Web Legacy Compatibility Semantics#

Prior to ECMAScript 2015, the ECMAScript specification did not define the occurrence of a FunctionDeclaration as an element of a Block statement's StatementList. However, support for that form of FunctionDeclaration was an allowable extension and most browser-hosted ECMAScript implementations permitted them. Unfortunately, the semantics of such declarations differ among those implementations. Because of these semantic differences, existing web ECMAScript code that uses Block level function declarations is only portable among browser implementation if the usage only depends upon the semantic intersection of all of the browser implementations for such declarations. The following are the use cases that fall within that intersection semantics:

  1. A function is declared and only referenced within a single block

    • A FunctionDeclaration whose BindingIdentifier is the name f occurs exactly once within the function code of an enclosing function g and that declaration is nested within a Block.
    • No other declaration of f that is not a var declaration occurs within the function code of g
    • All occurrences of f as an IdentifierReference are within the StatementList of the Block containing the declaration of f.
  2. A function is declared and possibly used within a single Block but also referenced by an inner function definition that is not contained within that same Block.

    • A FunctionDeclaration whose BindingIdentifier is the name f occurs exactly once within the function code of an enclosing function g and that declaration is nested within a Block.
    • No other declaration of f that is not a var declaration occurs within the function code of g
    • There may be occurrences of f as an IdentifierReference within the StatementList of the Block containing the declaration of f.
    • There is at least one occurrence of f as an IdentifierReference within another function h that is nested within g and no other declaration of f shadows the references to f from within h.
    • All invocations of h occur after the declaration of f has been evaluated.
  3. A function is declared and possibly used within a single block but also referenced within subsequent blocks.

    • A FunctionDeclaration whose BindingIdentifier is the name f occurs exactly once within the function code of an enclosing function g and that declaration is nested within a Block.
    • No other declaration of f that is not a var declaration occurs within the function code of g
    • There may be occurrences of f as an IdentifierReference within the StatementList of the Block containing the declaration of f.
    • There is at least one occurrence of f as an IdentifierReference within the function code of g that lexically follows the Block containing the declaration of f.

The first use case is interoperable with the semantics of Block level function declarations provided by ECMAScript 2015. Any pre-existing ECMAScript code that employs that use case will operate using the Block level function declarations semantics defined by clauses 9, 13, and 14 of this specification.

ECMAScript 2015 interoperability for the second and third use cases requires the following extensions to the clause 9, clause 14, clause 18.2.1 and clause 15.1.11 semantics.

If an ECMAScript implementation has a mechanism for reporting diagnostic warning messages, a warning should be produced when code contains a FunctionDeclaration for which these compatibility semantics are applied and introduce observable differences from non-compatibility semantics. For example, if a var binding is not introduced because its introduction would create an early error, a warning message should not be produced.

B.3.3.1Changes to FunctionDeclarationInstantiation#

During FunctionDeclarationInstantiation the following steps are performed in place of step 29:

  1. If strict is false, then
    1. For each FunctionDeclaration f that is directly contained in the StatementList of a Block, CaseClause, or DefaultClause,
      1. Let F be StringValue of the BindingIdentifier of FunctionDeclaration f.
      2. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for func and F is not an element of BoundNames of argumentsList, then
        1. NOTE A var binding for F is only instantiated here if it is neither a VarDeclaredName, the name of a formal parameter, or another FunctionDeclaration.
        2. If instantiatedVarNames does not contain F, then
          1. Perform ! varEnvRec.CreateMutableBinding(F, false).
          2. Perform varEnvRec.InitializeBinding(F, undefined).
          3. Append F to instantiatedVarNames.
        3. When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 14.1.21:
          1. Let fenv be the running execution context's VariableEnvironment.
          2. Let fenvRec be fenv's EnvironmentRecord.
          3. Let benv be the running execution context's LexicalEnvironment.
          4. Let benvRec be benv's EnvironmentRecord.
          5. Let fobj be ! benvRec.GetBindingValue(F, false).
          6. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
          7. Return NormalCompletion(empty).

B.3.3.2Changes to GlobalDeclarationInstantiation#

During GlobalDeclarationInstantiation the following steps are performed in place of step 14:

  1. Let strict be IsStrict of script
  2. If strict is false, then
    1. Let declaredFunctionOrVarNames be a new empty List.
    2. Append to declaredFunctionOrVarNames the elements of declaredFunctionNames.
    3. Append to declaredFunctionOrVarNames the elements of declaredVarNames.
    4. For each FunctionDeclaration f that is directly contained in the StatementList of a Block, CaseClause, or DefaultClause Contained within script,
      1. Let F be StringValue of the BindingIdentifier of FunctionDeclaration f.
      2. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for script, then
        1. If envRec.HasLexicalDeclaration(F) is false, then
          1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
          2. If fnDefinable is true, then
            1. NOTE A var binding for F is only instantiated here if it is neither a VarDeclaredName nor the name of another FunctionDeclaration.
            2. If declaredFunctionOrVarNames does not contain F, then
              1. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
              2. Append F to declaredFunctionOrVarNames.
            3. When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 14.1.21:
              1. Let genv be the running execution context's VariableEnvironment.
              2. Let genvRec be genv's EnvironmentRecord.
              3. Let benv be the running execution context's LexicalEnvironment.
              4. Let benvRec be benv's EnvironmentRecord.
              5. Let fobj be ! benvRec.GetBindingValue(F, false).
              6. Perform ? genvRec.SetMutableBinding(F, fobj, false).
              7. Return NormalCompletion(empty).

B.3.3.3Changes to EvalDeclarationInstantiation#

During EvalDeclarationInstantiation the following steps are performed in place of step 9:

  1. If strict is false, then
    1. Let declaredFunctionOrVarNames be a new empty List.
    2. Append to declaredFunctionOrVarNames the elements of declaredFunctionNames.
    3. Append to declaredFunctionOrVarNames the elements of declaredVarNames.
    4. For each FunctionDeclaration f that is directly contained in the StatementList of a Block, CaseClause, or DefaultClause Contained within body,
      1. Let F be StringValue of the BindingIdentifier of FunctionDeclaration f.
      2. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for body, then
        1. Let bindingExists be false.
        2. Let thisLex be lexEnv.
        3. Assert: the following loop will terminate.
        4. Repeat while thisLex is not the same as varEnv,
          1. Let thisEnvRec be thisLex's EnvironmentRecord.
          2. If thisEnvRec is not an object Environment Record, then
            1. If thisEnvRec.HasBinding(F) is true, then
              1. Let bindingExists be true.
          3. Let thisLex be thisLex's outer environment reference.
        5. If bindingExists is false and varEnvRec is a global Environment Record, then
          1. If varEnvRec.HasLexicalDeclaration(F) is false, then
            1. Let fnDefinable be ? varEnvRec.CanDeclareGlobalFunction(F).
          2. Else,
            1. Let fnDefinable be false.
        6. Else,
          1. Let fnDefinable be true.
        7. If bindingExists is false and fnDefinable is true, then
          1. If declaredFunctionOrVarNames does not contain F, then
            1. If varEnvRec is a global Environment Record, then
              1. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
            2. Else,
              1. Let bindingExists be varEnvRec.HasBinding(F).
              2. If bindingExists is false, then
                1. Perform ! varEnvRec.CreateMutableBinding(F, true).
                2. Perform ! varEnvRec.InitializeBinding(F, undefined).
            3. Append F to declaredFunctionOrVarNames.
          2. When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 14.1.21:
            1. Let genv be the running execution context's VariableEnvironment.
            2. Let genvRec be genv's EnvironmentRecord.
            3. Let benv be the running execution context's LexicalEnvironment.
            4. Let benvRec be benv's EnvironmentRecord.
            5. Let fobj be ! benvRec.GetBindingValue(F, false).
            6. Perform ? genvRec.SetMutableBinding(F, fobj, false).
            7. Return NormalCompletion(empty).

B.3.4FunctionDeclarations in IfStatement Statement Clauses#

The following rules for IfStatement augment those in 13.6:

IfStatement[Yield, Return]:if(Expression[In, ?Yield])FunctionDeclaration[?Yield]elseStatement[?Yield, ?Return] if(Expression[In, ?Yield])Statement[?Yield, ?Return]elseFunctionDeclaration[?Yield] if(Expression[In, ?Yield])FunctionDeclaration[?Yield]elseFunctionDeclaration[?Yield] if(Expression[In, ?Yield])FunctionDeclaration[?Yield]

The above rules are only applied when parsing code that is not strict mode code. If any such code is match by one of these rules subsequent processing of that code takes places as if each matching occurrence of FunctionDeclaration[?Yield] was the sole StatementListItem of a BlockStatement occupying that position in the source code. The semantics of such a synthetic BlockStatement includes the web legacy compatibility semantics specified in B.3.3.

B.3.5VariableStatements in Catch Blocks#

The content of subclause 13.15.1 is replaced with the following:

Catch:catch(CatchParameter)Block Note

The Block of a Catch clause may contain var declarations that bind a name that is also bound by the CatchParameter. At runtime, such bindings are instantiated in the VariableDeclarationEnvironment. They do not shadow the same-named bindings introduced by the CatchParameter and hence the Initializer for such var declarations will assign to the corresponding catch parameter rather than the var binding. The relaxation of the normal static semantic rule does not apply to names only bound by for-of statements.

This modified behaviour also applies to var and function declarations introduced by direct eval calls contained within the Block of a Catch clause. This change is accomplished by modify the algorithm of 18.2.1.2 as follows:

Step 5.d.ii.2.a.i is replaced by:

  1. If thisEnvRec is not the Environment Record for a Catch clause, throw a SyntaxError exception.
  2. If name is bound by any syntactic form other than a FunctionDeclaration, a VariableStatement, the VariableDeclarationList of a for statement, or the ForBinding of a for-in statement, throw a SyntaxError exception.

Step 9.d.ii.4.b.i.i is replaced by:

  1. If thisEnvRec is not the Environment Record for a Catch clause, let bindingExists be true.

CThe Strict Mode of ECMAScript#

The strict mode restriction and exceptions

DCorrections and Clarifications in ECMAScript 2015 with Possible Compatibility Impact#

8.1.1.4.15-8.1.1.4.18 Edition 5 and 5.1 used a property existence test to determine whether a global object property corresponding to a new global declaration already existed. ECMAScript 2015 uses an own property existence test. This corresponds to what has been most commonly implemented by web browsers.

9.4.2.1: The 5th Edition moved the capture of the current array length prior to the integer conversion of the array index or new length value. However, the captured length value could become invalid if the conversion process has the side-effect of changing the array length. ECMAScript 2015 specifies that the current array length must be captured after the possible occurrence of such side-effects.

20.3.1.15: Previous editions permitted the TimeClip abstract operation to return either +0 or -0 as the representation of a 0 time value. ECMAScript 2015 specifies that +0 always returned. This means that for ECMAScript 2015 the time value of a Date object is never observably -0 and methods that return time values never return -0.

20.3.1.16: If a time zone offset is not present, the local time zone is used. Edition 5.1 incorrectly stated that a missing time zone should be interpreted as "z".

20.3.4.36: If the year cannot be represented using the Date Time String Format specified in 20.3.1.16 a RangeError exception is thrown. Previous editions did not specify the behaviour for that case.

20.3.4.41: Previous editions did not specify the value returned by Date.prototype.toString when this time value is NaN. ECMAScript 2015 specifies the result to be the String value is "Invalid Date".

21.2.3.1, 21.2.3.2.4: Any LineTerminator code points in the value of the source property of an RegExp instance must be expressed using an escape sequence. Edition 5.1 only required the escaping of "/".

21.2.5.6, 21.2.5.8: In previous editions, the specifications for String.prototype.match and String.prototype.replace was incorrect for cases where the pattern argument was a RegExp value whose global is flag set. The previous specifications stated that for each attempt to match the pattern, if lastIndex did not change it should be incremented by 1. The correct behaviour is that lastIndex should be incremented by one only if the pattern matched the empty string.

22.1.3.25, 22.1.3.25.1: Previous editions did not specify how a NaN value returned by a comparefn was interpreted by Array.prototype.sort. ECMAScript 2015 specifies that such as value is treated as if +0 was returned from the comparefn. ECMAScript 2015 also specifies that ToNumber is applied to the result returned by a comparefn. In previous editions, the effect of a comparefn result that is not a Number value was implementation dependent. In practice, implementations call ToNumber.

EAdditions and Changes That Introduce Incompatibilities with Prior Editions#

7.1.3.1: In ECMAScript 2015, ToNumber applied to a String value now recognizes and converts BinaryIntegerLiteral and OctalIntegerLiteral numeric strings. In previous editions such strings were converted to NaN.

6.2.3: In ECMAScript 2015, Function calls are not allowed to return a Reference value.

11.6: In ECMAScript 2015, the valid code points for an IdentifierName are specified in terms of the Unicode properties “ID_Start” and “ID_Continue”. In previous editions, the valid IdentifierName or Identifier code points were specified by enumerating various Unicode code point categories.

11.9.1: In ECMAScript 2015, Automatic Semicolon Insertion adds a semicolon at the end of a do-while statement if the semicolon is missing. This change aligns the specification with the actual behaviour of most existing implementations.

12.2.6.1: In ECMAScript 2015, it is no longer an early error to have duplicate property names in Object Initializers.

12.15.1: In ECMAScript 2015, strict mode code containing an assignment to an immutable binding such as the function name of a FunctionExpression does not produce an early error. Instead it produces a runtime error.

13.2: In ECMAScript 2015, a StatementList beginning with the token let followed by the input elements LineTerminator then Identifier is the start of a LexicalDeclaration. In previous editions, automatic semicolon insertion would always insert a semicolon before the Identifier input element.

13.5: In ECMAScript 2015, a StatementListItem beginning with the token let followed by the token [ is the start of a LexicalDeclaration. In previous editions such a sequence would be the start of an ExpressionStatement.

13.6.7: In ECMAScript 2015, the normal completion value of an IfStatement is never the value empty. If no Statement part is evaluated or if the evaluated Statement part produces a normal completion whose value is empty, the completion value of the IfStatement is undefined.

13.7: In ECMAScript 2015, if the ( token of a for statement is immediately followed by the token sequence let [ then the let is treated as the start of a LexicalDeclaration. In previous editions such a token sequence would be the start of an Expression.

13.7: In ECMAScript 2015, if the ( token of a for-in statement is immediately followed by the token sequence let [ then the let is treated as the start of a ForDeclaration. In previous editions such a token sequence would be the start of an LeftHandSideExpression.

13.7: Prior to ECMAScript 2015, an initialization expression could appear as part of the VariableDeclaration that precedes the in keyword. The value of that expression was always discarded. In ECMAScript 2015, the ForBinding in that same position does not allow the occurrence of such an initializer.

13.7: In ECMAScript 2015, the completion value of an IterationStatement is never the value empty. If the Statement part of an IterationStatement is not evaluated or if the final evaluation of the Statement part produces a completion whose value is empty, the completion value of the IterationStatement is undefined.

13.11.7: In ECMAScript 2015, the normal completion value of a WithStatement is never the value empty. If evaluation of the Statement part of a WithStatement produces a normal completion whose value is empty, the completion value of the WithStatement is undefined.

13.12.11: In ECMAScript 2015, the completion value of a SwitchStatement is never the value empty. If the CaseBlock part of a SwitchStatement produces a completion whose value is empty, the completion value of the SwitchStatement is undefined.

13.15: In ECMAScript 2015, it is an early error for a Catch clause to contain a var declaration for the same Identifier that appears as the Catch clause parameter. In previous editions, such a variable declaration would be instantiated in the enclosing variable environment but the declaration's Initializer value would be assigned to the Catch parameter.

13.15, 18.2.1.2: In ECMAScript 2015, a runtime SyntaxError is thrown if a Catch clause evaluates a non-strict direct eval whose eval code includes a var or FunctionDeclaration declaration that binds the same Identifier that appears as the Catch clause parameter.

13.15.8: In ECMAScript 2015, the completion value of a TryStatement is never the value empty. If the Block part of a TryStatement evaluates to a normal completion whose value is empty, the completion value of the TryStatement is undefined. If the Block part of a TryStatement evaluates to a throw completion and it has a Catch part that evaluates to a normal completion whose value is empty, the completion value of the TryStatement is undefined if there is no Finally clause or if its Finally clause evalulates to an empty normal completion.

14.3.9 In ECMAScript 2015, the function objects that are created as the values of the [[Get]] or [[Set]] attribute of accessor properties in an ObjectLiteral are not constructor functions and they do not have a prototype own property. In the previous edition, they were constructors and had a prototype property.

19.1.2.5: In ECMAScript 2015, if the argument to Object.freeze is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

19.1.2.6: In ECMAScript 2015, if the argument to Object.getOwnPropertyDescriptor is not an object an attempt is made to coerce the argument using ToObject. If the coercion is successful the result is used in place of the original argument value. In the previous edition, a non-object argument always causes a TypeError to be thrown.

19.1.2.7: In ECMAScript 2015, if the argument to Object.getOwnPropertyNames is not an object an attempt is made to coerce the argument using ToObject. If the coercion is successful the result is used in place of the original argument value. In the previous edition, a non-object argument always causes a TypeError to be thrown.

19.1.2.9: In ECMAScript 2015, if the argument to Object.getPrototypeOf is not an object an attempt is made to coerce the argument using ToObject. If the coercion is successful the result is used in place of the original argument value. In the previous edition, a non-object argument always causes a TypeError to be thrown.

19.1.2.11: In ECMAScript 2015, if the argument to Object.isExtensible is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

19.1.2.12: In ECMAScript 2015, if the argument to Object.isFrozen is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

19.1.2.13: In ECMAScript 2015, if the argument to Object.isSealed is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

19.1.2.14: In ECMAScript 2015, if the argument to Object.keys is not an object an attempt is made to coerce the argument using ToObject. If the coercion is successful the result is used in place of the original argument value. In the previous edition, a non-object argument always causes a TypeError to be thrown.

19.1.2.15: In ECMAScript 2015, if the argument to Object.preventExtensions is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

19.1.2.17: In ECMAScript 2015, if the argument to Object.seal is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

19.2.3.2: In ECMAScript 2015, the [[Prototype]] internal slot of a bound function is set to the [[GetPrototypeOf]] value of its target function. In the previous edition, [[Prototype]] was always set to %FunctionPrototype%.

19.2.4.1: In ECMAScript 2015, the length property of function instances is configurable. In previous editions it was non-configurable.

19.5.6.2: In ECMAScript 2015, the [[Prototype]] internal slot of a NativeError constructor is the Error constructor. In previous editions it was the Function prototype object.

20.3.4 In ECMAScript 2015, the Date prototype object is not a Date instance. In previous editions it was a Date instance whose TimeValue was NaN.

21.1.3.10 In ECMAScript 2015, the String.prototype.localeCompare function must treat Strings that are canonically equivalent according to the Unicode standard as being identical. In previous editions implementations were permitted to ignore canonical equivalence and could instead use a bit-wise comparison.

21.1.3.22 and 21.1.3.24 In ECMAScript 2015, lowercase/upper conversion processing operates on code points. In previous editions such the conversion processing was only applied to individual code units. The only affected code points are those in the Deseret block of Unicode

21.1.3.25 In ECMAScript 2015, the String.prototype.trim method is defined to recognize white space code points that may exists outside of the Unicode BMP. However, as of Unicode 7 no such code points are defined. In previous editions such code points would not have been recognized as white space.

21.2.3.1 In ECMAScript 2015, If the pattern argument is a RegExp instance and the flags argument is not undefined, a new RegExp instance is created just like pattern except that pattern's flags are replaced by the argument flags. In previous editions a TypeError exception was thrown when pattern was a RegExp instance and flags was not undefined.

21.2.5 In ECMAScript 2015, the RegExp prototype object is not a RegExp instance. In previous editions it was a RegExp instance whose pattern is the empty string.

21.2.5 In ECMAScript 2015, source, global, ignoreCase, and multiline are accessor properties defined on the RegExp prototype object. In previous editions they were data properties defined on RegExp instances

FBibliography#

  1. IEEE Std 754-2008: IEEE Standard for Floating-Point Arithmetic. Institute of Electrical and Electronic Engineers, New York (2008)
  2. The Unicode Standard, Version 8.0.0 or successor.
    <http://www.unicode.org/versions/latest>
  3. Unicode Standard Annex #15, Unicode Normalization Forms, version Unicode 8.0.0, or successor.
    <http://www.unicode.org/reports/tr15/>
  4. Unicode Standard Annex #31, Unicode Identifiers and Pattern Syntax, version Unicode 8.0.0, or successor. <http://www.unicode.org/reports/tr31/>
  5. Unicode Technical Note #5: Canonical Equivalence in Applications, available at <http://www.unicode.org/notes/tn5/>
  6. Unicode Technical Standard #10: Unicode Collation Algorithm version 8.0.0, or successor, available at <http://www.unicode.org/reports/tr10/>
  7. IANA Time Zone Database at <http://www.iana.org/time-zones>
  8. ISO 8601:2004(E) Data elements and interchange formats – Information interchangeRepresentation of dates and times
  9. RFC 1738 “Uniform Resource Locators (URL)”, available at <http://tools.ietf.org/html/rfc1738>
  10. RFC 2396 “Uniform Resource Identifiers (URI): Generic Syntax”, available at <http://tools.ietf.org/html/rfc2396>
  11. RFC 3629 “UTF-8, a transformation format of ISO 10646”, available at <http://tools.ietf.org/html/rfc3629>

GCopyright & Software License#

Ecma International

Rue du Rhone 114

CH-1204 Geneva

Tel: +41 22 849 6000

Fax: +41 22 849 6001

Web: http://www.ecma-international.org

Copyright Notice

© 2016 Ecma International

This draft document may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published, and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this section are included on all such copies and derivative works. However, this document itself may not be modified in any way, including by removing the copyright notice or references to Ecma International, except as needed for the purpose of developing any document or deliverable produced by Ecma International.

This disclaimer is valid only prior to final version of this document. After approval all rights on the standard are reserved by Ecma International.

The limited permissions are granted through the standardization phase and will not be revoked by Ecma International or its successors or assigns during this time.

This document and the information contained herein is provided on an "AS IS" basis and ECMA INTERNATIONAL DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

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 http://www.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.