?
u
m
/
p
1-9
在 https://tc39.es/ecma262/ 上的文档是最准确和最新的ECMAScript规范。它包含了最新年度快照的内容以及任何已完成的提案(那些在提案流程中达到第4阶段并因此在多个实现中实现且将在下一次实际修订中包含的提案)自该快照以来的内容。
此规范在GitHub上由ECMAScript社区的帮助下开发。有多种方式可以为此规范的发展做出贡献:
有关如何创建此文档的更多信息,请参阅
此ecma标准定义了ECMAScript 2024语言。它是ECMAScript语言的第十五版 规范。自1997年第一版出版以来,ECMAScript已发展成为世界上 最广泛使用的通用编程语言。它最为人所知的是嵌入在网络中的语言 浏览器,但也被广泛用于服务器和嵌入式应用程序。
ECMAScript基于几种原始技术,最著名的是JavaScript(Netscape)和 JScript(微软)。该语言由Netscape的Brendan Eich发明,首次出现在该公司的 Navigator 2.0浏览器。它已出现在Netscape的所有后续浏览器和Netscape的所有浏览器中 Microsoft从Internet Explorer 3.0开始。
ECMAScript语言规范的开发始于1996年11月。这个的第一版 ECMA标准于1997年6月由ECMA大会通过。
该ECMA标准已提交给ISO/IEC JTC 1以供快速通道程序采用,并被批准为 国际标准ISO/IEC 16262,1998年4月。ECMA大会于1998年6月批准了第二个 ECMA-262版本,使其完全符合ISO/IEC 16262。第一个和第二个之间的变化 版本本质上是编辑性的。
标准第三版引入了强大的正则表达式、更好的字符串处理、新的控件 语句、try/catch异常处理、更严格的错误定义、数字输出的格式和次要 对未来语言增长的预期变化。ECMAScript标准的第三版被 1999年12月的ECMA大会,并于2002年6月作为ISO/IEC 16262:2002发布。
第三版发布后,ECMAScript与全球广泛采用 Web,它已成为基本上所有Web浏览器都支持的编程语言。重要的 开发ECMAScript第四版的工作已经完成。然而,这项工作没有完成,也没有出版 作为ECMAScript的第四版,但其中一些被纳入了第六版的开发。
ECMAScript第五版(作为ECMA-262 5th版发布)事实上已编纂
对浏览器实现中常见的语言规范的解释并添加了
支持自第三版出版以来出现的新功能。这些功能包括
第五版提交给ISO/IEC JTC 1采用快速通道程序,并被批准为国际标准ISO/IEC 16262:2011。ECMAScript标准的5.1版包含了一些小的修正,文本与ISO/IEC 16262:2011相同。5.1版于2011年6月被Ecma大会采纳。
第六版的集中开发始于2009年,当时第五版正在准备出版。然而,在此之前,自1999年第三版发布以来,已经进行了大量的实验和语言增强设计工作。从某种意义上说,第六版的完成是十五年努力的结晶。本版的目标包括提供对大型应用程序、库创建的更好支持,并将ECMAScript用作其他语言的编译目标。其主要增强功能包括模块、类声明、词法块作用域、迭代器和生成器、用于异步编程的Promises、解构模式和正确的尾调用。ECMAScript内置库扩展了对附加数据抽象的支持,包括地图、集合和二进制数值数组,并在字符串和正则表达式中增加了对Unicode补充字符的支持。内置库还通过子类化变得可扩展。第六版为常规的、增量的语言和库增强提供了基础。第六版于2015年6月被大会采纳。
ECMAScript 2016是Ecma TC39在新的年度发布节奏和开放开发流程下发布的第一个ECMAScript版本。从ECMAScript
2015源文档生成了一个纯文本源文档,作为在GitHub上进一步开发的基础。在这一标准的开发过程中,提交了数百个拉取请求和问题,代表了成千上万个错误修复、编辑修正和其他改进。此外,还开发了许多软件工具来帮助这一工作,包括Ecmarkup、Ecmarkdown和Grammarkdown。ES2016还包括对新幂运算符的支持,并在Array.prototype
中添加了一个名为includes
的新方法。
ECMAScript 2017引入了异步函数、共享内存和原子操作,以及一些较小的语言和库增强、错误修复和编辑更新。异步函数通过提供Promise返回函数的语法来改进异步编程体验。共享内存和原子操作引入了一种新的内存模型,允许多代理程序使用原子操作进行通信,即使在并行CPU上也能确保定义明确的执行顺序。它还包括Object上的新静态方法:Object.values
、Object.entries
和Object.getOwnPropertyDescriptors
。
ECMAScript
2018通过AsyncIterator协议和异步生成器引入了对异步迭代的支持。它还包括四个新的正则表达式特性:dotAll
标志、命名捕获组、Unicode属性转义和后行断言。最后,它还包括对象的剩余和扩展属性。
ECMAScript
2019引入了一些新的内置函数:Array.prototype
上的flat
和flatMap
用于扁平化数组,Object.fromEntries
用于直接将Object.entries
的返回值转化为新对象,以及String.prototype
上的trimStart
和trimEnd
作为更好命名的替代方案,取代广泛实现但非标准的String.prototype.trimLeft
和trimRight
内置函数。此外,它还包括一些语法和语义的较小更新。更新的语法包括可选的catch绑定参数,并允许在字符串字面量中使用U+2028(行分隔符)和U+2029(段落分隔符)以与JSON保持一致。其他更新包括要求Array.prototype.sort
为稳定排序,要求JSON.stringify
无论输入如何都返回格式良好的UTF-8,以及通过要求Function.prototype.toString
返回相应的原始源文本或标准占位符来进行明确。
ECMAScript
2020,第11版,引入了字符串的matchAll
方法,用于生成全局正则表达式匹配对象的迭代器;import()
语法,用于动态异步导入模块;BigInt
,一种新的数字原始类型,用于处理任意精度的整数;Promise.allSettled
,一种新的Promise组合器,不会短路;globalThis
,一种通用的全局this
值访问方式;专用的export * as ns from 'module'
语法,用于模块内;增加了for-in
枚举顺序的标准化;import.meta
,一个由宿主填充的对象,包含关于模块的上下文信息;以及为处理“nullish”值(
ECMAScript
2021,第12版,引入了字符串的replaceAll
方法;Promise.any
,一个在输入值被实现时短路的Promise组合器;AggregateError
,一种新错误类型,用于同时表示多个错误;逻辑赋值操作符(??=
、&&=
、||=
);WeakRef
,用于引用目标对象而不保留其免于垃圾回收,以及FinalizationRegistry
,用于管理在目标对象被垃圾回收时执行的清理操作的注册和取消注册;数字字面量的分隔符(1_000
);并且使Array.prototype.sort
更加精确,减少了导致
ECMAScript 2022,第13版,引入了顶层await
,允许在模块顶层使用关键字;新的类元素:公共和私有实例字段、公共和私有静态字段、私有实例方法和访问器、以及私有静态方法和访问器;类中的静态块,用于每类评估初始化;#x in obj
语法,用于测试对象上私有字段的存在;通过/d
标志的正则表达式匹配索引,提供匹配子字符串的起始和结束索引;Error
对象上的cause
属性,用于记录错误中的因果链;用于字符串、数组和类型化数组的at
方法,允许相对索引;以及Object.hasOwn
,Object.prototype.hasOwnProperty
的便捷替代。
ECMAScript
2023,第14版,引入了Array.prototype
和TypedArray.prototype
上的toSorted
、toReversed
、with
、findLast
和findLastIndex
方法,以及Array.prototype
上的toSpliced
方法;增加了对文件开头#!
注释的支持,以更好地促进可执行ECMAScript文件;并允许在弱集合中使用大多数符号作为键。
ECMAScript
2024,第15版,增加了调整和转移ArrayBuffers和SharedArrayBuffers大小的功能;添加了用于创建具有更高级功能的字符串集的RegExp/v
标志;引入了用于构建Promise的便捷方法Promise.withResolvers
、用于数据聚合的Object.groupBy
和Map.groupBy
方法、用于异步等待共享内存更改的Atomics.waitAsync
方法,以及用于检查和确保字符串仅包含格式良好的Unicode的String.prototype.isWellFormed
和String.prototype.toWellFormed
方法。
代表许多组织的数十个人在Ecma TC39中对这一版本的开发以及之前的版本做出了非常重要的贡献。此外,还出现了一个支持TC39的ECMAScript工作的活跃社区。这个社区审查了无数草案,提交了数千个错误报告,进行了实现实验,贡献了测试套件,并向全球开发者社区介绍了ECMAScript。不幸的是,不可能识别和感谢每一个为这项工作做出贡献的人和组织。
Allen Wirfs-Brock
ECMA-262,第六版项目编辑
Brian Terlson
ECMA-262,第七版至第十版项目编辑
Jordan Harband
ECMA-262,第十版至第十二版项目编辑
Shu-yu Guo
ECMA-262,第十二版至第十五版项目编辑
Michael Ficarra
ECMA-262,第十二版至第十五版项目编辑
Kevin Gibbons
ECMA-262,第十二版至第十五版项目编辑
本标准定义了ECMAScript 2024通用编程语言。
符合ECMAScript规范的实现必须提供并支持本规范中描述的所有类型、值、对象、属性、函数和程序语法及语义。
符合ECMAScript规范的实现必须按照最新版本的Unicode标准和ISO/IEC 10646解释源文本输入。
提供支持不同语言和国家的语言和文化习俗的应用编程接口(API)的符合ECMAScript规范的实现必须实现ECMA-402最新版本中与本规范兼容的接口。
符合ECMAScript规范的实现可以提供本规范中未描述的其他类型、值、对象、属性和函数。特别是,符合ECMAScript规范的实现可以为本规范中描述的对象提供本规范中未描述的属性和值。
符合ECMAScript规范的实现可以支持本规范中未描述的程序和正则表达式语法。特别是,符合ECMAScript规范的实现可以支持使用本规范第
符合ECMAScript规范的实现不得实现本规范第
符合ECMAScript规范的实现不得重新定义任何不是
符合ECMAScript规范的实现可以选择实现或不实现规范性可选的小节。如果实现了任何规范性可选行为,则必须实现包含的规范性可选条款中的所有行为。本规范中用彩色框中的“规范性可选”一词来表示规范性可选条款,如下所示。
示例条款内容。
符合ECMAScript规范的实现必须实现遗留小节,除非它们也被标记为规范性可选。遗留小节中指定的所有语言特性和行为都具有一个或多个不理想的特性。然而,它们在现有应用程序中的持续使用阻止了它们从本规范中删除。这些特性不被视为ECMAScript核心语言的一部分。程序员在编写新的ECMAScript代码时不应使用或假设这些特性和行为的存在。
示例条款内容。
示例条款内容。
下列引用文件对于本文档的应用是必不可少的。对于有日期的引用,仅适用于所引用的版本。对于无日期的引用,适用于引用文件的最新版本(包括任何修正案)。
Unicode 标准。
https://unicode.org/versions/latest
ISO/IEC 10646,信息技术 — 通用多八位编码字符集 (UCS) 加上修正案1:2005、修正案2:2006、修正案3:2008、修正案4:2008和其他修正案和勘误,或其后续版本。
ECMA-402,ECMAScript 国际化 API 规范,特别是与本规范版本相对应的年度版。
https://www.ecma-international.org/publications-and-standards/standards/ecma-402/
ECMA-404,JSON 数据交换格式。
https://www.ecma-international.org/publications-and-standards/standards/ecma-404/
本节包含 ECMAScript 语言的非规范性概述。
ECMAScript 是一种面向对象的编程语言,用于在 宿主环境 中执行计算和操作计算对象。本规范中定义的 ECMAScript 并不打算是计算自给自足的;实际上,本规范没有规定外部数据的输入或计算结果的输出。相反,预计 ECMAScript 程序的计算环境不仅会提供本规范中描述的对象和其他设施,还会提供某些环境特定的对象,这些对象的描述和行为超出了本规范的范围,只是表明它们可能提供某些属性可以从 ECMAScript 程序中访问和调用的函数。
ECMAScript 最初设计为一种脚本语言,但现已广泛用作通用编程语言。脚本语言 是一种用于操作、定制和自动化现有系统功能的编程语言。在这些系统中,有用的功能已经通过用户界面可用,脚本语言是将这些功能暴露给程序控制的机制。这样,现有系统就提供了一个对象和设施的 宿主环境,从而完善了脚本语言的功能。脚本语言旨在供专业和非专业程序员使用。
ECMAScript 最初设计为一种 Web 脚本语言,提供一种机制来在浏览器中使网页生动起来,并作为基于 Web 的客户端-服务器架构的一部分执行服务器计算。ECMAScript 现在用于为各种 宿主环境 提供核心脚本功能。因此,本文件中规定的核心语言与任何特定的 宿主环境 无关。
ECMAScript 的使用已经超出了简单的脚本编写,它现在用于许多不同环境和规模的全方位编程任务。随着 ECMAScript 使用范围的扩大,它提供的功能和设施也在扩展。ECMAScript 现在是一种功能齐全的通用编程语言。
Web浏览器为客户端计算提供了一个ECMAScript 宿主环境,包括表示窗口、菜单、弹出窗口、对话框、文本区域、锚点、框架、历史记录、Cookies以及输入/输出的对象。此外,宿主环境还提供了一种将脚本代码附加到事件(如焦点更改、页面和图像加载、卸载、错误和中止、选择、表单提交和鼠标操作)的方法。脚本代码出现在HTML中,显示的页面是用户界面元素和固定和计算文本及图像的组合。脚本代码对用户交互有反应,因此不需要主程序。
Web服务器为服务器端计算提供了不同的宿主环境,包括表示请求、客户端和文件的对象;以及锁定和共享数据的机制。通过结合使用浏览器端和服务器端脚本,可以在客户端和服务器之间分配计算,同时为基于Web的应用程序提供定制的用户界面。
每个支持ECMAScript的Web浏览器和服务器都提供自己的宿主环境,从而完成ECMAScript的执行环境。
为了帮助将ECMAScript集成到宿主环境中,本规范将某些功能的定义(例如,抽象操作)全部或部分地推迟到本规范之外的来源。在编辑上,本规范区分了以下几种推迟定义的方式。
实现是进一步定义附录D中列出的功能或那些标记为实现定义或实现近似的功能的外部来源。在非正式使用中,实现是指具体的人工制品,例如特定的网络浏览器。
实现定义的功能是指将其定义推迟到外部来源而没有进一步的限定。本规范对特定行为没有做出任何建议,符合规范的实现可以在本规范提出的约束范围内选择任何行为。
实现近似的功能是指将其定义推迟到外部来源,同时建议一种理想行为。虽然符合规范的实现可以在本规范提出的约束范围内选择任何行为,但鼓励它们尽量接近理想。一些数学操作,例如Math.exp
,属于实现近似。
宿主是进一步定义附录D中列出的功能,但不进一步定义其他实现定义或实现近似功能的外部来源。在非正式使用中,宿主是指以相同方式通过附录D与本规范接口的所有实现集,例如所有网络浏览器的集合。宿主通常是一个外部规范,例如WHATWG HTML (https://html.spec.whatwg.org/)。换句话说,宿主定义的功能通常在外部规范中进一步定义。
宿主挂钩 是一个由外部来源全部或部分定义的抽象操作。所有 宿主挂钩 必须列在附录 D 中。宿主挂钩 必须至少符合以下要求:
宿主定义 的功能是将其定义推迟到外部来源而没有进一步的限定,并列在附录 D 中。不是 宿主 的实现也可以提供 宿主定义 的功能定义。
宿主环境 是所有 宿主定义 功能的特定定义选择。宿主环境 通常包括允许获取输入和提供输出的对象或函数,作为 宿主定义 属性的一部分的 全局对象。
本规范遵循始终使用最具体术语的编辑约定。例如,如果一个功能是 宿主定义 的,则不应称其为 实现定义。
宿主和实现可以通过本规范中定义的语言类型、规范类型、抽象操作、语法生成、内在对象和内在符号与本规范接口。
以下是 ECMAScript 的非规范性概述,并未描述该语言的所有部分。该概述不属于标准的正式部分。
ECMAScript 是基于对象的:基本语言和宿主功能由对象提供,ECMAScript
程序是一个相互通信的对象集合。在 ECMAScript 中,对象 是具有零个或多个 属性 的集合,每个属性都有确定如何使用该属性的 特性 ——
例如,当属性的可写特性(Writable attribute)设置为
ECMAScript 定义了一组 内置对象,完善了 ECMAScript 实体的定义。这些内置对象包括 全局对象;对语言的 运行时语义 基本的对象,包括
Object
、Function
、Boolean
、Symbol
及各种 Error
对象;表示和操作数值的对象,包括 Math
、Number
和 Date
;处理文本的对象 String
和
RegExp
;值的索引集合的对象,包括 Array
和九种不同类型的元素具有特定数值表示的 Typed Arrays;键控集合,包括 Map
和 Set
对象;支持结构化数据的对象,包括 JSON
对象、ArrayBuffer
、SharedArrayBuffer
和 DataView
;支持控制抽象的对象,包括生成器函数和
Promise
对象;以及反射对象,包括 Proxy
和 Reflect
。
ECMAScript 还定义了一组内置 运算符。ECMAScript 运算符包括各种一元运算符、乘法运算符、加法运算符、位移运算符、关系运算符、相等运算符、二进制位运算符、二进制逻辑运算符、赋值运算符和逗号运算符。
大型 ECMAScript 程序由 模块 支持,允许程序划分为多个语句和声明的序列。每个模块明确标识其使用的需要由其他模块提供的声明,以及哪些声明可供其他模块使用。
ECMAScript 语法故意类似于 Java 语法。ECMAScript 语法被放宽,以使其作为一种易于使用的脚本语言。例如,变量不需要声明其类型,属性也没有关联类型,定义的函数也不需要在调用之前出现在文本上。
尽管 ECMAScript 包含类定义的语法,但 ECMAScript 对象并非如 C++、Smalltalk 或 Java 中的类为基础。相反,对象可以通过多种方式创建,包括字面量表示法或 构造函数,这些构造函数创建对象,然后通过为其属性分配初始值来初始化全部或部分对象。每个 构造函数 都是一个具有名为
new Date(2009, 11)
创建一个新的 Date 对象。不使用 new 调用 构造函数
会产生不同的结果,这取决于 构造函数。例如,Date()
生成当前日期和时间的字符串表示,而不是对象。
每个由 构造函数 创建的对象都有一个隐式引用(称为对象的
原型),指向其 构造函数 的
在基于类的面向对象语言中,通常状态由实例承载,方法由类承载,并且继承仅限于结构和行为。而在 ECMAScript 中,状态和方法由对象承载,而结构、行为和状态都是继承的。
所有不直接包含其原型所包含的特定属性的对象共享该属性及其值。图 1 说明了这一点:
CF 是一个 构造函数(也是一个对象)。通过使用
new
表达式创建了五个对象:cf1、cf2、cf3、cf4 和
cf5。这些对象每个都包含名为
与大多数基于类的对象语言不同,可以通过分配值动态地向对象添加属性。也就是说,构造函数 不需要命名或分配所有或任何构造对象的属性。在上图中,可以通过向 CFp 中的属性分配新值,为 cf1、cf2、cf3、cf4 和 cf5 添加一个新的共享属性。
尽管 ECMAScript 对象本质上不是基于类的,但根据 构造函数、原型对象和方法的共同模式定义类样抽象通常是方便的。ECMAScript 内置对象本身遵循这样的类样模式。从 ECMAScript 2015 开始,ECMAScript 语言包括语法类定义,允许程序员简洁地定义符合内置对象使用的相同类样抽象模式的对象。
ECMAScript 语言认识到某些用户可能希望限制其使用语言中某些功能的可能性。他们可能出于安全考虑,避免他们认为容易出错的功能,获得增强的错误检查,或出于其他原因。为了支持这种可能性,ECMAScript 定义了语言的严格变体。语言的严格变体排除了一些常规 ECMAScript 语言的特定语法和语义特性,并修改了某些特性的详细语义。严格变体还指定了在非严格形式的语言未指定为错误的情况下必须通过抛出错误异常来报告的其他错误条件。
ECMAScript 的严格变体通常称为语言的严格模式。严格模式的选择和 ECMAScript 严格模式语法和语义的使用明确在单个 ECMAScript 源文本 单元级别进行,如 11.2.2 中所述。由于在语法源文本单元级别选择严格模式,因此严格模式仅对该源文本单元内具有局部效果的限制。严格模式不会限制或修改必须在多个源文本单元之间一致操作的 ECMAScript 语义。完整的 ECMAScript 程序可以由严格模式和非严格模式 ECMAScript 源文本 单元组成。在这种情况下,严格模式仅在实际执行在严格模式源文本单元中定义的代码时才适用。
为了符合本规范,ECMAScript 实现必须实现完整的无限制 ECMAScript 语言和本规范定义的 ECMAScript 语言的严格变体。此外,实现必须支持将无限制和严格模式源文本单元组合成一个单一的组合程序。
在本文件中,适用以下术语和定义。
一个 实现近似 设施是由外部来源全部或部分定义的,但在本规范中有推荐的理想行为。
一个 实现定义 设施是由外部来源全部或部分定义的。
与 实现定义 相同。
编辑说明,参见 4.2 条款。
数据值集合,定义见
是 Undefined、Null、Boolean、Number、BigInt、Symbol 或 String 类型中的一个成员,定义见
原始值是在语言实现的最低层直接表示的数据。
Object 类型的成员。
对象是属性的集合,并且有一个单一的原型对象。原型可以是
构造函数的
为其他对象提供共享属性的对象。
具有所有对象必须支持的基本内部方法默认行为的对象
在一个或多个基本内部方法上不具有默认行为的对象
其语义由本规范定义的对象
由 ECMAScript 实现指定和提供的对象
标准内置对象在本规范中定义。ECMAScript 实现可以指定和提供其他种类的内置对象。
当变量未被赋值时使用的原始值
唯一值为
表示故意缺少任何对象值的原始值
唯一值为
属于
只有两个布尔值,
由原始值
属于
Boolean 对象是通过在 new
表达式中使用 Boolean
原始值,是一个
所有可能的字符串值的集合
对应双精度 64 位二进制格式
Number 值是
所有可能的 Number 值的集合,包括特殊的“非数值” (NaN) 值、正无穷大和负无穷大
属于
表示正无穷大的 Number 值
表示
对应任意精度
所有可能的 BigInt 值的集合
表示唯一的、非字符串对象
所有可能的 Symbol 值的集合
属于
除了它的属性之外,函数还包含可执行代码和状态,这些代码和状态决定了它在调用时的行为。函数的代码可以是 ECMAScript 编写的,也可以不是。
内置对象,是一个函数
内置函数的例子包括 parseInt
和 Math.exp
。
内置函数,是一个
对象的一部分,关联一个键(字符串值或 Symbol 值)和一个值
根据属性的形式,值可以直接表示为数据值(原始值、对象或
作为属性值的函数
当函数作为对象的方法调用时,对象会作为其
作为内置函数的方法
标准内置方法在本规范中定义。
定义属性某些特性的内部值
直接包含在对象中的属性
对象的属性,不是自有属性,但它是对象原型的属性(自有属性或继承属性)
本规范的其余部分组织如下:
第
第
第
第
第
一个上下文无关文法由若干生成式组成。每个生成式的左侧都有一个抽象符号,称为非终结符,右侧则是一系列零个或多个非终结符和终结符符号。对于每个文法,终结符号来自指定的字母表。
链生成式是右侧有且只有一个非终结符号以及零个或多个终结符号的生成式。
从一个由单个特殊非终结符组成的句子开始,称为目标符号,给定的上下文无关文法指定了一种语言,即通过不断将序列中的任何非终结符替换为其左侧为该非终结符的生成式的右侧所能产生的终结符号的(可能是无限的)集合。
ECMAScript 的词法文法在
除空白和注释外的输入元素构成 ECMAScript 语法文法的终结符,称为 ECMAScript 标记。这些标记是 ECMAScript 语言的 /*
…*/
的注释,不论是否跨越多行)不包含行终止符,则它同样会被丢弃;但如果
ECMAScript 的正则表达式文法在
词法和正则表达式文法的生成式通过两个冒号 “::” 作为分隔标点来区分。这两种文法共享一些生成式。
在
数值字符串文法的生成式通过三个冒号 “:::” 作为标点符号来区分,且从不用于解析源文本。
ECMAScript 的 句法文法 在
当要将代码点流解析为 ECMAScript
解析成功时,会构造一个 解析树,这是一个以根为起点的树结构,其中每个节点是一个 解析节点。每个解析节点都是文法中某个符号的实例;它表示可以从该符号派生的源文本范围。表示整个源文本的解析树的根节点是解析的
解析器的每次调用都会实例化新的解析节点,并且在解析相同源文本时永不重用。解析节点被认为是相同的解析节点,当且仅当它们表示相同的源文本范围,是相同文法符号的实例,并且是由同一次解析器调用生成的。
多次解析相同的字符串会导致不同的解析节点。例如,考虑:
let str = "1 + 1;";
eval(str);
eval(str);
每次调用 eval
都会将 str
的值转换为
句法文法的生成式通过使用一个冒号 “:” 作为标点符号来区分。
在
在某些情况下,为避免歧义,句法文法使用了泛化生成式,允许不形成有效 ECMAScript
在ECMAScript语法中,一些终结符号显示为固定宽度
字体。这些符号应当按照书写的样子准确出现在源文本中。以这种方式指定的所有终结符号码点都应被理解为来自基本拉丁块的适当Unicode码点,而不是来自其他Unicode范围的类似看起来的码点。终结符号中的一个码点不能通过\
在其终结符号是单个Unicode码点的语法中(即,词汇、RegExp和数值字符串语法),连续的多个固定宽度码点出现在一个生产中,是一种简单的速记,用于表示相同的码点序列,写作独立的终结符号。
例如,产生式:
是以下的简写形式:
相比之下,在句法语法中,连续的固定宽度码点构成一个单独的终结符号。
终结符号还有其他两种形式:
非终结符号显示为斜体类型。非终结(也称为“产生式”)的定义是由被定义的非终结名称开始,后面跟着一个或多个冒号(冒号的数量表示生产所属的语法)。然后,非终结的一个或多个备选右侧在后续行中跟随。例如,句法定义:
说明非终结while
,后跟一个左括号,然后是一个
说明一个
下标后缀“opt”,可出现在终结符或非终结符之后,表示一个可选符号。包含可选符号的替代项实际上指定了两个右侧,一个省略可选元素,一个包含它。这意味着:
是一个方便的缩写:
和:
是一个方便的缩写:
反过来又是一个缩写:
因此,在这个例子中,非终结符
一个产生式可能会被形式为“[parameters]”的下标注释参数化,它可能作为由产生式定义的非终结符号的后缀出现。“parameters”可以是单个名称或逗号分隔的名称列表。参数化的产生式是一组产生式的简写,这些产生式定义了所有参数名称的组合,这些名称由下划线前缀,并附加到参数化的非终结符号上。这意味着:
是以下的缩写:
并且:
是以下的缩写:
多个参数会产生组合数量的产生式,但并不是所有的产生式都必须在完整的语法中被引用。
产生式右侧的非终结符号的引用也可以被参数化。例如:
等同于说:
以及:
相当于:
一个非终结符的引用可能同时具有参数列表和“opt”后缀。例如:
是以下的缩写:
在右侧非终结符引用中,用“?”前缀参数名称,使得该参数值依赖于当前产生式左侧符号引用中参数名称的出现。例如:
是以下的缩写:
如果右侧的备选方案以“[+parameter]”为前缀,那么这个备选方案只在引用产生式的非终结符号时使用了指定的参数才可用。如果右侧的备选方案以“[~parameter]”为前缀,那么这个备选方案只在引用产生式的非终结符号时未使用指定的参数才可用。这意味着:
是以下的缩写:
并且:
是以下的缩写:
当语法定义中的冒号后面跟着“one of”这几个词时,它们表示接下来的每一行上的终结符号都是一个替代定义。例如,ECMAScript的词法语法包含以下产生式:
这只是一个方便的缩写,完整形式为:
如果产生式的右侧出现“[empty]”这一短语,它表示该产生式的右侧不包含任何终结符号或非终结符号。
如果短语“[lookahead = seq]”出现在产生式的右侧,它表示只有当令牌序列seq是紧随其后的输入令牌序列的前缀时,才能使用该产生式。类似地,“[lookahead ∈ set]”,其中set是一个非空的有限令牌序列集合,表示只有当set中的某个元素是紧随其后的令牌序列的前缀时,才能使用该产生式。为了方便起见,该集合也可以写作非终结符,这种情况下它代表所有非终结符可以扩展到的令牌序列的集合。如果非终结符可以扩展到无限多个不同的令牌序列,则被认为是编辑错误。
这些条件可以被否定。“[lookahead ≠ seq]”表示只有当seq不是紧随其后的输入令牌序列的前缀时,才能使用包含的产生式,“[lookahead ∉ set]”表示只有当set中的没有元素是紧随其后的令牌序列的前缀时,才能使用该产生式。
例如,给定以下定义:
定义如下:
匹配字母n
,后跟一个或多个十进制数字,第一个数字为偶数,或一个十进制数字,后面没有跟随另一个十进制数字。
注意,当这些短语在句法语法中使用时,可能无法明确识别紧随其后的令牌序列,因为确定后续的令牌需要知道在后续位置使用哪个词法目标符号。因此,当这些短语在句法语法中使用时,如果词法目标符号的选择可能会改变seq是否会成为生成的令牌序列的前缀,那么在前视限制中出现令牌序列seq(包括作为序列集合的一部分)被认为是编辑错误。
如果在句法文法的生成式右侧出现短语“[no
表示如果在脚本中 throw
标记和
除非受限生成式禁止出现
生成式的右侧可以使用短语“but not”并指示要排除的扩展来指定不允许某些扩展。例如,生成式:
意味着非终结符
最后,在一些列出所有替代方案不切实际的情况下,使用无衬线字体的描述性短语来描述少数非终结符号:
该规范经常使用编号列表来指定算法中的步骤。这些算法用于精确指定 ECMAScript 语言结构的所需语义。这些算法并不意味着必须使用任何特定的实现技术。实际上,可能有更有效的算法可用于实现给定的功能。
算法可以明确地用一个有序的、逗号分隔的别名序列参数化,这些别名在算法步骤中可用于引用在该位置传入的参数。可选参数用方括号([ , name
])表示,与算法步骤中的必需参数没有区别。参数列表的末尾可以出现一个剩余参数,以省略号(, ...name)表示。剩余参数捕获所有在必需参数和可选参数之后提供的参数,这些参数被编入一个
算法步骤可以细分为顺序子步骤。子步骤是缩进的,并且本身可以进一步分为缩进的子步骤。用大纲编号约定来标识子步骤,第一层子步骤用小写字母标记,第二层子步骤用小写罗马数字标记。如果需要超过三个层级,这些规则将重复,第四层使用数字标签。例如:
步骤或子步骤可以作为一个“if”谓词编写,条件化其子步骤。在这种情况下,只有当谓词为真时,子步骤才会被应用。如果步骤或子步骤以“else”一词开头,它是一个谓词,是与同一层级前一个“if”谓词步骤的否定。
步骤可以指定其子步骤的迭代应用。
以“Assert(断言):”开头的步骤断言其算法的不变条件。这种断言用来明确那些否则会是隐含的算法不变性。这样的断言不增加额外的语义要求,因此实现无需检查。它们仅用于澄清算法。
算法步骤可以使用“Let x be someValue”的形式声明任何值的命名别名。这些别名类似于引用,x和someValue都指向相同的底层数据,对任何一个的修改都对双方可见。如果算法步骤想要避免这种类似引用的行为,应该明确地复制右侧值:“Let x be a copy of someValue”创建了someValue的一个浅拷贝。
一旦声明,别名可以在任何后续步骤中被引用,并且不能从别名声明之前的步骤中被引用。别名可以使用“Set x to someOtherValue”的形式进行修改。
为了便于在本规范的多个部分中使用,一些算法被称为抽象操作,它们被命名并以参数化的函数形式编写,以便可以从其他算法中通过名称引用它们。抽象操作通常使用函数应用风格引用,如 OperationName(arg1, arg2)。一些抽象操作被视为类似类的规范抽象中多态分派的方法。这种类似方法的抽象操作通常使用方法应用风格引用,例如 someValue.OperationName(arg1, arg2)。
一个语法导向操作是一个命名操作,其定义包括多个算法,每个算法都与ECMAScript语法之一的一个或多个产生式相关联。具有多个替代定义的产生式通常会为每个替代定义有一个独特的算法。当一个算法与一个语法产生式相关联时,它可以引用产生式替代的终结符和非终结符,就好像它们是算法的参数一样。在这种方式下使用时,非终结符引用在解析源文本时匹配的实际替代定义。由语法产生式匹配的源文本或由其衍生的
当一个算法与一个产生式替代相关联时,该替代通常显示时不包括任何“[ ]”语法注释。这样的注释只应影响替代的语法识别,对替代的相关语义没有影响。
语法导向操作通过使用下列算法中的步骤
除非另有明确规定,所有
但是
运行时语义:
需要在运行时调用以指定语义的算法称为运行时语义。运行时语义由
抽象操作完成接受参数completionRecord(一个
算法步骤中提到抛出异常的,如:
意味着与以下内容相同:
算法步骤中提到或等同于以下内容:
意味着:
算法步骤中提到或等同于:
意味着:
hygienicTemp 是短暂的,仅在涉及 ReturnIfAbrupt 的步骤中可见。
算法步骤中提到或等同于:
意味着:
在?
表示应当应用
等同于以下步骤:
同样,对于方法应用风格,步骤:
等同于:
同样地,前缀!
用来表示以下对抽象或
等同于以下步骤:
!
或?
:
在声明返回
如果通过任何其他方式从这样的抽象操作中返回
意味着与任何一种
或
或
注意,通过
以下示例将是一个编辑错误,因为在该步骤中没有注明正在返回
无上下文语法并不足以表达所有定义流式输入元素是否形成可评估的 ECMAScript
静态语义规则具有名称,并通常使用算法定义。命名的静态语义规则与语法产生式相关联,具有多个备选定义的产生式通常对每个适用的命名静态语义规则有一个单独的算法。
静态语义规则的一种特殊类型是早期错误规则。
本规范参考以下数值类型:
在本规范的术语中,数值使用下标后缀来区分不同的数值类型。下标 𝔽 表示数字(Numbers),下标 ℤ 表示大整数(BigInts)。没有下标后缀的数值指代
数值运算符(如 +、×、= 和 ≥)根据操作数的类型确定其操作。当应用于
一般来说,当本规范提到数值时,例如“y 的长度”或“由四位十六进制数字表示的
不定义混合类型操作数(例如数字和
本规范中大多数数值以十进制表示;同时也使用形如 0x 后跟数字 0-9 或 A-F 的十六进制值。
当本规范中使用术语 整数 时,指的是在
本文档中对
数学函数
数学函数
记法 “
短语 "将 x 夹在 lower 和 upper 之间"(其中 x 是
数学函数
数学函数
数学函数
从下界 a 到上界 b 的 区间 是可能是无限的、可能为空的、相同数值类型的数值集合。每个边界都将描述为包含或排除,但不会同时包含。有四种类型的区间,如下所示:
例如,从 1(包含)到 2(排除)的
在本规范中,Function.prototype.apply
或 let n = 42;
区分开来。
在本规范中,规范值和
从本规范的角度来看,“is”一词用于比较两个值是否相等,例如“如果bool为
从 ECMAScript 语言的角度来看,语言值使用
对于规范值,没有规范身份的值包括但不限于:
规范身份对于所有
本规范中的算法操作值,每个值都有一个关联的类型。可能的值类型正是本条款中定义的那些类型。类型进一步分为
在本规范中,“Type(x)”表示“x的类型”,其中“类型”指的是本条款中定义的ECMAScript语言和规范类型。
ECMAScript 语言类型对应于由 ECMAScript 程序员直接使用 ECMAScript 语言操作的值。ECMAScript 语言类型包括 Undefined、Null、Boolean、String、Symbol、Number、BigInt 和 Object。一个ECMAScript 语言值是由 ECMAScript 语言类型特征化的值。
Undefined 类型恰好有一个值,称为
Null 类型恰好有一个值,称为
Boolean 类型表示具有两个值的逻辑实体,称为
String 类型是所有有序序列的集合,这些序列由零个或多个 16
位无符号
不解释 String 内容的 ECMAScript 操作不应用进一步的语义。对解释 String 值的操作将每个元素视为单个 UTF-16 代码单元。然而,ECMAScript 不限制这些代码单元的值或关系,因此进一步解释 String 内容为 UTF-16 编码的 Unicode 代码点序列的操作必须考虑到格式不正确的子序列。这些操作对于每个数值位于从 0xD800 到 0xDBFF(由 Unicode 标准定义为leading surrogate,或更正式地称为high-surrogate code unit)的代码单元,以及每个数值位于从 0xDC00 到 0xDFFF(定义为trailing surrogate,或更正式地称为low-surrogate code unit)的代码单元使用以下规则:
函数 String.prototype.normalize
(参见22.1.3.15)可以用来显式标准化一个字符串值。String.prototype.localeCompare
(参见22.1.3.12)在内部标准化字符串值,但其他操作不会隐式地标准化它们操作的字符串。操作结果除非另有说明,否则不受语言和/或地区的影响。
这种设计背后的理念是为了保持字符串的实现尽可能简单和高效。如果ECMAScript源代码文本处于规范形式C,只要它们不包含任何Unicode转义序列,字符串字面值也保证是标准化的。
在这个规范中,“字符串连接 A、B 等...”(每个参数是一个字符串值、代码单元或代码单元的序列)表示的是一个字符串值,其代码单元的序列是每个参数(按顺序)的代码单元的连接(按顺序)。
短语“从 inclusiveStart 到 exclusiveEnd 的 子字符串”(其中 S 是一个字符串值或代码单元序列,而 inclusiveStart 和 exclusiveEnd 是整数)表示由 S 的连续代码单元组成的字符串值,开始于索引 inclusiveStart 并在索引 exclusiveEnd 之前立即结束(当 inclusiveStart = exclusiveEnd 时为空字符串)。如果省略了“to”后缀,则使用 S 的长度作为 exclusiveEnd 的值。
短语“ASCII 单词字符”表示以下字符串值,它仅由 Unicode 基本拉丁语块中的每个字母和数字以及
U+005F(下划线)组成:
出于历史原因,它对各种算法具有重要意义。
抽象操作 StringIndexOf 接受参数 string(一个字符串)、searchValue(一个字符串)和 fromIndex
(一个非负
如果 searchValue 是空字符串且 fromIndex ≤ string 的长度,该算法返回 fromIndex。空字符串实际上在字符串中的每个位置都能找到,包括在最后一个码位之后。
如果 fromIndex 加上 searchValue 的长度大于 string 的长度,该算法总是返回 -1。
符号类型 是可以用作对象属性键的所有非字符串值的集合(
每个可能的符号值都是唯一且不可变的。
每个符号值不可变地持有一个关联的值,称为 [[Description]],它要么是
众所周知的符号是本规范算法明确引用的内建符号值。它们通常用作属性的键,这些属性的值作为规范算法的扩展点。除非另有说明,否则众所周知的符号值在所有
在本规范中,一个众所周知的符号用 @@name 的形式表示,其中“name”是
规范名称 | [[Description]] | 值和用途 |
---|---|---|
@@asyncIterator |
|
一个方法,返回对象的默认异步迭代器。由for -await -of 语句的语义调用。
|
@@hasInstance |
|
一个方法,确定构造函数对象是否将某个对象识别为其实例之一。由instanceof 运算符的语义调用。
|
@@isConcatSpreadable |
|
一个布尔值属性,如果为true,表示对象应通过Array.prototype.concat |
@@iterator |
|
一个方法,返回对象的默认迭代器。由for-of语句的语义调用。 |
@@match |
|
一个正则表达式方法,将正则表达式与字符串匹配。由String.prototype.match |
@@matchAll |
|
一个正则表达式方法,返回一个迭代器,该迭代器生成正则表达式与字符串匹配的所有结果。由String.prototype.matchAll |
@@replace |
|
一个正则表达式方法,替换字符串中的匹配子字符串。由String.prototype.replace |
@@search |
|
一个正则表达式方法,返回匹配正则表达式的字符串中的索引。由String.prototype.search |
@@species |
|
一个函数值属性,是用于创建派生对象的构造函数。 |
@@split |
|
一个正则表达式方法,在匹配正则表达式的索引处分割字符串。由String.prototype.split |
@@toPrimitive |
|
一个方法,将对象转换为相应的原始值。由 |
@@toStringTag |
|
一个字符串值属性,用于创建对象的默认字符串描述。由内建方法Object.prototype.toString |
@@unscopables |
|
一个对象值属性,其自身和继承的属性名称是从相关对象的with 环境绑定中排除的属性名称。
|
ECMAScript 有两种内建的数字类型:Number 和 BigInt。以下
由于数值类型通常不能在不损失精度或截断的情况下相互转换,ECMAScript语言不提供这些类型之间的隐式转换。在调用需要另一种类型的函数时,程序员必须显式调用 Number
和
BigInt
函数进行类型转换。
ECMAScript 的早期和后续版本为某些运算符提供了隐式数值转换,这可能会损失精度或
数字类型(Number type)具有精确的
18,437,736,874,454,810,627
(即 NaN
产生。)在一些实现中,外部代码可能能够检测到各种不同的非数值,但这种行为是
还有另外两个特殊值,分别称为 +Infinity
(或简单地
Infinity
)和 -Infinity
产生。)
其余的 18,437,736,874,454,810,624(即
注意,这里有一个 +0
(或简单地 0
)和 -0
产生。)
18,437,736,874,454,810,622(即
18,428,729,675,200,069,632(即
其中,s 可以是 1 或 -1,m 是一个
剩余的 9,007,199,254,740,990(即
其中,s 可以是 1 或 -1,m 是一个
注意,在 Number 类型中,所有不大于 2
一个
一些 ECMAScript 运算符只处理特定范围内的
抽象操作 Number::unaryMinus 接受参数 x(一个 Number),并返回一个 Number。调用时执行以下步骤:
抽象操作 Number::bitwiseNOT 接受参数 x(一个 Number),并返回一个
抽象操作 Number::exponentiate 接受参数 base(一个 Number)和 exponent(一个 Number),并返回一个
Number。它返回一个
当 base 是 **
exponent 的结果与
抽象操作 Number::multiply 接受参数 x(一个 Number)和 y(一个 Number),返回一个 Number。它根据
抽象操作 Number::divide 接受参数 x(一个 Number)和 y(一个 Number),返回一个 Number。
它根据
抽象操作 Number::remainder 接受参数 n(一个 Number)和 d(一个 Number),返回一个 Number。 它返回其操作数的隐含除法的余数,其中 n 是被除数,d 是除数。调用时执行以下步骤:
在 C 和 C++ 中,取余运算符只接受整数操作数;在 ECMAScript 中,它也接受浮点操作数。
%
运算符计算的“余数”操作不同,后者由 %
以类似于 Java 抽象操作 Number::add 接受参数 x(一个 Number)和 y(一个 Number),返回一个
Number。它根据
抽象操作 Number::subtract 接受参数 x(一个 Number)和 y(一个 Number),返回一个 Number。它执行减法运算,生成其操作数的差;x 是被减数,y 是减数。调用时执行以下步骤:
总是有 x - y
的结果与 x + (-y)
相同。
抽象操作 Number::leftShift 接受参数 x(一个 Number)和 y(一个 Number),返回一个整数 Number。调用时执行以下步骤:
抽象操作 Number::signedRightShift 接受参数 x(一个 Number)和 y(一个 Number),返回一个整数 Number。调用时执行以下步骤:
抽象操作 Number::unsignedRightShift 接受参数 x(一个 Number)和 y(一个 Number),返回一个整数 Number。调用时执行以下步骤:
抽象操作 Number::lessThan 接受参数 x(一个 Number)和 y(一个 Number),返回一个布尔值或
抽象操作 Number::equal 接受参数 x(一个 Number)和 y(一个 Number),返回一个布尔值。调用时执行以下步骤:
抽象操作 Number::sameValue 接受参数 x(一个 Number)和 y(一个 Number),返回一个布尔值。调用时执行以下步骤:
抽象操作 Number::sameValueZero 接受参数 x(一个 Number)和 y(一个 Number),返回一个布尔值。调用时执行以下步骤:
抽象操作 Number::NumberBitwiseOp 接受参数 op(&
、^
或
|
)、x(一个 Number)和 y(一个 Number),返回一个
&
,则^
,则|
。
抽象操作 Number::bitwiseAND 接受参数 x(一个 Number)和 y(一个 Number),返回一个
&
,
x, y).
抽象操作 Number::bitwiseXOR 接受参数 x(一个 Number)和 y(一个 Number),返回一个
^
,
x, y).
抽象操作 Number::bitwiseOR 接受参数 x(一个 Number)和 y(一个 Number),返回一个
|
,
x, y).
抽象操作 Number::toString 接受参数 x(一个数字)和 radix(一个在 2 到 36 之间的整数),并返回一个字符串。它使用以
radix 为基数的进位制系统将 x 表示为字符串。使用基数 r 表示数字时所用的数字取自
1.2e+3
。
ECMAScript 的实现者可能会发现 David M. Gay 撰写的关于浮点数二进制到十进制转换的论文和代码很有用:
Gay, David M. 正确舍入的二进制-十进制和十进制-二进制转换。数值分析,手稿 90-10。AT&T 贝尔实验室(新泽西州默里山)。1990 年 11 月 30 日。
可在
http://ampl.com/REFS/abstracts.html#rounding
获取。
相关代码可在
http://netlib.sandia.gov/fp/dtoa.c 和
http://netlib.sandia.gov/fp/g_fmt.c 获取,并且可能在各个
netlib
镜像站点上找到。
BigInt 类型 表示一个
抽象操作 BigInt::unaryMinus 接受参数 x(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:
抽象操作 BigInt::bitwiseNOT 接受参数 x(一个 BigInt)并返回一个 BigInt。 它返回 x 的按位取反。它在被调用时执行以下步骤:
抽象操作 BigInt::exponentiate 接受参数 base(一个 BigInt)和 exponent(一个 BigInt),并返回一个包含 BigInt 的正常完成或抛出完成。它在被调用时执行以下步骤:
抽象操作 BigInt::multiply 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:
抽象操作 BigInt::divide 接受参数 x(一个 BigInt)和 y(一个 BigInt),并返回一个包含 BigInt 的正常完成或抛出完成。它在被调用时执行以下步骤:
抽象操作 BigInt::remainder 接受参数 n(一个 BigInt)和 d(一个 BigInt),并返回一个
抽象操作 BigInt::add 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:
抽象操作 BigInt::subtract 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:
抽象操作 BigInt::leftShift 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:
抽象操作 BigInt::signedRightShift 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:
抽象操作 BigInt::unsignedRightShift 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个
抽象操作 BigInt::lessThan 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个布尔值。它在被调用时执行以下步骤:
抽象操作 BigInt::equal 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个布尔值。它在被调用时执行以下步骤:
抽象操作 BinaryAnd 接受参数 x(0 或 1)和 y(0 或 1)并返回 0 或 1。它在被调用时执行以下步骤:
抽象操作 BinaryOr 接受参数 x(0 或 1)和 y(0 或 1)并返回 0 或 1。它在被调用时执行以下步骤:
抽象操作 BinaryXor 接受参数 x(0 或 1)和 y(0 或 1)并返回 0 或 1。它在被调用时执行以下步骤:
抽象操作 BigInt位运算 接受参数 op(&
、
^
或 |
)、x(一个 BigInt)和 y(一个 BigInt)并返回一个
BigInt。它在被调用时执行以下步骤:
&
,那么
|
,那么
抽象操作 BigInt::bitwiseAND 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在调用时执行以下步骤:
&
,
x, y)。
抽象操作 BigInt::bitwiseXOR 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在调用时执行以下步骤:
^
,
x, y)。
抽象操作 BigInt::bitwiseOR 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在调用时执行以下步骤:
|
,
x, y)。
抽象操作 BigInt::toString 接受参数 x(一个 BigInt)和 radix(一个在 2 到 36 之间的整数)并返回一个字符串。它使用基数
radix 将 x 表示为字符串。使用基数 r 表示 BigInt 的数字取自
每个 对象类型 的实例,也简称为“一个对象”,表示一个属性的集合。每个属性要么是一个数据属性,要么是一个访问器属性:
对象的属性使用属性键唯一标识。一个 属性键
要么是一个字符串,要么是一个符号。所有字符串和符号,包括空字符串,都可以作为属性键。一个 属性名 是一个
一个 整数索引 是一个
属性键用于访问属性和它们的值。属性访问有两种类型:获取 和 设置,分别对应于值的检索和赋值。通过获取和设置访问的属性包括 自有属性 和 继承属性。继承属性可能是关联对象的自有属性或继承属性。每个对象的自有属性必须具有与其他自有属性不同的键值。
所有对象在逻辑上都是属性的集合,但有多种形式的对象,它们的属性访问和操作语义不同。请参见
此外,一些对象是可调用的;这些被称为函数或
属性用于在本规范中定义和解释对象属性的状态,如
属性名称 | 存在的属性类型 | 值域 | 默认值 | 描述 |
---|---|---|---|---|
[[Value]] |
|
|
|
通过获取属性访问检索到的值。 |
[[Writable]] |
|
布尔值 |
|
如果为 |
[[Get]] |
|
对象或 |
|
如果值 |
[[Set]] |
|
对象或 |
|
如果值 |
[[Enumerable]] |
|
一个布尔值 |
|
如果 |
[[Configurable]] |
|
一个布尔值 |
|
如果 |
在 ECMAScript 中,对象的实际语义是通过称为 内部方法 的算法指定的。每个 ECMAScript 引擎中的对象都与一组内部方法相关联,这些方法定义了其运行时行为。这些内部方法不是 ECMAScript 语言的一部分。它们纯粹是为了说明目的而由本规范定义的。然而,ECMAScript 实现中的每个对象必须按照与其相关联的内部方法指定的行为方式行事。实现的具体方式由实现决定。
内部方法名称是多态的。这意味着不同的对象值在调用相同的内部方法名称时可能会执行不同的算法。实际调用内部方法的对象是调用的“目标”。如果在运行时,算法的实现尝试使用对象不支持的内部方法,则会抛出
内部槽对应于与对象相关联并被各种 ECMAScript 规范算法使用的内部状态。内部槽不是对象属性,也不会被继承。
根据特定的内部槽规范,这种状态可能由任何
所有对象都有一个名为 [[PrivateElements]] 的内部槽,它是一个
内部方法和内部槽在本规范中使用双括号 [[ ]] 括起来的名称进行标识。
一个 普通对象 是满足以下所有条件的对象:
一个 异域对象 是一个不是
本规范通过这些对象的内部方法识别不同种类的
除了其参数外,内部方法总是可以访问作为方法调用目标的对象。
内部方法隐式返回一个
内部方法 | 签名 | 描述 |
---|---|---|
[[GetPrototypeOf]] | ( ) → Object | Null |
确定为该对象提供继承属性的对象。 |
[[SetPrototypeOf]] | (Object | Null) → Boolean |
将该对象与提供继承属性的另一个对象关联。传递 |
[[IsExtensible]] | ( ) → Boolean | 确定是否允许向该对象添加更多属性。 |
[[PreventExtensions]] | ( ) → Boolean |
控制是否可以向该对象添加新属性。返回 |
[[GetOwnProperty]] |
(propertyKey) → Undefined | |
返回该对象自身属性的 |
[[DefineOwnProperty]] | (propertyKey, 属性描述符) → Boolean |
创建或修改自身属性,其键为 propertyKey,具有 属性描述符 描述的状态。返回 |
[[HasProperty]] | (propertyKey) → Boolean | 返回一个布尔值,指示该对象是否已经具有键为 propertyKey 的自身或继承属性。 |
[[Get]] | (propertyKey, Receiver) → any |
从该对象返回键为 propertyKey 的属性的值。如果需要执行 ECMAScript 代码来检索属性值,Receiver 用作评估代码时的
|
[[Set]] | (propertyKey, value, Receiver) → Boolean |
将键为 propertyKey 的属性的值设置为 value。如果需要执行 ECMAScript
代码来设置属性值,Receiver 用作评估代码时的 |
[[Delete]] | (propertyKey) → Boolean |
从该对象中删除键为 propertyKey 的自身属性。如果属性未删除且仍存在,返回 |
[[OwnPropertyKeys]] |
( ) → |
返回一个 |
内部方法 | 签名 | 描述 |
---|---|---|
[[Call]] |
(any, a |
执行与此对象关联的代码。通过函数调用表达式调用。内部方法的参数是一个 |
[[Construct]] |
(a |
创建一个对象。通过 new 运算符或 super 调用调用。内部方法的第一个参数是一个 super
调用的参数。第二个参数是最初应用 new 运算符的对象。实现此内部方法的对象称为 |
普通对象和标准异域对象的基本内部方法的语义在第
ECMAScript引擎中对象的内部方法必须符合下面指定的不变性列表。普通ECMAScript对象以及本规范中的所有标准
任何实现提供的
实现不得以任何方式允许绕过这些不变性,例如通过提供实现基本内部方法功能的替代接口而不强制执行其不变性。
任何内部方法返回的值必须是一个
由于第三个不变性的结果,如果一个属性被描述为
众所周知的内在对象是内置对象,它们在本规范的算法中被明确引用,并且通常具有与
在本规范中,诸如%name%的引用意味着与当前
内置名称 | 全局名称 | ECMAScript 语言关联 |
---|---|---|
|
AggregateError
|
AggregateError |
|
Array
|
Array |
|
ArrayBuffer
|
ArrayBuffer |
|
数组迭代器对象的原型 ( |
|
|
async-from-sync 迭代器对象的原型 ( |
|
|
异步函数对象的 |
|
|
异步迭代器对象的 |
|
|
所有标准内置异步迭代器对象间接继承的对象 | |
|
Atomics
|
Atomics 对象 ( |
|
BigInt
|
BigInt |
|
BigInt64Array
|
BigInt64Array |
|
BigUint64Array
|
BigUint64Array |
|
布尔值
|
布尔值 |
|
数据视图
|
数据视图 |
|
Date
|
Date |
|
decodeURI
|
decodeURI 函数 ( |
|
decodeURIComponent
|
decodeURIComponent 函数 ( |
|
encodeURI
|
encodeURI 函数 ( |
|
encodeURIComponent
|
encodeURIComponent 函数 ( |
|
Error
|
Error |
|
eval
|
eval 函数 ( |
|
EvalError
|
EvalError |
|
FinalizationRegistry
|
|
|
Float32Array
|
Float32Array |
|
Float64Array
|
Float64Array |
|
For-In 迭代器对象的原型 ( |
|
|
Function
|
Function |
|
生成器的构造函数 ( |
|
|
Int8Array
|
Int8Array |
|
Int16Array
|
Int16Array |
|
Int32Array
|
Int32Array |
|
isFinite
|
isFinite 函数 ( |
|
isNaN
|
isNaN 函数 ( |
|
所有标准内置迭代器对象间接继承的对象 | |
|
JSON
|
JSON 对象 ( |
|
Map
|
Map |
|
Map 迭代器对象的原型 ( |
|
|
Math
|
Math 对象 ( |
|
Number
|
Number |
|
Object
|
Object |
|
parseFloat
|
parseFloat 函数 ( |
|
parseInt
|
parseInt 函数 ( |
|
Promise
|
Promise |
|
Proxy
|
Proxy |
|
RangeError
|
RangeError |
|
ReferenceError
|
ReferenceError |
|
Reflect
|
Reflect 对象 ( |
|
RegExp
|
RegExp |
|
正则表达式字符串迭代器对象的原型 ( |
|
|
Set
|
Set |
|
Set 迭代器对象的原型 ( |
|
|
SharedArrayBuffer
|
SharedArrayBuffer |
|
String
|
String |
|
字符串迭代器对象的原型 ( |
|
|
Symbol
|
Symbol |
|
SyntaxError
|
SyntaxError |
|
一个 |
|
|
所有类型化数组 |
|
|
TypeError
|
TypeError |
|
Uint8Array
|
Uint8Array |
|
Uint8ClampedArray
|
Uint8ClampedArray |
|
Uint16Array
|
Uint16Array |
|
Uint32Array
|
Uint32Array |
|
URIError
|
URIError |
|
WeakMap
|
WeakMap |
|
WeakRef
|
|
|
WeakSet
|
WeakSet |
在
规范类型对应于在算法中使用的元值,用于描述 ECMAScript 语言结构和
枚举是规范内部的值,不能直接从 ECMAScript 代码中观察到。枚举用
列表类型用于解释参数列表的评估(参见 new
表达式、函数调用和其他需要简单有序值列表的算法中。列表类型的值是包含各个值的列表元素的简单有序序列。这些序列可以是任意长度的。列表元素可以使用基于 0
的索引随机访问。为了表示方便,可以使用类似数组的语法来访问列表元素。例如,arguments[2] 是表示列表 arguments 的第 3 个元素的简写。
当算法迭代列表元素而不指定顺序时,使用的顺序是列表中元素的顺序。
为了在本规范中表示方便,可以使用字面量语法来表示新的列表值。例如,« 1, 2 » 定义了一个包含两个元素的列表值,每个元素初始化为特定值。一个新的空列表可以表示为 « »。
在本规范中,短语“列表连接 A、B、...”(其中每个参数是一个可能为空的列表)表示一个新列表值,其元素是每个参数(按顺序)的元素(按顺序)的连接。
记录类型用于描述本规范算法中的数据聚合。记录类型值由一个或多个命名字段组成。每个字段的值是一个
为了在本规范中表示方便,可以使用类似对象字面量的语法来表示记录值。例如,{ [[Field1]]: 42, [[Field2]]:
在规范文本和算法中,可以使用点表示法来引用记录值的特定字段。例如,如果 R 是前一段中显示的记录,则 R.[[Field2]] 是“R 中名为 [[Field2]] 的字段”的简写。
常用记录字段组合的模式可以命名,并且该名称可以用作字面量记录值的前缀,以标识所描述的特定聚合类型。例如:PropertyDescriptor { [[Value]]:
42, [[Writable]]:
集合类型用于解释
关系类型用于解释对集合的约束。关系类型的值是其值域中值的有序对集合。例如,事件上的关系是事件的有序对集合。对于关系 R 和 R 值域中的两个值 a 和 b,a R b 是表示有序对 (a, b) 是 R 成员的简写。关系在某些条件下是最小的,当它是满足这些条件的最小关系时。
严格偏序是满足以下条件的关系值 R:
对于 R 域中的所有 a、b 和 c:
上述两个属性分别称为非自反性和传递性。
严格全序是满足以下条件的关系值 R:
对于 R 域中的所有 a、b 和 c:
上述三个属性分别称为完全性、非自反性和传递性。
完成记录规范类型用于解释值和控制流的运行时传播,例如执行非本地控制转移的语句(break
、continue
、return
和 throw
)的行为。
完成记录具有
以下简短术语有时用于指代完成记录。
本规范中定义的可调用对象仅返回正常完成或抛出完成。返回任何其他类型的完成记录被视为编辑错误。
抽象操作 NormalCompletion 接受参数 value(任何值,除了
抽象操作 ThrowCompletion 接受参数 value(一个
抽象操作 UpdateEmpty 接受参数 completionRecord(一个
引用记录类型用于解释
delete
、typeof
、赋值运算符、super
引用记录是已解析的名称或属性绑定;其字段由
字段名称 | 值 | 含义 |
---|---|---|
[[Base]] | 一个 |
持有绑定的值或 |
[[ReferencedName]] | 字符串、符号或 |
绑定的名称。如果 [[Base]] 值是 |
[[Strict]] | 布尔值 | |
[[ThisValue]] | 一个 |
如果不是 super |
以下
抽象操作 IsPropertyReference 接受参数 V(一个
抽象操作 IsUnresolvableReference 接受参数 V(一个
抽象操作 IsSuperReference 接受参数 V(一个
抽象操作 IsPrivateReference 接受参数 V(一个
抽象操作 GetValue 接受参数 V(一个
抽象操作 PutValue 接受参数 V(一个
抽象操作GetThisValue接受参数V(一个
抽象操作InitializeReferencedBinding接受参数V(一个
抽象操作MakePrivateReference接受参数baseValue(一个
属性描述符类型用于解释对象属性属性的操作和具体化。属性描述符是一个
属性描述符值可以根据某些字段的存在或使用进一步分类为数据属性描述符和访问器属性描述符。数据属性描述符是包含名为[[Value]]或[[Writable]]的字段的描述符。访问器属性描述符是包含名为[[Get]]或[[Set]]的字段的描述符。任何属性描述符都可能包含名为[[Enumerable]]和[[Configurable]]的字段。属性描述符值不能同时是数据属性描述符和访问器属性描述符;然而,它可以既不是(在这种情况下,它是一个通用属性描述符)。一个完全填充的属性描述符是访问器属性描述符或数据属性描述符,并且具有
以下
抽象操作IsAccessorDescriptor接受参数Desc(一个
抽象操作IsDataDescriptor接受参数Desc(一个
抽象操作IsGenericDescriptor接受参数Desc(一个
抽象操作FromPropertyDescriptor接受参数Desc(一个
抽象操作ToPropertyDescriptor接受参数Obj(一个
抽象操作CompletePropertyDescriptor接受参数Desc(一个
抽象闭包规范类型用于引用算法步骤以及一组值。抽象闭包通过函数应用风格调用,例如closure(arg1, arg2)。与
在创建抽象闭包的算法步骤中,值通过“捕获”动词后跟别名列表来捕获。当创建抽象闭包时,它会捕获创建时与每个别名关联的值。在指定抽象闭包被调用时要执行的算法步骤中,每个捕获的值通过用于捕获该值的别名来引用。
如果抽象闭包返回一个
抽象闭包作为其他算法的一部分内联创建,如下例所示。
数据块规范类型用于描述一个独特且可变的字节大小(8位)数值序列。字节值是一个
为了在本规范中表示方便,可以使用类似数组的语法来访问数据块值的各个字节。这种表示法将数据块值呈现为从0开始的
驻留在可以被多个
共享数据块的语义通过
以下
抽象操作CreateByteDataBlock接受参数size(一个非负
抽象操作 CreateSharedByteDataBlock 接受参数 size(一个非负的
抽象操作 CopyDataBlockBytes 接受参数 toBlock(一个
私有元素类型是一个
私有元素类型的值是
字段名称 | [[Kind]] 字段值 | 值 | 含义 |
---|---|---|---|
[[Key]] | 所有 |
一个 |
字段、方法或访问器的名称。 |
[[Kind]] | 所有 |
|
元素的种类。 |
[[Value]] |
|
一个 |
字段的值。 |
[[Get]] |
|
一个 |
私有访问器的 getter。 |
[[Set]] |
|
一个 |
私有访问器的 setter。 |
类字段定义类型是一个
类字段定义类型的值是
私有名称规范类型用于描述一个全局唯一的值(不同于任何其他私有名称,即使它们在其他方面无法区分),该值表示私有类元素(字段、方法或访问器)的键。每个私有名称都有一个关联的不可变 [[Description]],它是一个
类静态块定义记录是一个
类静态块定义记录的字段列在
这些操作不是 ECMAScript 语言的一部分;它们在这里仅用于帮助规范 ECMAScript 语言的语义。其他更专业的
ECMAScript 语言在需要时隐式执行自动类型转换。为了阐明某些结构的语义,定义了一组转换
ECMAScript 语言中的
抽象操作 ToPrimitive 接受参数 input(一个
当 ToPrimitive 被调用时不带提示时,它的行为通常类似于提示为
抽象操作 OrdinaryToPrimitive 接受参数 O(一个对象)和 hint
(
抽象操作 ToBoolean 接受参数 argument(一个
抽象操作 ToNumeric 接受参数 value(一个
抽象操作 ToNumber 接受参数 argument(一个
抽象操作
所有未明确定义的语法符号均使用词法语法中为数字字面量定义的定义(
抽象操作 StringToNumber 接受参数 str(一个字符串)并返回一个数字。 当调用时,它执行以下步骤:
语法导向操作
将
它在以下产生式上分段定义:
抽象操作 RoundMVResult 接受参数 n(一个
抽象操作 ToIntegerOrInfinity 接受参数 argument(一个
抽象操作 ToInt32 接受参数 argument(一个
根据上述 ToInt32 的定义:
抽象操作 ToUint32 接受参数 argument(一个
抽象操作 ToInt16 接受参数 argument(一个
抽象操作 ToUint16 接受参数 argument(一个
根据上述 ToUint16 的定义:
抽象操作 ToInt8 接受参数 argument(一个
抽象操作ToUint8接受参数argument(一个ECMAScript语言值),并返回一个包含整数Number的正常完成或一个抛出完成。它将argument转换为从
抽象操作 ToUint8Clamp 接受参数 argument(一个
与大多数其他 ECMAScript Math.round
抽象操作 ToBigInt 接受参数 argument(一个
参数类型 | 结果 |
---|---|
Undefined | 抛出 |
Null | 抛出 |
Boolean | 如果 prim 是 1n ;如果 prim 是
0n 。
|
BigInt | 返回 prim。 |
Number | 抛出 |
String |
|
Symbol | 抛出 |
抽象操作 StringToBigInt 接受参数 str(一个字符串)并返回一个 BigInt 或
抽象操作 ToBigInt64 接受参数 argument(一个
抽象操作 ToBigUint64 接受参数 argument(一个
抽象操作 ToString 接受参数 argument(一个
抽象操作 ToObject 接受参数 argument(一个
参数类型 | 结果 |
---|---|
Undefined | 抛出一个 |
Null | 抛出一个 |
Boolean | 返回一个新的布尔对象,其 [[BooleanData]] 内部槽被设置为 argument。参见 |
Number | 返回一个新的数字对象,其 [[NumberData]] 内部槽被设置为 argument。参见 |
String | 返回一个新的字符串对象,其 [[StringData]] 内部槽被设置为 argument。参见 |
Symbol | 返回一个新的符号对象,其 [[SymbolData]] 内部槽被设置为 argument。参见 |
BigInt | 返回一个新的 BigInt 对象,其 [[BigIntData]] 内部槽被设置为 argument。参见
|
Object | 返回 argument。 |
抽象操作 ToPropertyKey 接受参数 argument(一个
抽象操作 ToLength 接受参数 argument(一个
抽象操作 CanonicalNumericIndexString 接受参数 argument(一个字符串)并返回一个数字或
一个规范数字字符串是任何使 CanonicalNumericIndexString
抽象操作不返回
抽象操作 ToIndex 接受参数 value(一个
抽象操作 RequireObjectCoercible 接受参数 argument(一个
参数类型 | 结果 |
---|---|
Undefined | 抛出一个 |
Null | 抛出一个 |
Boolean | 返回 argument。 |
Number | 返回 argument。 |
String | 返回 argument。 |
Symbol | 返回 argument。 |
BigInt | 返回 argument。 |
Object | 返回 argument。 |
抽象操作 IsArray 接受参数 argument(一个
抽象操作 IsCallable 接受参数 argument(一个
抽象操作 IsConstructor 接受参数 argument(一个
抽象操作 IsExtensible 接受参数 O(一个对象),并返回一个
抽象操作 IsIntegralNumber 接受参数 argument(一个
抽象操作 IsPropertyKey 接受参数 argument(一个
抽象操作 IsRegExp 接受参数 argument(一个
抽象操作 IsStringWellFormedUnicode 接受参数 string(一个字符串),并返回一个布尔值。它将 string 解释为一系列 UTF-16
编码的代码点,如
抽象操作 SameValue 接受参数 x(一个
这个算法不同于
抽象操作 SameValueZero 接受参数 x(一个
SameValueZero 与
抽象操作 SameValueNonNumber 接受参数 x(一个
抽象操作 IsLessThan 接受参数 x(一个
字符串的比较使用简单的按 UTF-16 代码单元值序列的字典顺序,没有尝试使用 Unicode 规范中定义的更复杂的、语义导向的字符或字符串相等性和排序顺序定义。因此,根据 Unicode
标准正规等价但不在相同规范化形式中的字符串值可能会被测试为不等。同样需要注意的是,对于包含
抽象操作 IsLooselyEqual 接受参数 x(一个 ==
操作符的语义。它在被调用时执行以下步骤:
抽象操作 IsStrictlyEqual 接受参数 x(一个 ===
操作符的语义。调用时执行以下步骤:
该算法在处理有符号零和 NaN 时与
抽象操作 MakeBasicObject 接受参数 internalSlotsList(一个
在本规范中,
抽象操作 Get 接受参数 O(一个对象)和 P(一个
抽象操作 GetV 接受参数 V(一个
抽象操作 Set 接受参数 O(一个对象)、P(一个
抽象操作 CreateDataProperty 接受参数 O(一个对象)、P(一个
此抽象操作创建一个属性,其属性设置为 ECMAScript 语言赋值运算符创建的默认值。通常,该属性不会已存在。如果存在且不可配置,或者 O 不可扩展,则 [[DefineOwnProperty]] 将返回
抽象操作 CreateDataPropertyOrThrow 接受参数 O(一个对象)、P(一个
此抽象操作创建一个属性,其属性设置为 ECMAScript 语言赋值运算符创建的默认值。通常,该属性不会已存在。如果存在且不可配置,或者 O 不可扩展,则 [[DefineOwnProperty]] 将返回
抽象操作 CreateNonEnumerableDataPropertyOrThrow 接受参数 O(一个对象)、P(一个
此抽象操作创建一个属性,其属性设置为与 ECMAScript 语言赋值运算符创建的默认值相同,但不可枚举。通常情况下,该属性不存在。如果存在,则
抽象操作 DefinePropertyOrThrow 接受参数 O(一个对象)、P(一个
抽象操作 DeletePropertyOrThrow 接受参数 O(一个对象)和 P(一个
抽象操作 GetMethod 接受参数 V(一个
抽象操作 HasProperty 接受参数 O(一个 Object)和 P(一个
抽象操作 HasOwnProperty 接受参数 O(一个 Object)和 P(一个
抽象操作 Call 接受参数 F(一个
抽象操作构造(Construct)接受参数F(一个
如果newTarget不存在,则该操作等效于:new F(...argumentsList)
抽象操作 SetIntegrityLevel 接受参数 O(一个对象)和 level(
抽象操作 TestIntegrityLevel 接受参数 O(一个对象)和 level(
抽象操作 CreateArrayFromList 接受参数 elements(一个
抽象操作 LengthOfArrayLike 接受参数 obj(一个对象)并返回一个
类似数组对象是指该操作返回
抽象操作 CreateListFromArrayLike 接受参数 obj(一个
抽象操作 Invoke 接受参数 V(一个
抽象操作 OrdinaryHasInstance 接受参数 C(一个
抽象操作 SpeciesConstructor 接受参数 O(一个对象)和 defaultConstructor(一个
抽象操作 EnumerableOwnProperties 接受参数 O(一个对象)和 kind
(
抽象操作 GetFunctionRealm 接受参数 obj(一个
抽象操作 CopyDataProperties 接受参数 target(一个对象),source
(一个
这里传入的目标对象始终是一个新创建的对象,在发生错误抛出时不会直接访问到它。
抽象操作 PrivateElementFind 接受参数 O(一个对象)和 P(一个
抽象操作 PrivateFieldAdd 接受参数 O(一个对象),P(一个
抽象操作 PrivateMethodOrAccessorAdd 接受参数 O(一个对象)和 method(一个
私有方法和访问器的值在实例之间是共享的。此操作不会创建方法或访问器的新副本。
宿主定义的抽象操作 HostEnsureCanAddPrivateElement 接受参数 O(一个对象),并返回一个包含正常完成的
HostEnsureCanAddPrivateElement 的实现必须符合以下要求:
HostEnsureCanAddPrivateElement 的默认实现是返回
此抽象操作仅由 ECMAScript
抽象操作 PrivateGet 接受参数 O(一个对象)和 P(一个私有名称),并返回一个包含 ECMAScript 语言值的普通完成或抛出完成。调用时执行以下步骤:
抽象操作 PrivateSet 接受参数 O(一个对象)、P(一个私有名称)和 value(一个 ECMAScript 语言值),并返回一个包含未使用的普通完成或抛出完成。调用时执行以下步骤:
抽象操作 DefineField 接受参数 receiver(一个对象)和 fieldRecord(一个
抽象操作 InitializeInstanceElements 接受参数 O(一个对象)和 constructor(一个 ECMAScript
抽象操作 AddValueToKeyedGroup 接受参数 groups(一个包含字段 [[Key]](一个 ECMAScript
语言值)和 [[Elements]](一个 ECMAScript 语言值列表)的
抽象操作 GroupBy 接受参数 items(一个 ECMAScript 语言值)、callbackfn(一个 ECMAScript 语言值)和
keyCoercion(
请参阅通用迭代接口(
迭代器记录是用于封装迭代器或异步迭代器及其 next
方法的
迭代器记录具有以下在
字段名 | 值 | 含义 |
---|---|---|
[[Iterator]] | 一个对象 | 符合 Iterator 或 AsyncIterator 接口的对象。 |
[[NextMethod]] |
一个 |
[[Iterator]] 对象的 next 方法。
|
[[Done]] | 一个布尔值 | 表示迭代器是否已关闭。 |
抽象操作 GetIteratorFromMethod 接受参数 obj(一个
抽象操作 GetIterator 接受参数 obj(一个 ECMAScript 语言值)和 kind(
抽象操作 IteratorNext 接受参数 iteratorRecord(一个
抽象操作 IteratorComplete 接受参数 iterResult(一个对象)并返回一个包含正常完成状态的布尔值或抛出异常完成状态。调用时执行以下步骤:
抽象操作 IteratorValue 接受参数 iterResult(一个对象)并返回一个包含正常完成状态的 ECMAScript 语言值或抛出异常完成状态。调用时执行以下步骤:
抽象操作 IteratorStep 接受参数 iteratorRecord(一个
抽象操作 IteratorStepValue 接受参数 iteratorRecord(一个
抽象操作 IteratorClose 接受参数 iteratorRecord(一个
IfAbruptCloseIterator 是一个使用
意味着与以下内容相同:
异步抽象操作 AsyncIteratorClose 接受参数 iteratorRecord (一个
抽象操作 CreateIterResultObject 接受参数 value (一个
抽象操作 CreateListIteratorRecord 接受参数 list (一个 next
方法返回
list 的连续元素。在调用时执行以下步骤:
列表迭代器对象对 ECMAScript 代码不可直接访问。
抽象操作 IteratorToList 接受参数 iteratorRecord (一个
除了本节中定义的操作外,专门的
语法导向操作 Evaluation 不接受参数并返回一个
语法导向操作 BoundNames 不接受参数,并返回一个字符串列表(List)。
它在以下产生式上分段定义:
DeclarationPart 是一个语法导向操作,不接受参数并返回一个解析节点(Parse Node)。它根据以下产生式逐段定义:
没有必要将 export default
在
export
在
本节由附录
export
VarScopedDeclarations是一个无需参数并返回
本节由附件
export
在函数或脚本的顶层,函数声明被视为 var 声明,而不是词法声明。
静态语义操作 TopLevelLexicallyScopedDeclarations 不接受参数,并返回一个
语法定向操作 TopLevelVarDeclaredNames 不接受参数,并返回一个
在函数或脚本的顶层,内部函数声明被视为 var 声明。
The
此部分由附录
语法定向操作 ContainsUndefinedBreakTarget 接受参数 labelSet(一个字符串
此部分由附件
语法定向操作 ContainsUndefinedContinueTarget 接受参数 iterationSet(一个字符串
本节由附录
抽象操作 IsAnonymousFunctionDefinition 接受参数 expr(一个
本规范中未列出的每个语法生成替代方案都隐含具有以下默认的 Contains 定义:
依赖于子结构的静态语义规则通常不会深入查看函数定义。
Static semantic rules that depend upon substructure generally do not look into class bodies except
for
依赖子结构的静态语义规则通常不会检查static
初始化块。
super
或
this
之一,则返回 super
,或
this
,返回 super
,或
this
,返回 Contains is used to detect new.target
, this
, and super
usage
within an
super
,返回
这些操作在整个规范的多个地方使用。
它在以下生成式中逐段定义:
抽象操作 InitializeBoundName 接受参数 name(字符串),value(一个
它通过以下生成式逐段定义:
语法导向操作
环境记录是一种规范类型,用于根据 ECMAScript 代码的词法嵌套结构,定义
每个环境记录都有一个[[OuterEnv]]字段,它要么是
环境记录纯粹是规范机制,不需要对应于 ECMAScript 实现的任何具体产物。ECMAScript 程序不可能直接访问或操作这些值。
方法 | 用途 |
---|---|
HasBinding(N) | 确定 |
CreateMutableBinding(N, D) | 在 |
CreateImmutableBinding(N, S) | 在 |
InitializeBinding(N, V) | 设置 |
SetMutableBinding(N, V, S) | 设置 |
GetBindingValue(N, S) | 返回 |
DeleteBinding(N) | 从 |
HasThisBinding() | 确定this 绑定。如果建立了,返回 |
HasSuperBinding() | 确定super 方法绑定。如果建立了,返回 |
WithBaseObject() | 如果此with 语句关联,则返回
with 对象。否则,返回 |
每个声明式环境记录都与包含变量、常量、let、class、模块、import和/或函数声明的 ECMAScript 程序范围相关联。声明式环境记录绑定其范围内包含的声明所定义的一组标识符。
声明式环境记录的具体规范方法的行为由以下算法定义。
在步骤
function f() { eval("var x; x = (delete x, 0);"); }
每个对象环境记录都与一个称为绑定对象的对象相关联。对象环境记录绑定一组字符串标识符名称,这些名称直接对应于其绑定对象的属性名称。
为with
语句创建的对象环境记录(
对象环境记录具有
对象环境记录的具体规范方法的行为由以下算法定义。
通常情况下,envRec不会有N的绑定,但如果有,
this
绑定。
super
绑定。
函数环境记录 是一种
this
绑定。如果函数不是一个super
,则其函数环境记录还包含用于在函数内部执行super
方法调用的状态。
函数环境记录具有
字段名称 | 值 | 含义 |
---|---|---|
[[ThisValue]] |
一个 |
这是该函数调用中使用的 |
[[ThisBindingStatus]] |
|
如果值是 |
[[FunctionObject]] |
一个ECMAScript |
导致创建此 |
[[NewTarget]] |
一个对象或 |
如果此 |
函数环境记录支持
函数环境记录附加具体方法的行为由以下算法定义:
函数环境记录
函数环境记录
函数环境记录
函数环境记录
函数环境记录
全局环境记录用于表示所有在同一个
全局环境记录在逻辑上是一个单一的记录,但它被指定为一个复合体,封装了一个
属性可以直接在
全局环境记录具有
字段名称 | 值 | 含义 |
---|---|---|
[[ObjectRecord]] |
一个 |
绑定对象是 |
[[GlobalThisValue]] | 一个对象 |
全局作用域中this 返回的值。 |
[[DeclarativeRecord]] |
一个 |
|
[[VarNames]] |
一个 |
在相关 |
方法 | 目的 |
---|---|
GetThisBinding() |
返回此this 绑定的值。
|
HasVarDeclaration (N) |
确定参数标识符是否在此 |
HasLexicalDeclaration (N) |
确定参数标识符是否在此 |
HasRestrictedGlobalProperty (N) |
确定参数是否为 |
CanDeclareGlobalVar (N) | 确定是否可以成功调用相应的CreateGlobalVarBinding方法,并为相同的参数N声明全局变量。 |
CanDeclareGlobalFunction (N) | 确定是否可以成功调用相应的CreateGlobalFunctionBinding方法,并为相同的参数N声明全局函数。 |
CreateGlobalVarBinding(N, D) |
用于在[[ObjectRecord]]组件中创建并初始化一个全局var 绑定,
该绑定的初始值为var 的属性值。
字符串值N是绑定的名称。如果D为 |
CreateGlobalFunctionBinding(N, V, D) |
在[[ObjectRecord]]组件中创建并初始化一个全局function 绑定。
绑定将是可变绑定。相应的function 的属性值。
字符串值N是绑定的名称。V是初始化值。
如果布尔参数D为 |
具体规范方法的行为定义如下算法。
全局环境记录envRec的HasBinding具体方法接受参数N(字符串),返回一个
全局环境记录envRec的CreateMutableBinding具体方法接受参数N(字符串)和D(布尔值),返回一个
全局环境记录envRec的CreateImmutableBinding具体方法接受参数N(字符串)和S(布尔值),返回一个
全局环境记录envRec的InitializeBinding具体方法接受参数N(字符串)和V(
全局环境记录envRec的SetMutableBinding具体方法接受参数N(字符串)、V(
全局环境记录envRec的GetBindingValue具体方法接受参数N(字符串)和S(布尔值),返回一个
全局环境记录envRec的DeleteBinding具体方法接受参数N(字符串),返回一个
全局环境记录envRec的HasThisBinding具体方法不接受参数,返回
this
绑定。
全局环境记录envRec的HasSuperBinding具体方法不接受参数,返回
super
绑定。
全局环境记录envRec的WithBaseObject具体方法不接受参数,返回
全局环境记录envRec的GetThisBinding具体方法不接受参数,返回一个
全局环境记录envRec的HasVarDeclaration具体方法接受参数N(字符串),返回一个布尔值。它确定参数标识符是否在此记录中具有通过
全局环境记录envRec的HasLexicalDeclaration具体方法接受参数N(字符串),返回一个布尔值。它确定参数标识符是否在此记录中具有通过词法声明(如
全局环境记录envRec的HasRestrictedGlobalProperty具体方法接受参数N(字符串),返回一个
全局环境记录envRec的CanDeclareGlobalVar具体方法接受参数N(字符串),返回一个
全局环境记录envRec的CanDeclareGlobalFunction具体方法接受参数N(字符串),返回一个
全局环境记录envRec的CreateGlobalVarBinding具体方法接受参数N(字符串)和D(布尔值),返回一个
全局环境记录envRec的CreateGlobalFunctionBinding具体方法接受参数N(字符串)、V(
模块环境记录 是一种
模块环境记录支持所有在
模块环境记录的附加具体规范方法的行为由以下算法定义:
模块环境记录的 GetBindingValue 具体方法 envRec 接受参数 N(字符串)和 S(布尔值),返回一个包含
ECMAScript 语言值的正常完成记录或抛出完成记录。它返回其绑定标识符 N 的值。但是,如果绑定是间接绑定,则返回目标绑定的值。如果绑定存在但未初始化,则抛出
S 将始终为
模块环境记录的 DeleteBinding 具体方法在本规范中从未使用。
模块环境记录的 HasThisBinding 具体方法 envRec 不接受任何参数并返回
模块环境记录始终提供 this
绑定。
模块环境记录的 GetThisBinding 具体方法 envRec 不接受任何参数并返回
模块环境记录的 CreateImportBinding 具体方法 envRec 接受参数 N(字符串)、M(模块记录)和 N2(字符串),并返回
抽象操作 GetIdentifierReference 接受参数 env(一个
抽象操作 NewDeclarativeEnvironment 接受参数 E(一个
抽象操作 NewObjectEnvironment 接受参数 O(一个对象)、W(布尔值)和 E(一个
抽象操作 NewFunctionEnvironment 接受参数 F(一个 ECMAScript
抽象操作 NewGlobalEnvironment 接受参数 G(一个对象)和 thisValue(一个对象),返回一个
抽象操作 NewModuleEnvironment 接受参数 E(一个
私有环境记录 是一种用于根据
ECMAScript 代码中的
抽象操作 NewPrivateEnvironment 接受参数 outerPrivEnv(一个
抽象操作 ResolvePrivateIdentifier 接受参数 privEnv(一个
在评估之前,所有 ECMAScript 代码都必须与一个 范围 相关联。从概念上讲,一个
本规范中以 范围记录 表示
字段名称 | 值 | 含义 |
---|---|---|
[[AgentSignifier]] | 一个 |
拥有此 |
[[Intrinsics]] | 一个 |
与此 |
[[GlobalObject]] | 一个对象或 |
此 |
[[GlobalEnv]] | 一个 |
此 |
[[TemplateMap]] | 一个 |
模板对象在每个 一旦
|
[[LoadedModules]] | 一个 |
从此 正如在
import() 表达式时使用。
|
[[HostDefined]] | 任何(默认值为 |
为 |
抽象操作 CreateRealm 不接受任何参数并返回一个
抽象操作 CreateIntrinsics 接受参数 realmRec(一个
抽象操作 SetRealmGlobalObject 接受参数 realmRec(一个
抽象操作 SetDefaultGlobalBindings 接受参数 realmRec(一个
执行上下文 是一个规范设备,用于跟踪 ECMAScript 实现对代码的运行时评估。在任何时候,每个
执行上下文堆栈
用于跟踪执行上下文。
执行上下文包含所有跟踪其关联代码执行进度的必要实现特定状态。每个执行上下文至少有
ECMAScript 代码执行上下文 具有
执行上下文的词法环境和变量环境组件始终是
表示生成器评估的执行上下文具有
组件 | 目的 |
---|---|
生成器 | 此 |
在大多数情况下,仅由此规范中的算法直接操作
执行上下文纯粹是一个规范机制,不需要对应于 ECMAScript 实现的任何特定制品。ECMAScript 代码不可能直接访问或观察到执行上下文。
抽象操作 GetActiveScriptOrModule 不接受参数,并返回
抽象操作 ResolveBinding 接受参数 name(一个字符串)和可选参数 env(一个
ResolveBinding 的结果始终是一个
抽象操作 GetThisEnvironment 不接受参数,并返回一个 this
绑定的
步骤 this
绑定的全局环境结束。
抽象操作 ResolveThisBinding 不接受参数,并返回 this
的绑定。调用时执行以下步骤:
抽象操作 GetNewTarget 不接受参数,并返回一个对象或
抽象操作 GetGlobalObject 不接受参数并返回一个对象。它返回由当前
作业是一个无参数的
在任何特定时间,如果以下所有条件都为真,则scriptOrModule(一个
在任何特定时间,如果以下所有条件都为真,则执行准备好评估 ECMAScript 代码:
特定种类的
作业回调记录是一个
WHATWG HTML 规范(https://html.spec.whatwg.org/)例如,使用宿主定义的值传播 Promise 回调的现有设置对象。
作业回调记录具有
HostMakeJobCallback 的实现必须符合以下要求:
HostMakeJobCallback 的默认实现在调用时执行以下步骤:
不是网络浏览器的 ECMAScript 宿主必须使用 HostMakeJobCallback 的默认实现。
这在将回调传递给负责其最终调度和运行的函数时调用。例如,promise.then(thenAction)
在调用Promise.prototype.then
时调用
MakeJobCallback
在调用Promise.prototype.then
时调用 MakeJobCallback,而不是在调度反应作业时。
HostCallJobCallback 的实现必须符合以下要求:
此要求意味着宿主不能更改本规范中定义的函数对象的[[Call]]行为。
HostCallJobCallback 的默认实现在调用时执行以下步骤:
不是网络浏览器的 ECMAScript 宿主必须使用 HostCallJobCallback 的默认实现。
HostEnqueueGenericJob 的实现必须符合
HostEnqueuePromiseJob 的实现必须符合
通过
HostEnqueueTimeoutJob 的实现必须符合
抽象操作 InitializeHostDefinedRealm 不接受任何参数,返回一个包含
this
绑定在 realm
的全局作用域中返回一个不同于 this
绑定应为 一个代理包括一组ECMAScript
一个
一些网络浏览器会在多个不相关的浏览器窗口标签页之间共享单个
当一个
一个代理标识符是一个全局唯一的、不透明的值,用于标识一个
字段名 | 值 | 含义 |
---|---|---|
[[LittleEndian]] | 布尔值 | 在算法 |
[[CanBlock]] | 布尔值 | 确定 |
[[Signifier]] | 一个 |
唯一标识其 |
[[IsLockFree1]] | 布尔值 | 如果对一个字节大小值的原子操作是无锁的,则为 |
[[IsLockFree2]] | 布尔值 | 如果对两字节大小值的原子操作是无锁的,则为 |
[[IsLockFree8]] | 布尔值 | 如果对八字节大小值的原子操作是无锁的,则为 |
[[CandidateExecution]] | 一个 |
参见 |
[[KeptAlive]] | 一个 |
最初是一个新的空 |
一旦[[Signifier]]、[[IsLockFree1]]和[[IsLockFree2]]的值被任何
[[IsLockFree1]]和[[IsLockFree2]]的值不一定由硬件决定,还可能反映出可能随时间和不同ECMAScript实现而变化的实现选择。
没有[[IsLockFree4]]字段:四字节原子操作总是无锁的。
实际上,如果一个原子操作的实现使用了任何类型的锁,则该操作就不是无锁的。无锁不意味着无等待:没有关于完成无锁原子操作需要多少机器步骤的上限。
原子访问大小为n是无锁的,并不意味着对非原子访问大小为n的访问有任何暗示,特别是,非原子访问仍可能作为一系列单独的内存访问执行。详见
一个
抽象操作 AgentSignifier 不接受任何参数,并返回一个
抽象操作 AgentCanSuspend 不接受任何参数,并返回一个布尔值。调用时,它执行以下步骤:
在某些环境中,允许给定
一个代理集群是可以通过操作共享内存进行通信的
每个
集群中的所有
如果一个代理集群中的不同
集群中的所有
集群中的所有
嵌入环境可以在不通知或合作代理的情况下停用(停止前进进程)或激活(恢复前进进程)一个
嵌入环境可以在不通知或合作集群中其他
每个以下的规范值及从它们递归可达的值,只属于一个代理集群。
在集群中任何
代理集群是一个规范机制,不必对应于ECMAScript实现的任何特定工件。
对于一个
当
实现必须确保:
本规范不保证任何对象或符号将被垃圾回收。对于那些不是
WeakRef.prototype.deref
时,如果未返回这些操作(
一些 ECMAScript 实现包括在后台运行的垃圾回收器实现,包括 ECMAScript 空闲时。让
对于某些对象和/或符号的集合S,相对于S的假设的 WeakRef-oblivious执行是指抽象操作
在评估过程中,如果对象和/或符号的集合S满足以下任一条件,则被认为是存活的:
对象或符号在字段、内部槽或属性中的存在并不意味着该值是存活的。例如,如果问题中的值从未传递回程序,则无法观察到它。
这是 WeakMap 中的键、WeakSet 的成员以及[[WeakRefTarget]]和[[UnregisterToken]]字段在
上述定义意味着,如果 WeakMap 中的键不是存活的,则其对应的值也不一定是存活的。
在任何时候,如果对象和/或符号的集合S不是
结合存活性的定义,本条款规定了实现可以应用的关于
有可能在不观察对象身份的情况下访问对象。允许对非逃逸对象的属性进行死变量消除和标量替换等优化,因此这些优化可以可观察地清空指向这些对象的
另一方面,如果可以观察到对象的身份,并且该对象位于
由于调用
让cleanupJob成为一个新的
HostEnqueueFinalizationRegistryCleanupJob 的实现会安排在将来的某个时间执行cleanupJob,如果可能的话。它还必须符合
抽象操作 ClearKeptObjects 不接受任何参数并返回
抽象操作 AddToKeptObjects 接受参数 value(一个对象或符号)并返回
抽象操作 CleanupFinalizationRegistry 接受参数 finalizationRegistry(一个
抽象操作 CanBeHeldWeakly 接受参数 v(一个
没有
所有的
每个
在以下算法描述中,假设 O 是一个
每个
[[GetPrototypeOf]] 内部方法用于一个
抽象操作 OrdinaryGetPrototypeOf 接受一个参数 O(一个对象),并返回一个对象或
[[SetPrototypeOf]] 内部方法用于一个
抽象操作 OrdinarySetPrototypeOf 接受两个参数:O(一个对象)和 V(一个对象或
[[IsExtensible]] 内部方法用于一个
抽象操作 OrdinaryIsExtensible 接受一个参数 O(一个对象),并返回一个布尔值。调用时执行以下步骤:
[[PreventExtensions]] 内部方法用于一个
抽象操作 OrdinaryPreventExtensions 接受一个参数 O(一个对象),并返回
[[GetOwnProperty]] 内部方法用于一个
抽象操作 OrdinaryGetOwnProperty 接受两个参数 O(一个对象)和 P(一个
普通对象的 [[DefineOwnProperty]] 内部方法接受两个参数:P(一个
抽象操作 OrdinaryDefineOwnProperty 接受参数 O(一个对象)、P(一个
抽象操作 IsCompatiblePropertyDescriptor 接受参数 Extensible(一个布尔值)、Desc(一个
抽象操作 ValidateAndApplyPropertyDescriptor 接受参数
O(一个对象或
一个
抽象操作 OrdinaryHasProperty 接受参数 O(一个对象)和 P(一个
[[Get]] 内部方法用于一个
抽象操作 OrdinaryGet 接受参数 O(一个对象)、P(一个
普通对象(
抽象操作 OrdinarySet 接受四个参数:O(对象),P(属性键),V(ECMAScript 语言值),和 Receiver(ECMAScript 语言值),并返回一个完成记录,可能是包含布尔值的正常完成记录,也可能是抛出异常的完成记录。调用时执行以下步骤:
抽象操作 OrdinarySetWithOwnDescriptor 接受五个参数:O(对象),P(属性键),V(ECMAScript
语言值),Receiver(ECMAScript 语言值),和 ownDesc(属性描述符或
普通对象(
抽象操作 OrdinaryDelete 接受两个参数:O(对象)和 P(
普通对象(
抽象操作 OrdinaryOwnPropertyKeys 接受一个参数 O(对象),并返回一个包含
抽象操作 OrdinaryObjectCreate 接受参数 proto(一个对象或
尽管 OrdinaryObjectCreate 仅调用
抽象操作 OrdinaryCreateFromConstructor 接受参数 constructor(一个
抽象操作 GetPrototypeFromConstructor 接受参数 constructor(一个
抽象操作 RequireInternalSlot 接受参数 O(一个
ECMAScript
除了 [[Extensible]] 和 [[Prototype]] 外,ECMAScript
内部槽 | 类型 | 描述 |
---|---|---|
[[Environment]] |
一个 |
函数封闭的 |
[[PrivateEnvironment]] |
一个 |
函数封闭的 |
[[FormalParameters]] |
一个 |
定义函数正式参数列表的源文本的根解析节点。 |
[[ECMAScriptCode]] |
一个 |
定义函数主体的源文本的根解析节点。 |
[[ConstructorKind]] |
|
函数是否是派生类 |
[[Realm]] |
一个 |
函数创建的 |
[[ScriptOrModule]] |
一个 |
函数创建的脚本或模块。 |
[[ThisMode]] |
|
定义 this 引用在函数的正式参数和代码体内如何被解释。this
指向词法上封闭函数的 |
[[Strict]] | 一个布尔值 |
如果这是一个 |
[[HomeObject]] | 一个对象 |
如果函数使用了 super ,这是提供 [[GetPrototypeOf]] 的对象,从而开始
super 属性的查找。
|
[[SourceText]] | 一系列 Unicode 码点 |
定义函数的 |
[[Fields]] |
一个 |
如果函数是一个类,则这是一个列表,表示类的非静态字段及其对应的初始化器。 |
[[PrivateMethods]] |
一个 |
如果函数是一个类,则这是一个列表,表示类的非静态私有方法和访问器。 |
[[ClassFieldInitializerName]] |
一个字符串、一个符号、一个 |
如果函数作为类字段的初始化器创建,则用于 |
[[IsClassConstructor]] | 一个布尔值 |
指示函数是否是一个类 |
所有 ECMAScript
ECMAScript
抽象操作 PrepareForOrdinaryCall 接受参数 F(一个 ECMAScript
抽象操作 OrdinaryCallBindThis 接受参数 F(一个 ECMAScript
语法驱动操作
尽管字段初始化器构成函数边界,调用
抽象操作 OrdinaryCallEvaluateBody 接受两个参数:F(一个 ECMAScript
ECMAScript
抽象操作 OrdinaryFunctionCreate 接受以下参数:functionPrototype(一个对象),
sourceText(一系列 Unicode 代码点),ParameterList(一个
抽象操作 AddRestrictedFunctionProperties 接受两个参数:F(一个
这个函数是 %ThrowTypeError% 内在对象。
它是一个匿名的内置
当调用时,它执行以下步骤:
这个函数的 [[Extensible]] 内部槽的值为
这个函数的
这个函数的
抽象操作 MakeConstructor 接受一个参数 F(一个 ECMAScript
抽象操作 MakeClassConstructor 接受一个参数 F(一个 ECMAScript
抽象操作 MakeMethod 接受参数 F(一个 ECMAScript
抽象操作 DefineMethodProperty 接受四个参数:homeObject(一个对象),key(一个
抽象操作 SetFunctionName 接受两个必需参数和一个可选参数:F(一个
抽象操作 SetFunctionLength 接受两个参数:F(一个
抽象操作 FunctionDeclarationInstantiation 接受两个参数:func(一个 ECMAScript
它在调用时执行以下步骤:
内置的
除了每个
内置
内置
内置
实现可以提供本规范中未定义的额外内置
内置
内置
抽象操作 BuiltinCallOrConstruct 接受以下参数:F(一个内置的
当 calleeContext 从
抽象操作 CreateBuiltinFunction 接受以下参数:behaviour(一个
本规范中定义的每个内置函数都是通过调用 CreateBuiltinFunction 抽象操作创建的。
本规范定义了几种内置的
一个对象是一个 绑定函数异域对象,如果它的 [[Call]] 和(如果适用的话)[[Construct]] 内部方法使用以下实现,并且它的其他基本内部方法使用在
内部槽 | 类型 | 描述 |
---|---|---|
[[BoundTargetFunction]] | 可调用的对象 |
封装的 |
[[BoundThis]] |
一个 |
在调用封装的函数时始终传递的 |
[[BoundArguments]] |
一个 |
一个值的列表,其元素作为对封装函数的任何调用的第一个参数。 |
[[Call]] 内部方法用于一个
[[Construct]] 内部方法用于一个
抽象操作 BoundFunctionCreate 接受参数 targetFunction(一个
数组是一个
一个对象是一个 数组异域对象(或简称为数组),如果它的 [[DefineOwnProperty]]
内部方法使用以下实现,并且它的其他基本内部方法使用在
[[DefineOwnProperty]] 内部方法在
抽象操作 ArrayCreate 接受参数 length(一个非负的
抽象操作 ArraySpeciesCreate 接受两个参数:originalArray(一个对象)和 length(一个非负的
抽象操作 ArraySetLength 接受两个参数:A(一个数组)和 Desc(一个
字符串对象是一个封装了字符串值的
如果一个对象的 [[GetOwnProperty]]、[[DefineOwnProperty]] 和 [[OwnPropertyKeys]] 内部方法使用以下实现,并且它的其他基本内部方法使用在
一个
一个
一个
抽象操作 StringCreate 接受两个参数:value(一个字符串)和 prototype(一个对象),并返回一个
抽象操作 StringGetOwnProperty 接受两个参数:S(一个具有 [[StringData]] 内部槽的对象)和
P(一个
大多数 ECMAScript 函数会向其代码提供一个 arguments 对象。根据函数定义的特性,其 arguments 对象可能是一个
如果一个对象的内部方法使用以下实现(未在此处指定的使用
虽然
Object.prototype.toString
(
ParameterMap 对象及其属性值用作指定 arguments 对象与参数绑定之间对应关系的设备。ParameterMap 对象及其属性值并不直接从 ECMAScript 代码中可观察。ECMAScript 实现不需要实际创建或使用此类对象来实现指定的语义。
普通 arguments 对象定义了一个不可配置的
ECMAScript 对
[[GetOwnProperty]] 内部方法用于
[[DefineOwnProperty]] 内部方法用于
[[Get]] 内部方法用于
[[Set]] 内部方法用于
[[Delete]] 内部方法用于
抽象操作 CreateUnmappedArgumentsObject 接受一个参数 argumentsList(一个
抽象操作 CreateMappedArgumentsObject 接受参数 func(一个对象)、formals(一个
抽象操作 MakeArgGetter 接受参数 name(一个字符串)和 env(一个
抽象操作 MakeArgSetter 接受参数 name(一个字符串)和 env(一个
如果一个对象的 [[GetOwnProperty]]、[[HasProperty]]、[[DefineOwnProperty]]、[[Get]]、[[Set]]、[[Delete]] 和 [[OwnPropertyKeys]] 内部方法使用本节中的定义,并且其其他基本内部方法使用
[[GetOwnProperty]] 是
[[HasProperty]] 是
[[DefineOwnProperty]] 是
[[Get]] 是
[[Set]] 是
[[Delete]] 是
[[OwnPropertyKeys]] 是
一个 带缓冲见证记录的 TypedArray 是一个
带缓冲见证记录的 TypedArray 具有
字段名称 | 值 | 含义 |
---|---|---|
[[Object]] | 一个 |
其缓冲区的字节长度被加载的 |
[[CachedBufferByteLength]] | 一个非负的 |
创建 |
抽象操作 MakeTypedArrayWithBufferWitnessRecord 接受参数 obj(一个
抽象操作 TypedArrayCreate 接受参数 prototype(一个对象),并返回一个
抽象操作 TypedArrayByteLength 接受参数 taRecord(一个
抽象操作 TypedArrayLength 接受参数 taRecord(一个
抽象操作 IsTypedArrayOutOfBounds 接受参数 taRecord(一个
抽象操作 IsValidIntegerIndex 接受参数 O(一个
抽象操作 TypedArrayGetElement 接受参数 O(一个
抽象操作 TypedArraySetElement 接受参数 O(一个
此操作似乎总是成功,但在尝试写入
抽象操作 IsArrayBufferViewOutOfBounds 接受参数 O(一个
一个 export *
语法间接导出的绑定。每个字符串值自身属性键是相应导出绑定名称的
一个对象是一个 模块命名空间特殊对象,如果它的 [[GetPrototypeOf]],
[[SetPrototypeOf]], [[IsExtensible]], [[PreventExtensions]], [[GetOwnProperty]], [[DefineOwnProperty]], [[HasProperty]], [[Get]], [[Set]], [[Delete]],
和
[[OwnPropertyKeys]] 内部方法使用本节中的定义,而它的其他基本内部方法使用
一个
一个
一个
一个
一个
一个
一个
一个
ResolveExport 是无副作用的。每次用特定的 exportName 和 resolveSet
参数调用此操作时,它必须返回相同的结果。实现可以选择预先计算或缓存每个
一个
一个
一个
抽象操作 ModuleNamespaceCreate 接收参数 module(一个
一个
如果对象的 [[SetPrototypeOf]] 内部方法使用以下实现,则该对象是一个 不可变原型特殊对象。(其其他基本内部方法可以根据具体的
与其他
一个
抽象操作 SetImmutablePrototype 接收参数 O(一个对象)和 V(一个对象或
代理对象是一个
如果对象的基本内部方法(包括 [[Call]] 和 [[Construct]],如果适用)使用本节中的定义,则该对象是一个 代理特殊对象。这些内部方法在
内部方法 | 处理程序方法 |
---|---|
[[GetPrototypeOf]] |
getPrototypeOf
|
[[SetPrototypeOf]] |
setPrototypeOf
|
[[IsExtensible]] |
isExtensible
|
[[PreventExtensions]] |
preventExtensions
|
[[GetOwnProperty]] |
getOwnPropertyDescriptor
|
[[DefineOwnProperty]] |
defineProperty
|
[[HasProperty]] |
has
|
[[Get]] |
get
|
[[Set]] |
set
|
[[Delete]] |
deleteProperty
|
[[OwnPropertyKeys]] |
ownKeys
|
[[Call]] |
apply
|
[[Construct]] |
construct
|
当调用处理程序方法来提供代理对象内部方法的实现时,处理程序方法会将代理的目标对象作为参数传递。代理的处理程序对象不一定具有与每个基本内部方法对应的方法。如果处理程序对象没有对应于内部陷阱的方法,则在代理上调用内部方法将导致调用代理目标对象上的相应内部方法。
代理对象的 [[ProxyHandler]] 和 [[ProxyTarget]]
内部插槽在对象创建时总是被初始化,并且通常不可修改。有些代理对象是以允许其随后被撤销的方式创建的。当代理被撤销时,其 [[ProxyHandler]]
和 [[ProxyTarget]] 内部插槽被设置为
由于代理对象允许内部方法的实现由任意 ECMAScript 代码提供,因此可能会定义一个其处理程序方法违反
在以下算法描述中,假设 O 是一个 ECMAScript 代理对象,P 是一个
[[GetPrototypeOf]] 内部方法的
Proxy 对象的 [[GetPrototypeOf]] 强制执行以下不变量:
[[SetPrototypeOf]] 内部方法的
Proxy 对象的 [[SetPrototypeOf]] 强制执行以下不变量:
[[IsExtensible]] 内部方法的
Proxy 对象的 [[IsExtensible]] 强制执行以下不变量:
[[PreventExtensions]] 内部方法的
Proxy 对象的 [[PreventExtensions]] 强制执行以下不变量:
[[GetOwnProperty]] 内部方法的
Proxy 对象的 [[GetOwnProperty]] 强制执行以下不变量:
[[DefineOwnProperty]] 内部方法的
Proxy 对象的 [[DefineOwnProperty]] 强制执行以下不变量:
[[HasProperty]] 内部方法的
Proxy 对象的 [[HasProperty]] 强制执行以下不变量:
[[Get]] 内部方法的
[[Set]] 内部方法的
[[Delete]] 内部方法的
Proxy 对象的 [[Delete]] 强制执行以下不变量:
[[OwnPropertyKeys]] 内部方法的
[[Call]] 内部方法用于
[[Construct]] 内部方法用于
[[Construct]] 对于 Proxy 对象强制执行以下不变量:
抽象操作 ValidateNonRevokedProxy 接受参数 proxy(一个
抽象操作 ProxyCreate 接受参数 target(一个
ECMAScript 源代码 是一系列 Unicode 代码点。在 ECMAScript 语法允许的地方,所有从 U+0000 到 U+10FFFF 的 Unicode
代码点值,包括代理代码点,都可以出现在 ECMAScript 源代码中。用于存储和交换 ECMAScript 源代码的实际编码与本规范无关。不论外部源代码编码如何,符合规范的 ECMAScript
实现都将源代码处理为等效的
组合字符序列的组成部分被视为单独的 Unicode 代码点,即使用户可能将整个序列视为一个字符。
在字符串字面量、正则表达式字面量、模板字面量和标识符中,任何 Unicode 代码点也可以使用 Unicode 转义序列来表示,显式表达代码点的数值。在注释中,这样的转义序列实际上被忽略,作为注释的一部分。
ECMAScript 与 Java 编程语言在 Unicode 转义序列的行为上有所不同。例如,在 Java 程序中,如果 Unicode 转义序列 \u000A
出现在单行注释中,它会被解释为行终止符(Unicode 代码点 U+000A 是换行符(LF)),因此下一个代码点不再是注释的一部分。同样,如果 Unicode 转义序列 \u000A
出现在 Java 程序的字符串字面量中,它也会被解释为行终止符,字符串字面量中不允许有行终止符——必须写成 \n
而不是
\u000A
,以使换行符(LF)成为字符串字面量的字符串值的一部分。在 ECMAScript 程序中,出现在注释中的 Unicode 转义序列从不被解释,因此不能终止注释。同样,出现在
ECMAScript 程序的字符串字面量中的 Unicode 转义序列始终是字面量的一部分,永远不会被解释为行终止符或可能终止字符串字面量的代码点。
抽象操作 UTF16EncodeCodePoint 接受参数 cp(一个 Unicode 代码点)并返回一个字符串。调用时,它执行以下步骤:
抽象操作 CodePointsToString 接受参数 text(一个 Unicode 代码点序列)并返回一个字符串。它将 text 转换为字符串值,如
抽象操作 UTF16SurrogatePairToCodePoint 接受参数 lead(一个代码单元)和 trail(一个代码单元),并返回一个代码点。形成
UTF-16
抽象操作 CodePointAt 接受参数 string(一个字符串)和 position(一个非负
抽象操作 StringToCodePoints 接受参数 string(一个字符串)并返回一个代码点的
抽象操作 ParseText 接受参数 sourceText(一个 Unicode 代码点序列)和 goalSymbol(ECMAScript
语法中的一个非终结符)并返回一个
另见第
有四种类型的 ECMAScript 代码:
eval
函数的源文本。更准确地说,如果传递给内建 eval
函数的参数
eval
的 eval code 是该 Function code 通常以函数定义的主体形式提供(
将
指令序言 是出现在
"use strict" 指令 是出现在
"use strict"
或 'use strict'
。
ECMAScript 语法单元可以使用无限制或严格模式语法和语义进行处理
(
eval
是包含在严格模式代码中的 不是严格模式代码的 ECMAScript 代码称为 非严格代码。
ECMAScript 实现可能支持对函数
ECMAScript
在多个情况下,词法输入元素的识别对消耗输入元素的语法语境是敏感的。这需要词法语法的多个
Unicode 格式控制字符(即 Unicode 字符数据库中类别为 “Cf” 的字符,如左到右标记或右到左标记)是用于在缺乏高级协议(如标记语言)的情况下控制一段文本格式的控制代码。
允许在源文本中使用格式控制字符以便于编辑和显示是很有用的。所有格式控制字符都可以在注释、字符串字面量、模板字面量和正则表达式字面量中使用。
U+200C(零宽非连接符)和 U+200D(零宽连接符)是用于在某些语言中形成单词或短语时进行必要区分的格式控制字符。在
U+FEFF(零宽不换行空格)是主要用于文本开头的格式控制字符,用来标记它为 Unicode 并允许检测文本的编码和字节顺序。出于这种目的而使用的 <ZWNBSP>
字符有时也会出现在文本的开头之后,例如由于文件连接的结果。在
某些格式控制字符在注释、字符串字面量和正则表达式字面量之外的特殊处理在
代码点 | 名称 | 缩写 | 用法 |
---|---|---|---|
U+200C
|
零宽非连接符 | <ZWNJ> |
|
U+200D
|
零宽连接符 | <ZWJ> |
|
U+FEFF
|
零宽不换行空格 | <ZWNBSP> |
|
空白符代码点用于提高源文本的可读性,并将词法单元(不可分割的词法单位)彼此分开,但除此之外没有其他意义。空白符代码点可以出现在任意两个词法单元之间,以及输入的开头或结尾。空白符代码点可以出现在
ECMAScript 的空白符代码点列在
代码点 | 名称 | 缩写 |
---|---|---|
U+0009 |
CHARACTER TABULATION | <TAB> |
U+000B |
LINE TABULATION | <VT> |
U+000C |
FORM FEED (FF) | <FF> |
U+FEFF |
ZERO WIDTH NO-BREAK SPACE | <ZWNBSP> |
general category 中的任意代码点 “Space_Separator” | <USP> |
U+0020 (SPACE) 和 U+00A0 (NO-BREAK SPACE) 代码点是 <USP> 的一部分。
除了表
像空白符代码点一样,行终止符代码点用于提高源文本的可读性,并将词法单元(不可分割的词法单位)彼此分开。然而,与空白符代码点不同,行终止符对语法规则的行为有一定影响。通常,行终止符可以出现在任意两个词法单元之间,但在某些地方,语法规则禁止它们的出现。行终止符还会影响自动分号插入的过程(
行终止符可以出现在
行终止符包含在正则表达式中的 \s
类匹配的空白符代码点集合中。
ECMAScript 行终止符代码点列在
代码点 | Unicode 名称 | 缩写 |
---|---|---|
U+000A |
LINE FEED (LF) | <LF> |
U+000D |
CARRIAGE RETURN (CR) | <CR> |
U+2028 |
LINE SEPARATOR | <LS> |
U+2029 |
PARAGRAPH SEPARATOR | <PS> |
只有表
注释可以是单行或多行。多行注释不能嵌套。
由于单行注释可以包含任何 Unicode 代码点,除了 //
标记到行尾的所有代码点组成。然而,行尾的
注释表现得像空白符,并被丢弃,除了如果一个
本节中的一些规则在
Hashbang 注释是位置敏感的,并且像其他类型的注释一样,从语法解析的输入元素流中被丢弃。
本标准指定了特定的代码点添加:U+0024 (美元符号) 和 U+005F (下划线) 在
非终结符
_
。
具有 Unicode 属性 “ID_Start” 和 “ID_Continue” 的代码点集合分别包括具有 Unicode 属性 “Other_ID_Start” 和 “Other_ID_Continue” 的代码点。
在 \
不贡献任何代码点。Unicode 转义序列不能用于对
根据 Unicode 标准,两个规范等效的
语法导向操作
语法导向操作
关键字 是一个与
if
、while
、async
、await
等。
保留字 是一个不能用作标识符的
if
和 while
是保留字,await
仅在异步函数和模块中是保留的,而 async
不是保留的,它可以在变量名或语句标签中使用。
本规范使用语法生成式和
await
和 yield
,都是无条件保留的。await
和 yield
的例外情况在
那些始终允许作为标识符使用的,不是关键字的名称,例如 Math
、window
、toString
和
_
;
那些永远不允许作为标识符使用的名称,即下面列出的 await
和
yield
);
那些在特定上下文中允许作为标识符使用的名称,即 await
和 yield
;
那些在 let
、static
、implements
、interface
、package
、private
、protected
和 public
;
那些始终允许作为标识符使用,但在某些语法生成式中的某些地方也出现为关键字的名称,即 as
、async
、from
、get
、meta
、of
、set
和 target
。
术语 条件关键字 或 上下文关键字 有时用来指在上述最后三类中的关键字,这些关键字可以在某些上下文中作为标识符使用,而在其他上下文中作为关键字使用。
根据
\
Unicode 转义序列表示。
\
els\u{65}
来声明一个名为 "else" 的变量。
enum
目前在本规范中不作为关键字使用。它是一个 未来保留字,为将来的语言扩展预留。
同样,implements
、interface
、package
、private
、protected
和 public
在
紧跟在
例如:3in
是错误的,而不是两个输入元素 3
和 in
。
数值字面量表示
字符串字面量是用单引号或双引号括起来的 0 个或更多 Unicode 代码点。Unicode 代码点也可以通过转义序列表示。除了闭合引号的代码点、U+005C(反斜杠)、U+000D(回车符)和
U+000A(换行符)外,所有代码点都可以直接出现在字符串字面量中。任何代码点都可以以转义序列的形式出现。字符串字面量求值为 ECMAScript 字符串值。在生成这些字符串值时,Unicode 代码点按照
非终结符
<LF> 和 <CR> 不能出现在字符串字面量中,除非作为 \n
或 \u000A
。
字符串字面量表示
转义序列 | 代码单元值 | Unicode 字符名称 | 符号 |
---|---|---|---|
\b |
0x0008 |
退格符 | <BS> |
\t |
0x0009 |
字符制表符 | <HT> |
\n |
0x000A |
换行符 (LF) | <LF> |
\v |
0x000B |
行制表符 | <VT> |
\f |
0x000C |
换页符 (FF) | <FF> |
\r |
0x000D |
回车符 (CR) | <CR> |
\" |
0x0022 |
引号 | " |
\' |
0x0027 |
撇号 | ' |
\\ |
0x005C |
反斜杠 | \ |
下面的生成式描述了正则表达式字面量的语法,并由输入元素扫描器用于查找正则表达式字面量的结束位置。包含
实现可以扩展
正则表达式字面量不能为空;而不是表示一个空的正则表达式字面量,代码单元序列 //
启动一个单行注释。要指定一个空的正则表达式,请使用:/(?:)/
。
大多数 ECMAScript 语句和声明必须以分号结尾。这些分号总是可以显式出现在源代码中。然而,为了方便,在某些情况下,这些分号可以从源代码中省略。在这些情况下,可以通过描述分号自动插入到源代码令牌流中的那些情况来解释。
在以下规则中,“令牌”是指使用当前词法
分号插入有三条基本规则:
当从左到右解析源文本时,遇到不允许的令牌(称为冒犯令牌)时,如果以下条件之一为真, 则会在冒犯令牌之前自动插入分号:
但是,前述规则有一个额外的优先条件:如果分号将被解析为空语句或成为for
语句头中的两个分号之一,
则不会自动插入分号(见
以下是语法中唯一的受限规则:
这些受限规则的实际效果如下:
++
或--
令牌且解析器将其视为后缀操作符,并且前一个令牌与++
或--
令牌之间至少有一个++
或--
令牌之前自动插入分号。
continue
、break
、return
、throw
或
yield
令牌并且在下一个令牌之前遇到一个continue
、break
、return
、throw
或
yield
令牌之后自动插入分号。
=>
令牌之前时,自动插入分号并且标点符号会导致语法错误。
async
令牌之后有一个function
或(
令牌之前时,自动插入分号并且async
令牌不会被视为与后续令牌相同的表达式或类元素。
async
令牌之后有一个*
令牌之前时,自动插入分号并且标点符号会导致语法错误。
因此,对ECMAScript程序员的实际建议是:
以下源代码
{ 1 2 } 3
即使使用自动分号插入规则,也不是 ECMAScript 语法中的有效句子。相反,以下源代码
{ 1
2 } 3
也不是有效的 ECMAScript 句子,但通过自动分号插入会被转换为以下内容:
{ 1
;2 ;} 3;
这是一个有效的 ECMAScript 句子。
以下源代码
for (a; b
)
不是有效的 ECMAScript 句子,且不会因自动分号插入而改变,因为 for 语句头部需要的分号。自动分号插入永远不会插入 for 语句头部的两个分号之一。
以下源代码
return
a + b
通过自动分号插入会被转换为以下内容:
return;
a + b;
表达式 a + b
不会被视为 return
语句要返回的值,因为 return
与 a + b
之间有一个
以下源代码
a = b
++c
通过自动分号插入会被转换为以下内容:
a = b;
++c;
符号 ++
不会被视为应用于变量 b
的后缀运算符,因为 b
与 ++
之间有一个
以下源代码
if (a > b)
else c = d
不是有效的 ECMAScript 句子,且即使在 else
符号之前没有任何语法规则适用,自动分号插入也不会改变,因为自动插入的分号会被解析为一个空语句。
以下源代码
a = b + c
(d + e).print()
不会被自动分号插入规则改变,因为第二行开始的括号表达式可以被解释为函数调用的参数列表:
a = b + c(d + e).print()
在赋值语句必须以左括号开始的情况下,程序员最好在前一条语句的末尾提供一个显式分号,而不是依赖自动分号插入。
ECMAScript 程序可以通过依赖自动分号插入来以很少分号的风格编写。如上所述,分号并不会在每个换行处插入,自动分号插入可能依赖跨行终止符的多个标记。
随着新的语法特性被添加到 ECMAScript 中,可能会增加一些语法产生式,这会导致依赖自动分号插入的行在解析时改变语法产生式。
在本节的目的中,如果某个地方的分号是否插入取决于之前的源文本,则该自动分号插入的案例被认为是有趣的。本节的其余部分描述了 ECMAScript 这一版本中一些有趣的自动分号插入案例。
在一个
(
)。没有分号,这两行会被视为一个 [
)。没有分号,这两行会被视为属性访问,而不是一个 `
)。没有分号,这两行会被解释为一个标记模板 (+
或 -
。没有分号,这两行会被解释为使用对应的二元运算符。/
ECMAScript 包含一些语法产生式,它们包括“[无
本节的其余部分描述了 ECMAScript 这一版本中使用“[无
yield
和 await
在语法中允许作为
let
await 0;
yield
或 await
,那么这是一个语法错误。
评估
在 yield
可以用作标识符。评估 yield
解析为
当处理如下产生式实例时
对
this
关键字关于
false
,返回 true
,返回 数组元素可以在元素列表的开头、中间或结尾省略。每当元素列表中的逗号前没有
对象初始化器是一个描述对象初始化的表达式,写成类似字面量的形式。它是一个由零个或多个
在某些上下文中,
除了描述实际的对象初始化器外,
此生产的存在是为了使
由
参见
参见
参见
参见
抽象操作IsValidRegularExpressionLiteral接受参数literal(一个
d
、g
、i
、m
、s
、u
、v
或y
之外的任何代码点,或flags包含的任何代码点不止一次,则返回u
,则令u为v
,则令v为模板字符串是一个
抽象操作 TemplateString 接受参数 templateToken(一个
如果 raw 是
抽象操作 GetTemplateObject 接受参数 templateLiteral(一个
模板对象的创建不会导致
程序代码中的每个
本规范的未来版本可能会定义模板对象的附加不可枚举属性。
SubstitutionEvaluation 是一个
String.prototype.concat
而不是 +
运算符。
String.prototype.concat
而不是 +
运算符。
String.prototype.concat
而不是 +
运算符。
此算法不会对 delete
和 typeof
等运算符应用于带括号的表达式。
当处理以下产生式的一个实例时
此产生式存在是为了防止自动分号插入规则(
a?.b
`c`
以便将其解释为两个有效的语句。目的是保持与没有可选链的类似代码的一致性:
a.b
`c`
这是一个有效的语句,并且自动分号插入不适用。
属性通过名称访问,使用点表示法:
或方括号表示法:
点表示法通过以下句法转换解释:
其行为与以下相同:
同样地:
其行为与以下相同:
其中 <identifier-name-string> 是评估
抽象操作 EvaluatePropertyAccessWithExpressionKey 接受参数 baseValue(一个
抽象操作 EvaluatePropertyAccessWithIdentifierKey 接受参数 baseValue(一个
new
Operator抽象操作 EvaluateNew 接受参数 constructExpr(一个
一个
抽象操作 EvaluateCall 接受参数 func(一个
super
关键字抽象操作 GetSuperConstructor 不接受任何参数,并返回一个
抽象操作 MakeSuperPropertyReference 接受参数 actualThis(一个
参数列表的评估产生一个
语法导向操作
?.
标记开始。语法导向操作
抽象操作ContinueDynamicImport接受参数promiseCapability(一个import()
标签模板是一个函数调用,其中调用的参数是从一个
The import.meta
返回的对象。
HostGetImportMetaProperties 的默认实现是返回一个新的空
The import.meta
返回的对象。
大多数
HostFinalizeImportMeta 的默认实现是返回
delete
运算符
如果派生的
并且
最后一项规则意味着表达式如 delete (((foo)))
会产生
当 delete
运算符出现在 delete
运算符出现在
void
运算符typeof
运算符+
运算符一元 + 运算符将其操作数转换为
-
运算符一元 -
运算符将其操作数转换为数值,然后对其取反。取反
~
)!
)*
执行乘法,生成其操作数的乘积。/
执行除法,生成其操作数的商。%
生成其操作数在隐式除法中的余数。+
)加法运算符既可以执行字符串连接,也可以执行数值加法。
-
)减法运算符执行减法,生成其操作数的差值。
<<
)对左操作数执行按位左移操作,移动的位数由右操作数指定。
>>
)对左操作数执行按位右移操作,移动的位数由右操作数指定,并使用符号位填充空出的位。
>>>
)对左操作数执行按位右移操作,移动的位数由右操作数指定,并使用零填充空出的位。
关系运算符的求值结果总是布尔类型,反映运算符命名的关系是否在其两个操作数之间成立。
[In] 语法参数是为了避免在关系表达式中混淆 in
运算符和 for
语句中的 in
运算符。
抽象操作 InstanceofOperator 接受参数 V(一个
步骤
instanceof
运算符语义。如果对象没有定义或继承
instanceof
语义。
等值运算符的求值结果总是布尔类型,反映运算符命名的关系是否在其两个操作数之间成立。
根据上述等值定义:
`${a}` == `${b}`
强制进行。
+a == +b
强制进行。
!a == !b
强制进行。
等值运算符保持以下不变量:
A != B
等价于 !(A == B)
。
A == B
等价于 B == A
,除了 A
和 B
的求值顺序。
等值运算符并不总是传递的。例如,可能存在两个不同的字符串对象,每个对象表示相同的字符串值;每个字符串对象会被 ==
运算符视为与字符串值相等,但这两个字符串对象彼此并不相等。例如:
new String("a") == "a"
和 "a" == new String("a")
均为 new String("a") == new String("a")
为 字符串比较使用简单的代码单元值相等测试。不会尝试使用 Unicode 规范中定义的更复杂的、语义导向的字符或字符串相等性定义和排序顺序。因此,根据 Unicode 标准规范等价的字符串值可能会被测试为不相等。实际上,这个算法假设两个字符串都已处于规范化形式。
由 &&
或 ||
运算符生成的值不一定是布尔类型。生成的值始终是两个操作数表达式之一的值。
? :
)
ECMAScript 中
如果
如果
assignmentOpText | opText |
---|---|
**= |
** |
*= |
* |
/= |
/ |
%= |
% |
+= |
+ |
-= |
- |
<<= |
<< |
>>= |
>> |
>>>= |
>>> |
&= |
& |
^= |
^ |
|= |
| |
抽象操作 ApplyStringOrNumericBinaryOperator 接受参数 lval(一个 **
、*
、/
、%
、+
、-
、<<
、>>
、>>>
、&
、^
或 |
)和 rval(一个
+
,则
**
,返回 ? /
,返回 ? %
,返回 ? >>>
,返回
? opText | |
operation |
---|---|---|
** |
Number | |
* |
Number | |
* |
BigInt | |
/ |
Number | |
% |
Number | |
+ |
Number | |
+ |
BigInt | |
- |
Number | |
- |
BigInt | |
<< |
Number | |
<< |
BigInt | |
>> |
Number | |
>> |
BigInt | |
>>> |
Number | |
& |
Number | |
& |
BigInt | |
^ |
Number | |
^ |
BigInt | |
| |
Number | |
| |
BigInt | |
在步骤
步骤
抽象操作 EvaluateStringOrNumericBinaryExpression 接受参数 leftOperand(一个
在处理以下产生式的实例时
对于
如果
如果
语法导向操作
语法导向操作
语法导向操作
从左到右的求值顺序通过在访问迭代器或求值
,
)
无论控制如何离开
eval
函数的调用都返回值 1:
eval("1;;;;;")
eval("1;{}")
eval("1;var a;")
抽象操作 BlockDeclarationInstantiation 接受参数 code(一个
当调用时,它执行以下步骤:
let
和 const
声明定义的变量作用域为 let
声明中的
一个 const
声明中。
一个 var
语句声明的变量作用域为
如果一个
属性绑定初始化是一个
剩余绑定初始化是一个
键绑定初始化是一个
它在以下产生式上分段定义:
一个 function
或 class
async function
开始,因为这可能会使其与一个 let [
开始,因为这可能会使其与一个 let
if
语句else
] 以通常的方式解决了经典的“悬空 else”问题。也就是说,当关联的
if
选择不明确时,else
与最近的(最内层的)候选 if
相关联。
只有在实现
抽象操作 LoopContinues 接受参数 completion(一个
在
语法导向操作 LoopEvaluation 接受参数 labelSet(一个
do
-while
语句只有在实现
语法导向操作 DoWhileLoopEvaluation 接受参数 labelSet(一个
while
语句只有在实现
语法导向操作 WhileLoopEvaluation 接受参数 labelSet(一个
for
语句只有在实现
语法导向操作 ForLoopEvaluation 接受参数 labelSet(一个
抽象操作 ForBodyEvaluation 接受参数 test(一个
抽象操作 CreatePerIterationEnvironment 接受参数 perIterationBindings
(一个
for
-in
、for
-of
和
for
-await
-of
语句
本节由附录
只有在实现
如果
如果
语法导向操作 IsDestructuring 不接受参数并返回一个布尔值。它在以下产生式上定义:
本节由附录
语法导向操作 ForDeclarationBindingInitialization 接受参数 value(一个
它在以下产生式上定义:
语法导向操作 ForDeclarationBindingInstantiation 接受参数 environment(一个
语法导向操作 ForInOfLoopEvaluation 接受参数 labelSet(一个
本节由附录
抽象操作 ForIn/OfHeadEvaluation 接受参数 uninitializedBoundNames(一个
抽象操作 ForIn/OfBodyEvaluation 接受参数 lhs(一个
抽象操作 EnumerateObjectProperties 接受参数 O(一个对象)并返回一个迭代器。它在调用时执行以下步骤:
next
方法遍历 O 的所有可枚举的字符串键属性。迭代器对象对 ECMAScript
代码永远不可直接访问。遍历属性的机制和顺序未指定,但必须符合以下规则。
迭代器的 throw
和 return
方法是 next
方法处理对象属性以确定属性键是否应作为迭代器值返回。返回的属性键不包括 Symbols。目标对象的属性可能在枚举期间被删除。在迭代器的 next
方法处理之前删除的属性将被忽略。如果在枚举期间向目标对象添加新属性,则不能保证新添加的属性会在活动枚举中被处理。一个属性名在任何枚举中最多由迭代器的 next
方法返回一次。
枚举目标对象的属性包括枚举其原型及其原型的原型等的属性,递归地;但如果原型的属性与迭代器的 next
方法已经处理的属性同名,则不处理原型的属性。原型对象的可枚举属性名必须通过调用
EnumerateObjectProperties 并将原型对象作为参数来获取。EnumerateObjectProperties 必须通过调用目标对象的 [[OwnPropertyKeys]] 内部方法来获取目标对象的自有属性键。目标对象的属性属性必须通过调用其 [[GetOwnProperty]] 内部方法来获取。
此外,如果 O 或其原型链中的任何对象不是
ECMAScript 实现不需要直接实现
以下是一个符合这些规则的 ECMAScript 生成器函数的非正式定义:
function* EnumerateObjectProperties(obj) {
const visited = new Set();
for (const key of Reflect.ownKeys(obj)) {
if (typeof key === "symbol") continue;
const desc = Reflect.getOwnPropertyDescriptor(obj, key);
if (desc) {
visited.add(key);
if (desc.enumerable) yield key;
}
}
const proto = Reflect.getPrototypeOf(obj);
if (proto === null) return;
for (const protoKey of EnumerateObjectProperties(proto)) {
if (!visited.has(protoKey)) yield protoKey;
}
}
For-In 迭代器是表示特定对象上的特定迭代的对象。For-In 迭代器对象永远不会直接对 ECMAScript 代码可访问;它们仅存在于阐明
抽象操作 CreateForInIterator 接受参数 object(一个对象)并返回一个 For-In 迭代器。它用于创建一个 For-In 迭代器对象,该对象按特定顺序迭代 object 的自身和继承的可枚举字符串属性。调用时执行以下步骤:
%ForInIteratorPrototype% 对象:
For-In 迭代器实例是
continue
语句static
初始化块边界),则是语法错误。
break
语句static
初始化块边界),则是语法错误。
return
语句
return
语句会导致函数停止执行,并在大多数情况下返回一个值给调用者。如果省略了
return
语句可能实际上不会返回值给调用者。例如,在
try
块中,return
语句的
finally
块时被另一个
with
语句
with
语句为计算对象添加了一个
仅在实现
switch
语句
抽象操作 CaseClauseIsSelected 接受参数 C(一个
此操作不执行 C 的
无论控制如何离开
一个 break
和continue
语句结合使用。ECMAScript
没有goto
语句。
一个
如果实现了
抽象操作 IsLabelledFunction 接受参数 stmt (一个
一个
try 语句包含可能发生异常的代码块,如运行时错误或 throw 语句。catch 子句提供异常处理代码。当 catch 子句捕获异常时,其
对于此生成规则的替代静态语义定义,见
CatchClauseEvaluation 是一个带有参数 thrownValue(一个 ECMAScript 语言值)的语法直接操作,返回一个包含 ECMAScript 语言值的正常完成记录或一个中断完成记录。它在以下生成规则中定义:
无论控制如何离开
debugger
语句执行
各种 ECMAScript 语言元素会导致创建 ECMAScript
在
匿名的 export default
声明的一部分出现,因此其函数代码始终是
替代语义见
使用
处理生产式的实例时
arguments
,super
,this
或 new.target
的本地绑定。在
arguments
,super
,this
或 new.target
的任何引用必须解析为词法上封闭的环境中的绑定。通常,这将是紧密封闭函数的函数环境。即使
super
的引用,在步骤
super
的
super
所需的状态可以通过
语法指向操作 HasDirectSuper 不接受任何参数并返回一个布尔值。它在以下生成式上逐段定义:
语法指向操作 SpecialMethod 不接受任何参数并返回一个布尔值。它在以下生成式上逐段定义:
语法指向操作 DefineMethod 接受参数 object(一个对象)和可选参数 functionPrototype(一个对象),并返回一个包含字段 [[Key]](一个属性键)和 [[Closure]](一个 ECMAScript 函数对象)的 Record 的正常完成,或一个中断完成。它在以下生成式上逐段定义:
语法指向操作 MethodDefinitionEvaluation 接受参数 object(一个对象)和 enumerable(一个布尔值),并返回包含一个 PrivateElement 或 unused 的正常完成,或一个中断完成。它在以下生成式上逐段定义:
紧接在 yield
之后的语法上下文要求使用
语法导向操作
语法导向操作
匿名的 export default
声明的一部分出现,因此其函数代码始终是
throw
方法抛出的异常会被传播。throw
方法的正常完成与 next
类似。
匿名的
export default
声明的一部分出现。
在
类定义总是
如果
await
为 早期错误规则确保只有一个名为
本规范中未列出的每个语法生成式替代项隐含有以下默认的 AllPrivateIdentifiersValid 定义:
本规范中未列出的每个语法生成式替代方案隐式具有以下 ContainsArguments 的默认定义: