?
u
m
/
p
1-9
0
`
位于 https://tc39.es/ecma262/ 的文档是最准确和最新的 ECMAScript 规范。它包含最新年度快照的内容以及自该快照以来的所有 已完成提案 (那些在 提案流程 中达到第4阶段的提案,因此已在多个实现中实现,将包含在下一个实际修订版中)。
本规范在 GitHub 上借助 ECMAScript 社区的帮助进行开发。有多种方式可以为本规范的开发做出贡献:
有关本文档创建方式的更多信息,请参阅
本 Ecma 标准定义了 ECMAScript 2026 语言。这是 ECMAScript 语言规范的第十七版。自 1997 年第一版发布以来,ECMAScript 已经发展成为世界上最广泛使用的通用编程语言之一。它最为人所知的是作为嵌入在 Web 浏览器中的语言,但也被广泛应用于服务器和嵌入式应用程序。
ECMAScript 基于几种原创技术,最著名的是 JavaScript(Netscape)和 JScript(Microsoft)。该语言由 Brendan Eich 在 Netscape 发明,首次出现在该公司的 Navigator 2.0 浏览器中。它出现在 Netscape 的所有后续浏览器中,以及从 Internet Explorer 3.0 开始的所有 Microsoft 浏览器中。
ECMAScript 语言规范的开发始于 1996 年 11 月。本 Ecma 标准的第一版于 1997 年 6 月由 Ecma 大会通过。
该 Ecma 标准已提交给 ISO/IEC JTC 1,按照快速通道程序通过,并于 1998 年 4 月批准为国际标准 ISO/IEC 16262。1998 年 6 月的 Ecma 大会批准了 ECMA-262 的第二版,以保持与 ISO/IEC 16262 完全一致。第一版和第二版之间的变化在性质上是编辑性的。
该标准的第三版引入了强大的正则表达式、更好的字符串处理、新的控制语句、try/catch 异常处理、更严格的错误定义、数值输出格式化以及为预期的未来语言增长而进行的小幅更改。ECMAScript 标准的第三版于 1999 年 12 月由 Ecma 大会通过,并于 2002 年 6 月作为 ISO/IEC 16262:2002 发布。
第三版发布后,ECMAScript 与万维网结合实现了大规模应用,成为几乎所有 Web 浏览器支持的编程语言。为开发 ECMAScript 第四版做了大量工作。然而,这项工作没有完成,也没有作为 ECMAScript 第四版发布,但其中一些内容被纳入了第六版的开发中。
ECMAScript 第五版(作为 ECMA-262 第 5 版发布)编纂了在浏览器实现中已经常见的语言规范的事实解释,并增加了对自第三版发布以来出现的新功能的支持。这些功能包括
第五版已提交给 ISO/IEC JTC 1,按照快速通道程序通过,并批准为国际标准 ISO/IEC 16262:2011。ECMAScript 标准的 5.1 版纳入了小幅更正,与 ISO/IEC 16262:2011 文本相同。5.1 版于 2011 年 6 月由 Ecma 大会通过。
第六版的重点开发始于 2009 年,当时第五版正在准备发布。然而,这之前进行了大量的实验和语言增强设计工作,可以追溯到 1999
年第三版的发布。从很真实的意义上说,第六版的完成是十五年努力的顶峰。这一版的目标包括为大型应用程序、库创建以及将 ECMAScript
用作其他语言的编译目标提供更好的支持。它的一些主要增强功能包括模块、类声明、词法块作用域、
ECMAScript 2016 是在 Ecma TC39 新的年度发布节奏和开放开发过程下发布的第一个 ECMAScript 版本。从 ECMAScript 2015 源文档构建了一个纯文本源文档,作为完全在
GitHub 上进一步开发的基础。在这个标准开发的一年中,提交了数百个拉取请求和问题,代表了数千个错误修复、编辑修复和其他改进。此外,还开发了许多软件工具来帮助这一工作,包括
Ecmarkup、Ecmarkdown 和 Grammarkdown。ES2016 还包括对新指数运算符的支持,并向 Array.prototype
添加了一个名为
includes
的新方法。
ECMAScript 2017 引入了异步函数、共享内存和原子操作,以及较小的语言和库增强、错误修复和编辑更新。异步函数通过为返回 promise
的函数提供语法来改善异步编程体验。共享内存和原子操作引入了新的Object.values
、Object.entries
和
Object.getOwnPropertyDescriptors
。
ECMAScript 2018 通过dotAll
标志、命名捕获组、Unicode 属性转义和后行断言。最后,它包括对象 rest 和展开属性。
ECMAScript 2019 引入了一些新的内置函数:Array.prototype
上用于扁平化数组的 flat
和
flatMap
,用于直接将 Object.entries
的返回值转换为新 Object 的
Object.fromEntries
,以及 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
,一个在模块中可用的
ECMAScript 2021,第 12 版,为字符串引入了 replaceAll
方法;Promise.any
,一个在输入值被满足时短路的 Promise
组合器;AggregateError
,一个同时表示多个错误的新 Error
类型;逻辑赋值运算符(??=
、&&=
、||=
);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 文件;并允许在弱集合中使用大多数 Symbol 作为键。
ECMAScript 2024,第 15 版,增加了调整大小和传输 ArrayBuffer 和 SharedArrayBuffer 的功能;增加了新的 RegExp /v
标志,用于创建具有更高级功能的 RegExp 以处理字符串集合;并引入了用于构造 Promise 的 Promise.withResolvers
便捷方法,用于聚合数据的
Object.groupBy
和 Map.groupBy
方法,用于异步等待共享内存更改的 Atomics.waitAsync
方法,以及用于检查和确保字符串仅包含格式良好的 Unicode 的 String.prototype.isWellFormed
和
String.prototype.toWellFormed
方法。
ECMAScript 2025,第 16 版,添加了一个新的 Iterator
全局对象,带有相关的静态和原型方法,用于处理Set.prototype
添加了用于对 Set 执行常见操作的方法;增加了对导入 JSON 模块的支持以及用于声明导入模块属性的语法;添加了用于转义字符串以在正则表达式中安全使用的
RegExp.escape
方法;添加了用于在正则表达式内内联启用和禁用修饰符标志的语法;添加了用于调用可能返回或可能不返回 Promise
的函数并确保结果始终为 Promise
的 Promise.try
方法;并添加了新的 Float16Array
DataView.prototype.getFloat16
、DataView.prototype.setFloat16
和
Math.f16round
方法。
代表众多组织的数十名个人在 Ecma TC39 内对本版本和以前版本的开发做出了非常重要的贡献。此外,已经形成了一个充满活力的社区来支持 TC39 的 ECMAScript 工作。这个社区审查了许多草案,提交了数千个错误报告,进行了实现实验,贡献了测试套件,并向全球开发者社区介绍了 ECMAScript。不幸的是,无法识别和承认每个为这一努力做出贡献的个人和组织。
Allen Wirfs-Brock
ECMA-262,项目编辑,第 6 版
Brian Terlson
ECMA-262,项目编辑,第 7 至第 10 版
Jordan Harband
ECMA-262,项目编辑,第 10 至第 12 版
Shu-yu Guo
ECMA-262,项目编辑,第 12 至第 16 版
Michael Ficarra
ECMA-262,项目编辑,第 12 至第 16 版
Kevin Gibbons
ECMA-262,项目编辑,第 12 至第 16 版
本标准定义了 ECMAScript 2026 通用编程语言。
ECMAScript 的一致性实现必须提供并支持本规范中描述的所有类型、值、对象、属性、函数以及程序语法和语义。
ECMAScript 的一致性实现必须按照最新版本的 Unicode 标准和 ISO/IEC 10646 来解释源文本输入。
提供应用程序编程接口 (API) 的 ECMAScript 一致性实现,如果该 API 支持需要适应不同人类语言和国家使用的语言和文化约定的程序,则必须实现与本规范兼容的最新版本 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 最初被设计为Web 脚本语言,提供在浏览器中活跃网页并作为基于 Web 的客户端-服务器架构的一部分执行服务器计算的机制。ECMAScript
现在用于为各种
ECMAScript 的使用已经超越了简单的脚本编写,现在用于许多不同环境和规模中编程任务的全谱。随着 ECMAScript 使用的扩展,它提供的功能和设施也在扩展。ECMAScript 现在是一种功能齐全的通用编程语言。
Web 浏览器为客户端计算提供 ECMAScript
Web 服务器为服务器端计算提供不同的
每个支持 ECMAScript 的 Web 浏览器和服务器都提供自己的
为了帮助将 ECMAScript 集成到
实现是进一步定义附录
实现定义设施是将其定义推迟到外部来源而无需进一步限定的设施。本规范不对特定行为提出任何建议,符合规范的实现可以在本规范提出的约束内自由选择任何行为。
实现近似设施是将其定义推迟到外部来源同时推荐理想行为的设施。虽然符合规范的实现可以在本规范提出的约束内自由选择任何行为,但鼓励它们努力接近理想。某些数学运算,如Math.exp
宿主是进一步定义附录
宿主钩子是全部或部分由外部来源定义的抽象操作。所有
宿主定义设施是将其定义推迟到外部来源而无需进一步限定并在附录
宿主环境是对所有
以下是 ECMAScript 的非正式概述——并非语言的所有部分都被描述。这个概述不是标准本身的一部分。
ECMAScript 是基于对象的:基本语言和
ECMAScript 定义了一个内置对象集合,完善了 ECMAScript 实体的定义。这些内置对象包括Object
、Function
、Boolean
、Symbol
和各种
Error
对象;表示和操作数值的对象,包括 Math
、Number
和
Date
;文本处理对象 String
和 RegExp
;作为值的索引集合的对象,包括
Array
和九种不同类型的类型化数组,其元素都有特定的数值数据表示;键值集合,包括 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。这些对象中的每一个都包含名为
与大多数基于类的对象语言不同,可以通过为对象赋值来动态添加属性。也就是说,
虽然 ECMAScript 对象本质上不是基于类的,但基于
ECMAScript 语言认识到一些语言用户可能希望限制使用语言中可用的某些功能的可能性。他们可能出于安全考虑、避免他们认为容易出错的功能、获得增强的错误检查或其他他们选择的原因而这样做。为了支持这种可能性,ECMAScript 定义了语言的严格变体。语言的严格变体排除了常规 ECMAScript 语言的一些特定语法和语义功能,并修改了一些功能的详细语义。严格变体还指定了必须通过在非严格形式的语言未指定为错误的情况下抛出错误异常来报告的额外错误条件。
ECMAScript 的严格变体通常被称为语言的严格模式。严格模式的选择和使用以及 ECMAScript 的严格模式语法和语义在个别
为了符合本规范,ECMAScript 实现必须实现完整的无限制 ECMAScript 语言和本规范定义的 ECMAScript 语言的严格变体。此外,实现必须支持将无限制和严格模式源文本单元组合到单个复合程序中。
就本文档而言,以下术语和定义适用。
与
编辑上,见条款
如条款
Undefined、Null、Boolean、Number、BigInt、Symbol 或 String 类型之一的成员,如条款
原始值是在语言实现的最低级别直接表示的数据。
Object 类型的成员
对象是属性的集合,并且有一个原型对象。原型可能是
创建和初始化对象的
为其他对象提供共享属性的对象
对于所有对象必须支持的基本内部方法具有默认行为的对象
对于一个或多个基本内部方法没有默认行为的对象
语义由本规范定义的对象
由 ECMAScript 实现指定和提供的对象
标准内置对象在本规范中定义。ECMAScript 实现可以指定和提供本规范中未描述的其他类型的内置对象。
在变量未被赋值时使用的原始值
唯一值为
表示故意缺少任何对象值的原始值
唯一值为
只有两个 Boolean 值,
由原始值
Boolean 对象通过在 new
表达式中使用 Boolean
所有可能 String 值的集合
对应于双精度 64 位二进制格式
Number 值是
所有可能 Number 值的集合,包括
正无限 Number 值的 Number 值
对应于任意精度
所有可能 BigInt 值的集合
表示唯一、非 String 对象
所有可能 Symbol 值的集合
除了其属性外,函数包含可执行代码和状态,这些决定了调用时的行为。函数的代码可能用 ECMAScript 编写,也可能不是。
是函数的内置对象
内置函数的例子包括 parseInt
和 Math.exp
。
是
对象的一部分,将键(String 值或 Symbol 值)与值关联
根据属性的形式,值可以直接表示为数据值(原始值、对象或
作为属性值的函数
当函数作为对象的方法调用时,对象作为其
是内置函数的方法
标准内置方法在本规范中定义。
定义属性某些特征的内部值
直接包含在其对象中的属性
对象的属性,不是自有属性但是对象原型的属性(自有或继承)
本规范的其余部分组织如下:
章节
章节
章节
章节
章节
上下文无关文法由若干产生式组成。每个产生式的左侧有一个称为非终结符的抽象符号,右侧是零个或多个非终结符和终结符符号的序列。对于每个文法,终结符都从指定的字母表中选取。
链式产生式是在其右侧恰好有一个非终结符号以及零个或多个终结符的产生式。
从一个由单一特殊非终结符组成的句子开始,称为目标符号,给定的上下文无关文法指定一种语言,即,通过反复将序列中的任何非终结符替换为以该非终结符作为左侧的产生式的右侧,可能产生的终结符序列的(可能无限的)集合。
ECMAScript 的词法文法在
除空白和注释之外的输入元素构成了 ECMAScript 句法文法的终结符,并被称为 ECMAScript 标记。这些标记是 ECMAScript 语言的/*
…*/
的注释,无论其是否跨越多行)不包含行终止符,则同样会被简单丢弃;但如果
ECMAScript 的 RegExp 文法在章节
词法文法和 RegExp 文法的产生式以两个冒号"::"作为分隔标点符号来区分。词法文法和 RegExp 文法共享一些产生式。
数值字符串文法出现在章节
数值字符串文法的产生式以三个冒号":::"作为标点符号来区分,从不用于解析源文本。
ECMAScript 的语法文法在章节
当代码点流要被解析为 ECMAScript
当解析成功时,它构造一个解析树,这是一个根树结构,其中每个节点都是一个解析节点。每个解析节点是文法中符号的一个实例;它表示可以从该符号派生的源文本范围。表示整个源文本的解析树根节点是解析的
为每次解析器调用实例化新的解析节点,即使是相同源文本的解析也从不重用。当且仅当解析节点表示相同的源文本范围、是相同文法符号的实例且来自相同的解析器调用时,才被认为是同一个解析节点。
多次解析相同的字符串将导致不同的解析节点。例如,考虑:
let str = "1 + 1;";
eval(str);
eval(str);
每次调用 eval
都将 str
的值转换为
语法文法的产生式以仅一个冒号":"作为标点符号来区分。
章节
在某些情况下,为了避免歧义,语法文法使用广义产生式,允许不构成有效 ECMAScript
在 ECMAScript 文法中,一些终结符号以 固定宽度
字体显示。
这些符号必须在源文本中完全按照所写的方式出现。以这种方式指定的所有终结符号代码点
都应理解为来自基本拉丁块的适当 Unicode 代码点,而不是来自其他 Unicode 范围的任何类似代码点。
终结符号中的代码点不能用 \
在终结符号为单个 Unicode 代码点的文法中(即词法、正则表达式和数字字符串文法), 产生式中出现的多个连续固定宽度代码点是相同代码点序列的简写, 写作独立的终结符号。
例如,产生式:
是以下的简写:
相比之下,在语法文法中,连续的固定宽度代码点是单个终结符号。
终结符号有另外两种形式:
非终结符号以 斜体 显示。非终结符的定义(也称为"产生式") 由要定义的非终结符的名称后跟一个或多个冒号引入。(冒号的数量表示产生式属于哪个文法。) 然后在后续行中跟随非终结符的一个或多个可选右侧。例如,语法定义:
表示非终结符 while
,后跟左括号 token,后跟
表示
下标后缀 "opt" 可能出现在终结符或非终结符之后,表示可选符号。 包含可选符号的选择实际上指定了两个右侧,一个省略可选元素,一个包含它。这意味着:
是以下的便利缩写:
并且:
是以下的便利缩写:
这又是以下的缩写:
所以,在这个例子中,非终结符
产生式可以通过下标注释的形式 "[parameters]" 进行参数化, 该注释可以作为产生式定义的非终结符号的后缀出现。"parameters" 可以是单个名称 或用逗号分隔的名称列表。参数化产生式是一组产生式的简写, 定义了参数名称的所有组合,在下划线前面,附加到参数化非终结符号。这意味着:
是以下的便利缩写:
并且:
是以下的缩写:
多个参数产生组合数量的产生式,并非所有这些产生式都必须在完整文法中引用。
产生式右侧的非终结符引用也可以参数化。例如:
等价于说:
并且:
等价于:
非终结符引用可以同时具有参数列表和 "opt" 后缀。例如:
是以下的缩写:
在右侧非终结符引用中,使用 "?" 作为参数名称的前缀 使该参数值依赖于当前产生式左侧符号引用中该参数名称的出现。例如:
是以下的缩写:
如果右侧选择以 "[+parameter]" 为前缀,那么该选择只有在引用产生式的非终结符号时使用了命名参数才可用。 如果右侧选择以 "[~parameter]" 为前缀,那么该选择只有在引用产生式的非终结符号时 没有 使用命名参数才可用。这意味着:
是以下的缩写:
并且:
是以下的缩写:
当单词 "one of" 跟在文法定义中的冒号后面时,它们表示后续行中的每个终结符号 都是一个可选定义。例如,ECMAScript 的词法文法包含产生式:
这只是以下的便利缩写:
如果短语 "[empty]" 作为产生式的右侧出现,它表示产生式的右侧不包含终结符或非终结符。
如果短语 "[lookahead = seq]" 出现在产生式的右侧,
它表示只有当标记序列 seq 是紧随其后的输入标记序列的前缀时,才能使用该产生式。类似地,"[lookahead ∈
set]"(其中 set 是标记序列的
这些条件可以被否定。"[lookahead ≠ seq]" 表示只有当 seq 不是紧随其后的输入标记序列的前缀时,才能使用包含的产生式,而 "[lookahead ∉ set]" 表示只有当 set 中没有元素是紧随其后的标记序列的前缀时,才能使用该产生式。
作为示例,给定定义:
定义:
匹配字母 n
后跟一个或多个十进制数字(其中第一个数字是偶数),或者一个十进制数字后面不跟另一个十进制数字。
注意,当这些短语在语法文法中使用时,可能无法明确地识别紧随其后的标记序列,因为确定后续标记需要知道在后续位置使用哪个词法
如果短语 "[no
表示如果在脚本的 throw
标记和
除非受限产生式禁止出现
产生式的右侧可以通过使用短语 "but not" 然后指出要排除的展开来指定某些展开是不被允许的。例如,产生式:
意味着非终结符
最后,少数非终结符通过无衬线字体的描述性短语来描述,这是在列出所有选择不切实际的情况下:
本规范通常使用编号列表来指定算法中的步骤。这些算法用于精确指定 ECMAScript 语言构造所需的语义。这些算法并非旨在暗示使用任何特定的实现技术。实际上,可能存在更有效的算法来实现给定的特性。
算法可以使用有序的、逗号分隔的别名序列进行显式参数化,这些别名可以在算法步骤中用于引用在该位置传入的参数。可选参数用方括号([ , name
])表示,在算法步骤中与必需参数没有区别。剩余参数可以出现在参数列表的末尾,用前导省略号(, ...name)表示。剩余参数将捕获在必需参数和可选参数之后提供的所有参数到一个
算法步骤可以细分为顺序的子步骤。子步骤是缩进的,并且它们本身可以进一步划分为缩进的子步骤。使用大纲编号约定来标识子步骤,第一级子步骤用小写字母标记,第二级子步骤用小写罗马数字标记。如果需要三个以上的级别,则这些规则会重复,第四级使用数字标签。例如:
一个步骤或子步骤可以写成一个“if”谓词,该谓词对其子步骤进行条件限制。在这种情况下,仅当谓词为真时才应用子步骤。如果一个步骤或子步骤以单词“else”开头,则它是一个谓词,该谓词是同一级别上在前的“if”谓词步骤的否定。
一个步骤可以指定其子步骤的迭代应用。
以“断言:”开头的步骤断言其算法的不变条件。此类断言用于明确算法中否则将是隐式的不变量。此类断言不增加额外的语义要求,因此实现无需检查。它们仅用于阐明算法。
算法步骤可以使用“令 x 为 someValue”的形式为任何值声明命名别名。这些别名是引用式的,即 x 和 someValue 都引用相同的基础数据,对其中任何一个的修改对两者都可见。希望避免这种引用式行为的算法步骤应显式复制右侧的值:“令 x 为 someValue 的副本”会创建 someValue 的浅拷贝。
一旦声明,别名就可以在任何后续步骤中引用,并且不得在别名声明之前的步骤中引用。可以使用“将 x 设置为 someOtherValue”的形式修改别名。
为了便于在规范的多个部分中使用,一些算法(称为抽象操作)被命名并以参数化函数形式编写,以便可以从其他算法中按名称引用它们。抽象操作通常使用函数应用样式(如 OperationName(arg1, arg2))进行引用。一些抽象操作被视为类规范抽象的多态分派方法。此类方法式抽象操作通常使用方法应用样式(如 someValue.OperationName(arg1, arg2))进行引用。
语法导向操作是一种命名操作,其定义由算法组成,每个算法都与 ECMAScript
语法中的一个或多个产生式相关联。具有多个备选定义的产生式通常会为每个备选方案提供一个不同的算法。当算法与语法产生式相关联时,它可以像引用算法参数一样引用产生式备选方案的终结符和非终结符。以这种方式使用时,非终结符指的是解析源文本时匹配的实际备选定义。语法产生式或由其派生的
当算法与产生式备选方案相关联时,该备选方案通常不带任何“[ ]”语法注释。此类注释仅影响备选方案的语法识别,对备选方案的相关语义没有影响。
语法导向操作通过使用以下算法中的步骤
除非另有明确规定,否则所有
但是
运行时语义:
指定必须在运行时调用的语义的算法称为运行时语义。运行时语义由
抽象操作 Completion 接受参数 completionRecord(一个
算法步骤中说要抛出异常,例如:
与以下含义相同:
算法步骤中说或等效于:
与以下含义相同:
算法步骤中说或等效于:
与以下含义相同:
其中 hygienicTemp 是临时的,并且仅在与 ReturnIfAbrupt 相关的步骤中可见。
算法步骤中说或等效于:
与以下含义相同:
以 ?
为前缀的
等效于以下步骤:
类似地,对于方法应用样式,步骤:
等效于:
类似地,前缀 !
用于指示以下抽象操作或
等效于以下步骤:
!
或
?
来使用此简写:
在声明返回
如果通过任何其他方式从此类抽象操作返回
与以下任何一种含义相同:
或
或
请注意,通过
以下示例将是编辑错误,因为正在返回一个
上下文无关文法不足以表达所有规则,这些规则定义输入元素流是否形成一个有效的、可以求值的 ECMAScript
静态语义规则具有名称,并且通常使用算法定义。命名的静态语义规则与语法产生式相关联,具有多个备选定义的产生式通常会为每个备选方案的每个适用的命名静态语义规则提供一个不同的算法。
一种特殊的静态语义规则是早期错误规则。
本规范引用以下类型的数值:
在本规范的语言中,使用下标后缀来区分不同数值种类的数值。下标 𝔽 指的是数字,下标 ℤ 指的是
BigInts。没有下标后缀的数值指的是
通常,当本规范引用一个数值时,例如在短语“y 的长度”或“由四个十六进制数字表示的
当本规范中使用术语整数时,它指的是一个
诸如 +、×、= 和 ≥ 之类的数值运算符指的是由操作数类型决定的那些运算。当应用于
数学函数
数学函数
符号“
短语“将 x 限制在 lower 和 upper
之间”的结果(其中 x 是一个
数学函数
数学函数
数学函数
从下界 a 到上界 b 的区间是一个可能是无限的、可能是空的、相同数值类型的数值集合。每个界限将被描述为包含的或排除的,但不能两者都是。有四种区间,如下所示:
例如,从 1(包含)到 2(排除)的
在本规范中,Function.prototype.apply
或
let n = 42;
)相区别。
在本规范中,规范值和
从本规范的角度来看,“是”用于比较两个值的相等性,如“如果 bool 是
从 ECMAScript 语言的角度来看,语言值使用
对于规范值,无规范同一性的值的示例包括但不限于:
对于所有
本规范中的算法操作的值都具有关联的类型。可能的值类型正是本条款中定义的那些类型。类型进一步分为
ECMAScript 语言类型对应于 ECMAScript 程序员使用 ECMAScript 语言直接操作的值。ECMAScript 语言类型包括 Undefined、Null、Boolean、String、Symbol、Number、BigInt 和 Object。 ECMAScript 语言值 是由 ECMAScript 语言类型表征的值。
Undefined 类型只有一个值,称为
Null 类型只有一个值,称为
Boolean 类型表示一个逻辑实体,具有两个值,称为
字符串类型是所有长度不超过 253 - 1 个元素的零个或多个 16
位无符号
不解释字符串内容的 ECMAScript 操作不应用任何进一步的语义。解释字符串值的操作将每个元素视为单个 UTF-16 代码单元。但是,ECMAScript
不限制这些代码单元的值或它们之间的关系,因此将字符串内容进一步解释为以 UTF-16 编码的 Unicode 码点序列的操作必须考虑到格式错误的子序列。此类操作对数值在
函数 String.prototype.normalize
(参见 String.prototype.localeCompare
(参见
这种设计背后的基本原理是使字符串的实现尽可能简单和高性能。如果
在本规范中,短语“A、B、... 的字符串连接”(其中每个参数都是字符串值、代码单元或代码单元序列)表示其代码单元序列是每个参数(按顺序)的代码单元(按顺序)连接而成的字符串值。
短语“S 从 inclusiveStart 到 exclusiveEnd 的子字符串”(其中 S 是字符串值或代码单元序列,inclusiveStart 和
exclusiveEnd 是
短语“ASCII 词字符”表示以下字符串值,该值仅由 Unicode
基本拉丁块中的所有字母和数字以及 U+005F (LOW LINE) 组成:
由于历史原因,它对各种算法具有重要意义。
抽象操作 StringIndexOf 接受参数 string (一个字符串)、searchValue (一个字符串) 和
fromIndex (一个非负
如果 searchValue 是空字符串且 fromIndex ≤ string 的长度,则此算法返回 fromIndex。空字符串实际上在字符串中的每个位置都能找到,包括最后一个代码单元之后。
如果 fromIndex + searchValue 的长度 > string 的长度,则此算法始终返回
抽象操作 StringLastIndexOf 接受参数 string (一个字符串)、searchValue (一个字符串) 和
fromIndex (一个非负
如果 searchValue 是空字符串,则此算法返回 fromIndex。空字符串实际上在字符串中的每个位置都能找到,包括最后一个代码单元之后。
Symbol 类型是所有可用作对象属性键(
每个可能的 Symbol 值都是唯一且不可变的。
每个 Symbol 值都不可变地持有一个关联值,称为 [[Description]],该值要么是
知名符号是本规范算法明确引用的内置 Symbol 值。它们通常用作属性的键,这些属性的值充当规范算法的扩展点。除非另有规定,否则知名符号值由所有
在本规范中,使用标准的
%Symbol.name%
。特别是,使用了以下名称:@@asyncIterator、@@hasInstance、@@isConcatSpreadable、@@规范名称 | [[Description]] | 值和用途 |
---|---|---|
%Symbol.asyncIterator% |
|
一个返回对象默认for -await -of 语句的语义调用。
|
%Symbol.hasInstance% |
|
一个确定instanceof 运算符的语义调用。
|
%Symbol.isConcatSpreadable% |
|
一个布尔值属性,如果为 true,则表示一个对象应由 Array.prototype.concat |
%Symbol.iterator% |
|
一个返回对象默认 |
%Symbol.match% |
|
一个正则表达式方法,用于将正则表达式与字符串进行匹配。由 String.prototype.match |
%Symbol.matchAll% |
|
一个正则表达式方法,返回一个String.prototype.matchAll |
%Symbol.replace% |
|
一个正则表达式方法,用于替换字符串中匹配的子字符串。由 String.prototype.replace |
%Symbol.search% |
|
一个正则表达式方法,返回字符串中与正则表达式匹配的索引。由 String.prototype.search |
%Symbol.species% |
|
一个函数值属性,是用于创建派生对象的 |
%Symbol.split% |
|
一个正则表达式方法,用于在与正则表达式匹配的索引处拆分字符串。由 String.prototype.split |
%Symbol.toPrimitive% |
|
一个将对象转换为相应原始值的方法。由 |
%Symbol.toStringTag% |
|
一个字符串值属性,用于创建对象的默认字符串描述。由内置方法 Object.prototype.toString |
%Symbol.unscopables% |
|
一个对象值属性,其自身和继承的属性名称是从关联对象的 with 环境绑定中排除的属性名称。
|
ECMAScript 有两种内置的数字类型:Number 和 BigInt。以下
由于数字类型通常无法在不损失精度或截断的情况下进行转换,因此 ECMAScript 语言不提供这些类型之间的隐式转换。在调用需要另一种类型的函数时,程序员必须显式调用
Number
和 BigInt
函数在类型之间进行转换。
ECMAScript 的第一版及后续版本为某些运算符提供了可能损失精度或
Number 类型恰好有
18,437,736,874,454,810,627 (即 NaN
产生。)在某些实现中,外部代码可能能够检测到各种 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 是
注意,所有大小不超过 253 的正负
如果一个
在本规范中,短语“x 的Number 值”(其中 x 表示一个精确的实数数学量,甚至可能是一个无理数,如
π)指的是按以下方式选择的 Number 值。考虑 Number 类型的所有
+∞ 的
某些 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::signedRightShift 接受参数 x (一个 Number) 和 y (一个 Number)
并返回一个
抽象操作 Number::unsignedRightShift 接受参数 x (一个 Number) 和 y (一个 Number)
并返回一个
抽象操作 Number::lessThan 接受参数 x (一个 Number) 和 y (一个 Number) 并返回一个
Boolean 或
抽象操作 Number::equal 接受参数 x (一个 Number) 和 y (一个 Number) 并返回一个 Boolean。调用时它执行以下步骤:
抽象操作 Number::sameValue 接受参数 x (一个 Number) 和 y (一个 Number) 并返回一个 Boolean。调用时它执行以下步骤:
抽象操作 Number::sameValueZero 接受参数 x (一个 Number) 和 y (一个 Number) 并返回一个 Boolean。调用时它执行以下步骤:
抽象操作 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 (一个 Number) 和 radix (一个
1.2e+3
。ECMAScript 的实现者可能会发现 David M. Gay 编写的用于浮点数二进制到十进制转换的论文和代码很有用:
Gay, David M. Correctly Rounded Binary-Decimal and Decimal-Binary Conversions.
Numerical Analysis, Manuscript 90-10. AT&T Bell Laboratories (Murray Hill,
New Jersey). 1990年11月30日。可从以下网址获取:
https://ampl.com/_archive/first-website/REFS/rounding.pdf。
相关代码可从以下网址获取:
http://netlib.sandia.gov/fp/dtoa.c
和
http://netlib.sandia.gov/fp/g_fmt.c
也可以在各种 netlib
镜像站点找到。
BigInt 类型表示一个
抽象操作 BigInt::unaryMinus 接受参数 x(一个 BigInt)并返回一个 BigInt。调用时执行以下步骤:
抽象操作 BigInt::bitwiseNOT 接受参数 x(一个 BigInt)并返回一个 BigInt。它返回 x 的一的补码。调用时执行以下步骤:
抽象操作 BigInt::exponentiate 接受参数 base(一个 BigInt)和 exponent(一个
BigInt),返回
抽象操作 BigInt::multiply 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。调用时执行以下步骤:
抽象操作 BigInt::divide 接受参数 x(一个 BigInt)和 y(一个 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。调用时执行以下步骤:
抽象操作 BigIntBitwiseOp 接受参数 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
的
Object 类型的每个实例,也简称为"一个 Object",表示属性的集合。每个属性要么是数据属性,要么是访问器属性:
对象的属性使用
整数索引是
所有对象在逻辑上都是属性的集合,但存在多种形式的对象,它们在访问和操作属性的语义上有所不同。请参见
此外,某些对象是可调用的;这些被称为函数或
本规范使用特性来定义和解释 Object 属性的状态,如
特性名称 | 存在该特性的属性类型 | 值域 | 默认值 | 描述 |
---|---|---|---|---|
[[Value]] | 通过对属性的 get 访问检索到的值。 | |||
[[Writable]] | 布尔值 | 如果为 |
||
[[Get]] | Object 或 |
如果值 |
||
[[Set]] | Object 或 |
如果值 |
||
[[Enumerable]] | 布尔值 | 如果为 |
||
[[Configurable]] | 布尔值 | 如果为 |
在 ECMAScript 中,对象的实际语义通过称为内部方法的算法指定。ECMAScript 引擎中的每个对象都与一组定义其运行时行为的内部方法相关联。这些内部方法不是 ECMAScript 语言的一部分。它们由本规范纯粹为了解释目的而定义。但是,ECMAScript 实现中的每个对象都必须按照与其关联的内部方法所指定的方式行为。实现这一点的确切方式由实现决定。
内部方法名称是多态的。这意味着当在不同的对象值上调用相同的内部方法名称时,可能执行不同的算法。实际调用内部方法的对象是调用的"目标"。如果在运行时,算法的实现尝试使用对象不支持的内部方法,则抛出
内部槽对应于与对象关联并由各种 ECMAScript 规范算法使用的内部状态。内部槽不是对象属性,它们不被继承。根据特定的内部槽规范,这种状态可能由任何
所有对象都有一个名为 [[PrivateElements]] 的内部槽,它是
内部方法和内部槽在本规范中使用双方括号 [[ ]] 括起来的名称标识。
普通对象是满足以下所有条件的对象:
异质对象是不是
本规范通过对象的内部方法识别不同种类的
除了参数之外,内部方法始终可以访问作为方法调用目标的对象。
内部方法隐式返回
内部方法 | 签名 | 描述 |
---|---|---|
[[GetPrototypeOf]] | ( ) → Object | Null | 确定为此对象提供继承属性的对象。 |
[[SetPrototypeOf]] | (Object | Null) → Boolean | 将此对象与提供继承属性的另一个对象关联。传递 |
[[IsExtensible]] | ( ) → Boolean | 确定是否允许向此对象添加额外属性。 |
[[PreventExtensions]] | ( ) → Boolean | 控制是否可以向此对象添加新属性。如果操作成功则返回 |
[[GetOwnProperty]] | (propertyKey) → Undefined | |
返回此对象键为 propertyKey 的自有属性的 |
[[DefineOwnProperty]] | (propertyKey, PropertyDescriptor) → Boolean | 创建或更改键为 propertyKey 的自有属性,使其具有 PropertyDescriptor
描述的状态。如果该属性成功创建/更新则返回 |
[[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 语言构造和
枚举是规范内部的值,不能从 ECMAScript
代码直接观察到。枚举使用
列表类型用于解释 new
表达式、函数调用和其他需要简单有序值列表的算法中参数列表的求值(参见
当算法遍历列表的元素而不指定顺序时,使用的顺序是列表中元素的顺序。
为了在本规范中方便表示,可以使用字面量语法来表达新的列表值。例如,« 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
)的行为。
完成记录具有
以下简写术语有时用于指代完成记录。
本规范中定义的可调用对象只返回正常完成或 throw 完成。返回任何其他类型的完成记录被认为是编辑错误。
抽象操作 NormalCompletion 接受参数 value(除
抽象操作 ThrowCompletion 接受参数 value(一个
抽象操作 ReturnCompletion 接受参数 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)。与
在创建抽象闭包的算法步骤中,值使用动词"capture"后跟别名列表来捕获。当创建抽象闭包时,它捕获当时与每个别名关联的值。在指定调用抽象闭包时要执行的算法的步骤中,每个捕获的值都通过用于捕获该值的别名来引用。
如果抽象闭包返回
抽象闭包作为其他算法的一部分内联创建,如以下示例所示。
数据块规范类型用于描述一个不同且可变的字节大小(8位)数值序列。字节值是
为了在本规范中表示方便,可以使用类似数组的语法来访问数据块值的各个字节。此表示法将数据块值表示为基于 0 的
驻留在内存中且可以被多个
共享数据块的语义通过
本规范中使用以下
抽象操作 CreateByteDataBlock 接受参数 size(一个非负
抽象操作 CreateSharedByteDataBlock 接受参数 size(一个非负
抽象操作 CopyDataBlockBytes 接受参数 toBlock(一个
PrivateElement 类型是一个
PrivateElement 类型的值是
字段名 | 出现该字段的 [[Kind]] 字段值 | 值 | 含义 |
---|---|---|---|
[[Key]] | 全部 | 一个 |
字段、方法或访问器的名称。 |
[[Kind]] | 全部 | 元素的类型。 | |
[[Value]] | 一个 |
字段的值。 | |
[[Get]] | 一个 |
私有访问器的 getter。 | |
[[Set]] | 一个 |
私有访问器的 setter。 |
ClassFieldDefinition 类型是一个
ClassFieldDefinition 类型的值是
字段名 | 值 | 含义 |
---|---|---|
[[Name]] | 一个 |
字段的名称。 |
[[Initializer]] | 一个 ECMAScript |
字段的初始化器(如果有)。 |
私有名称规范类型用于描述一个全局唯一值(即使与其他私有名称在其他方面无法区分,该值也与任何其他私有名称不同),它表示私有类元素(字段、方法或访问器)的键。每个私有名称都有一个关联的不可变
[[Description]],它
ClassStaticBlockDefinition
记录是一个
ClassStaticBlockDefinition 记录具有
字段名 | 值 | 含义 |
---|---|---|
[[BodyFunction]] | 一个 ECMAScript |
在类的静态初始化期间要调用的 |
这些操作不是 ECMAScript 语言的一部分;定义它们仅是为了帮助说明 ECMAScript 语言的语义。其他更专门的
ECMAScript 语言根据需要隐式执行自动类型转换。为了阐明某些构造的语义,定义一组转换
抽象操作 ToPrimitive 接受参数 input(一个
当调用 ToPrimitive 时不带提示,那么它通常表现为提示是
抽象操作 OrdinaryToPrimitive 接受参数 O(一个对象)和
hint(
抽象操作 ToBoolean 接受参数 argument(一个
抽象操作 ToNumeric 接受参数 value(一个
抽象操作 ToNumber 接受参数 argument(一个
抽象操作
所有未在上面明确定义的语法符号都具有数字字面量词法语法中使用的定义(
应注意
0
数字。+
或 -
来表示其符号。
Infinity
和 -Infinity
被识别为 抽象操作 StringToNumber 接受参数 str(一个字符串)并返回一个数字。它在被调用时执行以下步骤:
它在以下产生式上分段定义:
抽象操作 RoundMVResult 接受参数 n(一个
抽象操作 ToIntegerOrInfinity 接受参数 argument(一个
抽象操作 ToInt32 接受参数 argument(一个
根据 ToInt32 的上述定义:
抽象操作 ToUint32 接受参数 argument(一个
抽象操作 ToInt16 接受参数 argument(一个
抽象操作 ToUint16 接受参数 argument(一个
抽象操作 ToInt8 接受参数 argument(一个
抽象操作 ToUint8 接受参数 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。有关 BigInt 对象的描述,请参见 |
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(一个对象)并返回一个
抽象操作 IsRegExp 接受参数 argument(一个
抽象操作 IsStringWellFormedUnicode 接受参数 string(一个字符串)并返回一个布尔值。它将 string 解释为
UTF-16 编码代码点的序列,如
抽象操作 SameType 接受参数 x(一个
抽象操作 SameValue 接受参数 x(一个
此算法与
抽象操作 SameValueZero 接受参数 x(一个
SameValueZero 与
抽象操作 SameValueNonNumber 接受参数 x(一个
抽象操作 IsLessThan 接受参数 x(一个
字符串的比较使用 UTF-16 代码单元值序列的简单字典序。没有尝试使用 Unicode 规范中定义的更复杂的、面向语义的字符或字符串相等性和整理顺序定义。因此,根据
Unicode 标准规范相等但不在相同规范化形式中的字符串值可能测试为不相等。还要注意,对于包含
抽象操作 IsLooselyEqual 接受参数 x(一个==
运算符提供语义。它在被调用时执行以下步骤:
抽象操作 IsStrictlyEqual 接受参数 x(一个===
运算符提供语义。它在被调用时执行以下步骤:
此算法与
抽象操作 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(一个对象)和 P(一个
抽象操作 HasOwnProperty 接受参数 O(一个对象)和 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 的实现必须符合以下要求:
HostEnsureCanAddPrivateElement 的默认实现是返回
此抽象操作仅由作为 Web 浏览器的 ECMAScript
抽象操作 PrivateGet 接受参数 O(一个对象)和 P(一个
抽象操作 PrivateSet 接受参数 O(一个对象)、P(一个
抽象操作 DefineField 接受参数 receiver(一个对象)和 fieldRecord(一个
抽象操作 InitializeInstanceElements 接受参数 O(一个对象)和 constructor(一个 ECMAScript
抽象操作 AddValueToKeyedGroup 接受参数 groups(一个
抽象操作 GroupBy 接受参数 items(一个
抽象操作 SetterThatIgnoresPrototypeProperties 接受参数 thisValue(一个
参见通用迭代接口(
迭代器记录是一个next
方法。
迭代器记录具有
字段名称 | 值 | 含义 |
---|---|---|
[[Iterator]] | 一个对象 | 符合 |
[[NextMethod]] | 一个 |
[[Iterator]] 对象的 next 方法。 |
[[Done]] | 一个布尔值 |
抽象操作 GetIteratorDirect 接受参数 obj(一个对象)并返回一个
抽象操作 GetIteratorFromMethod 接受参数 obj(一个
抽象操作 GetIterator 接受参数 obj(一个
抽象操作 GetIteratorFlattenable 接受参数 obj(一个
抽象操作 IteratorNext 接受参数 iteratorRecord(一个
抽象操作 IteratorComplete 接受参数 iteratorResult(一个对象)并返回一个
抽象操作 IteratorValue 接受参数 iteratorResult(一个对象)并返回一个
抽象操作 IteratorStep 接受参数 iteratorRecord(一个
抽象操作 IteratorStepValue 接受参数 iteratorRecord(一个
抽象操作 IteratorClose 接受参数 iteratorRecord(一个
IfAbruptCloseIterator 是使用
与以下含义相同:
抽象操作 AsyncIteratorClose 接受参数 iteratorRecord(一个
抽象操作 CreateIteratorResultObject 接受参数 value(一个
抽象操作 CreateListIteratorRecord 接受参数 list(一个包含
列表
抽象操作 IteratorToList 接受参数 iteratorRecord(一个
除了本节中定义的操作外,专用的
它在以下产生式上分段定义:
没有必要将 export default
在
export
在
本节由附录
export
本节由附录
export
在函数或脚本的顶层,函数声明被当作 var 声明处理,而不是词法声明。
在函数或脚本的顶层,内部函数声明被当作 var 声明处理。
此部分由附录
本节由附录
本节由附录
抽象操作 IsAnonymousFunctionDefinition 接受参数 expr(一个
本规范中所有未在下面列出的语法产生式备选都隐式具有以下 包含 (Contains) 的默认定义:
依赖于子结构的静态语义规则通常不深入函数定义。
依赖于子结构的静态语义规则通常不深入类体,除了
依赖于子结构的静态语义规则通常不深入 static
初始化块。
super
或
this
之一,返回 super
或
this
之一,返回 super
,返回
这些操作在规范中的多个地方使用。
它在以下产生式上分段定义:
抽象操作 InitializeBoundName 接受参数 name(一个字符串)、value(一个
它在以下产生式上分段定义:
环境记录是一种规范类型,
用于定义
每个环境记录都有一个[[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、类、模块、导入和/或函数声明的ECMAScript程序作用域相关联。声明式环境记录绑定其作用域内包含的声明所定义的标识符集合。
导致步骤
function f() { eval("var x; x = (delete x, 0);"); }
每个对象环境记录
都与一个称为其绑定对象的对象相关联。对象环境记录绑定一组字符串标识符名称,
这些名称直接对应于其绑定对象的属性名称。不是
为with
语句(
对象环境记录具有
通常envRec不会有N的绑定,但如果有,
this
绑定。
super
绑定。
函数环境记录是一个this
绑定。如果函数不是super
,其函数环境记录还包含用于在函数内执行super
方法调用的状态。
函数环境记录具有
字段名称 | 值 | 含义 |
---|---|---|
[[ThisValue]] |
一个 |
这是用于此函数调用的 |
[[ThisBindingStatus]] |
|
如果值是 |
[[FunctionObject]] |
一个ECMAScript |
调用导致创建此 |
[[NewTarget]] |
一个 |
如果此 |
函数环境记录支持
抽象操作BindThisValue接受参数envRec(一个
抽象操作GetSuperBase接受参数envRec(一个super
属性访问基础的对象。值
全局环境记录用于表示被在共同
全局环境记录在逻辑上是单个记录,但它被指定为一个封装
属性可以直接在
全局环境记录具有
this
绑定。
super
绑定。
抽象操作HasLexicalDeclaration接受参数envRec(一个
抽象操作HasRestrictedGlobalProperty接受参数envRec(一个
抽象操作CanDeclareGlobalVar接受参数envRec(一个
抽象操作CanDeclareGlobalFunction接受参数envRec(一个
抽象操作CreateGlobalVarBinding接受参数envRec(一个
抽象操作CreateGlobalFunctionBinding接受参数envRec(一个
模块环境记录是一个
模块环境记录支持
this
绑定。
抽象操作 CreateImportBinding 接收参数 envRec(一个
抽象操作 GetIdentifierReference 接收参数 env(一个
抽象操作 NewDeclarativeEnvironment 接收参数 E(一个
抽象操作 NewObjectEnvironment 接收参数 O(一个对象)、W(一个布尔值)和
E(一个
抽象操作 NewFunctionEnvironment 接收参数 F(一个 ECMAScript
抽象操作 NewGlobalEnvironment 接收参数 G(一个对象)和 thisValue(一个对象),并返回一个
抽象操作 NewModuleEnvironment 接收参数 E(一个
私有环境记录是一种规范机制,用于基于 ECMAScript 代码中
抽象操作 NewPrivateEnvironment 接收参数 outerPrivateEnv(一个
抽象操作 ResolvePrivateIdentifier 接收参数 privateEnv(一个
在求值之前,所有 ECMAScript 代码都必须与一个领域关联。从概念上讲,一个
字段名称 | 值 | 含义 |
---|---|---|
[[AgentSignifier]] |
一个 |
拥有此 |
[[Intrinsics]] |
一个 |
与此 |
[[GlobalObject]] | 一个对象 |
此 |
[[GlobalEnv]] |
一个 |
此 |
[[TemplateMap]] |
具有字段 [[Site]](一个 |
模板对象使用其 一旦
|
[[LoadedModules]] |
|
从此
如
import() 表达式时使用。
|
[[HostDefined]] |
任何值(默认值为 |
为需要将附加信息与 |
抽象操作 InitializeHostDefinedRealm 不接收参数,并返回
this
绑定返回除抽象操作 CreateIntrinsics 接收参数 realmRec(一个
抽象操作 SetDefaultGlobalBindings 接收参数 realmRec(一个
执行上下文是一种规范设备,用于跟踪 ECMAScript
实现对代码的运行时求值。在任何时候,每个
执行上下文栈用于跟踪执行上下文。
执行上下文包含跟踪其关联代码的执行进度所需的任何实现特定状态。每个执行上下文至少具有
ECMAScript 代码执行上下文具有
执行上下文的 LexicalEnvironment 和 VariableEnvironment 组件始终是
表示生成器求值的执行上下文具有
组件 | 目的 |
---|---|
Generator |
此 |
在大多数情况下,只有
执行上下文纯粹是一种规范机制,不需要对应 ECMAScript 实现的任何特定工件。ECMAScript 代码不可能直接访问或观察执行上下文。
抽象操作 GetActiveScriptOrModule 不接收参数,并返回
抽象操作 ResolveBinding 接收参数 name(一个字符串)和可选参数 env(一个
ResolveBinding 的结果始终是一个
抽象操作 GetThisEnvironment 不接收参数,并返回一个this
绑定的
步骤this
绑定的全局环境结束。
抽象操作 ResolveThisBinding 不接收参数,并返回this
的绑定。调用时执行以下步骤:
抽象操作 GetNewTarget 不接收参数,并返回一个对象或
抽象操作 GetGlobalObject 不接收参数,并返回一个对象。它返回当前
作业是一个无参数的
在任何特定时间,scriptOrModule(一个
在任何特定时间,如果所有以下条件都为真,则执行准备求值 ECMAScript 代码:
特定类型的
作业回调记录是用于存储
例如,WHATWG HTML 规范(https://html.spec.whatwg.org/)使用
作业回调记录具有
HostMakeJobCallback 的实现必须符合以下要求:
HostMakeJobCallback 的默认实现在调用时执行以下步骤:
非 Web 浏览器的 ECMAScript
这在回调被传递给负责其最终调度和运行的函数时调用。例如,promise.then(thenAction)
在调用
Promise.prototype.then
时对 thenAction
调用
MakeJobCallback,而不是在调度反应
HostCallJobCallback 的实现必须符合以下要求:
HostCallJobCallback 的默认实现在调用时执行以下步骤:
非 Web 浏览器的 ECMAScript
HostEnqueueGenericJob 的实现必须符合
HostEnqueuePromiseJob 的实现必须符合
HostEnqueueTimeoutJob 的实现必须符合
代理包含一组 ECMAScript
例如,一些 Web 浏览器在浏览器窗口的多个不相关选项卡之间共享单个
当
代理标识符是用于标识
字段名称 | 值 | 含义 |
---|---|---|
[[LittleEndian]] | 布尔值 | 当算法 |
[[CanBlock]] | 布尔值 | 确定 |
[[Signifier]] | 一个 |
在其 |
[[IsLockFree1]] | 布尔值 | 如果对单字节值的原子操作是无锁的,则为 |
[[IsLockFree2]] | 布尔值 | 如果对双字节值的原子操作是无锁的,则为 |
[[IsLockFree8]] | 布尔值 | 如果对八字节值的原子操作是无锁的,则为 |
[[CandidateExecution]] | 一个 |
参见 |
[[KeptAlive]] | 对象或符号的 |
初始为一个新的空 |
[[ModuleAsyncEvaluationCount]] | 一个 |
初始为 0,用于为异步或具有异步依赖的模块的[[AsyncEvaluationOrder]]字段分配唯一的递增值。 |
一旦[[Signifier]]、[[IsLockFree1]]和[[IsLockFree2]]的值被
[[IsLockFree1]]和[[IsLockFree2]]的值不一定由硬件决定,也可能反映可能随时间和 ECMAScript 实现而变化的实现选择。
没有[[IsLockFree4]]字段:4 字节原子操作总是无锁的。
实际上,如果原子操作是用任何类型的锁实现的,则该操作不是无锁的。无锁并不意味着无等待:对于完成无锁原子操作可能需要多少个机器步骤没有上限。
大小为n的原子访问是无锁的,并不意味着大小为n的非原子访问的(感知的)原子性,具体来说,非原子访问仍然可能作为几个单独的内存访问序列来执行。详见
抽象操作 AgentSignifier 不接收参数,并返回一个
抽象操作 AgentCanSuspend 不接收参数,并返回一个布尔值。调用时执行以下步骤:
在某些环境中,给定
抽象操作 IncrementModuleAsyncEvaluationCount 不接收参数,并返回一个
此值仅用于跟踪挂起模块之间的相对求值顺序。当没有挂起模块时,实现可以不可观察地将[[ModuleAsyncEvaluationCount]]重置为 0。
代理集群是可以通过操作共享内存进行通信的
每个
集群内的所有
如果代理集群内不同的
集群内的所有
集群内的所有
嵌入可以在
嵌入可以在
以下每个规范值以及从它们可传递到达的值都恰好属于一个代理集群。
在集群中任何
代理集群是一种规范机制,不需要对应 ECMAScript 实现的任何特定工件。
当
实现必须确保:
本规范不保证任何对象或符号会被垃圾回收。不
WeakRef.prototype.deref
时,引用对象(如果未返回这两个动作(
一些 ECMAScript 实现包括在后台运行的垃圾收集器实现,包括当 ECMAScript 处于空闲状态时。让
对于某个对象和/或符号集合S,关于S的假设 WeakRef
无关执行是指这样的执行:其引用对象是S元素的
在求值期间的任何时点,如果满足以下任一条件,则对象和/或符号集合S被认为是活跃的:
对象或符号在字段、内部槽或属性中的存在并不意味着该值是活跃的。例如,如果所讨论的值从未传回程序,那么它就无法被观察到。
WeakMap 中的键、WeakSet 的成员以及
上述定义意味着,如果 WeakMap 中的键不是活跃的,那么其对应的值也不一定是活跃的。
在任何时候,如果对象和/或符号集合S不是
与活跃性定义一起,本条款规定了实现可以应用于
可以在不观察对象身份的情况下访问对象。诸如死变量消除和对身份未被观察的非逃逸对象属性的标量替换等优化是允许的。因此,这些优化被允许可观察地清空指向此类对象的
另一方面,如果对象的身份是可观察的,并且该对象在
因为调用
设cleanupJob为捕获finalizationRegistry的无参数新
HostEnqueueFinalizationRegistryCleanupJob
的实现调度cleanupJob在将来某个时间执行(如果可能)。它还必须符合
抽象操作 ClearKeptObjects 不接收参数,并返回
抽象操作 AddToKeptObjects 接收参数value(一个对象或符号),并返回
抽象操作 CleanupFinalizationRegistry 接收参数finalizationRegistry(一个
抽象操作 CanBeHeldWeakly 接收参数v(一个
没有
所有
每个
在以下算法描述中,假设O是一个
每个
抽象操作OrdinaryGetPrototypeOf接受参数O(一个Object),返回一个Object或
抽象操作OrdinarySetPrototypeOf接受参数O(一个Object)和V(一个Object或
抽象操作OrdinaryIsExtensible接受参数O(一个Object),返回一个Boolean。调用时执行以下步骤:
抽象操作OrdinaryPreventExtensions接受参数O(一个Object),返回
抽象操作OrdinaryGetOwnProperty接受参数O(一个Object)和P(一个
抽象操作OrdinaryDefineOwnProperty接受参数O(一个Object)、P(一个
抽象操作IsCompatiblePropertyDescriptor接受参数Extensible(一个Boolean)、Desc(一个
抽象操作ValidateAndApplyPropertyDescriptor接受参数O(一个Object或
抽象操作OrdinaryHasProperty接受参数O(一个Object)和P(一个
抽象操作OrdinaryGet接受参数O(一个Object)、P(一个
抽象操作OrdinarySet接受参数O(一个Object)、P(一个
抽象操作OrdinarySetWithOwnDescriptor接受参数O(一个Object)、P(一个
抽象操作OrdinaryDelete接受参数O(一个Object)和P(一个
抽象操作OrdinaryOwnPropertyKeys接受参数O(一个Object),返回一个
抽象操作OrdinaryObjectCreate接受参数proto(一个Object或
虽然OrdinaryObjectCreate除了调用
抽象操作OrdinaryCreateFromConstructor接受参数constructor(一个
抽象操作GetPrototypeFromConstructor接受参数constructor(一个
抽象操作RequireInternalSlot接受参数O(一个
ECMAScript
除了[[Extensible]]和[[Prototype]]之外,ECMAScript
内部插槽 | 类型 | 描述 |
---|---|---|
[[Environment]] |
一个 |
函数封闭的 |
[[PrivateEnvironment]] |
一个 |
函数封闭的 |
[[FormalParameters]] |
一个 |
定义函数形式参数列表的源文本的根解析节点。 |
[[ECMAScriptCode]] |
一个 |
定义函数体的源文本的根解析节点。 |
[[ConstructorKind]] |
|
函数是否为派生类 |
[[Realm]] |
一个 |
创建函数的 |
[[ScriptOrModule]] |
一个 |
创建函数的脚本或模块。 |
[[ThisMode]] |
|
定义如何在函数的形式参数和代码体中解释this 引用。this 引用词法封闭函数的 |
[[Strict]] | 一个Boolean |
如果这是 |
[[HomeObject]] | 一个Object |
如果函数使用super ,这是其[[GetPrototypeOf]]提供super 属性查找开始的对象的对象。
|
[[SourceText]] | Unicode代码点序列 |
定义函数的 |
[[Fields]] |
|
如果函数是类,这是表示类的非静态字段和相应初始化器的 |
[[PrivateMethods]] |
|
如果函数是类,这是表示类的非静态私有方法和访问器的列表。 |
[[ClassFieldInitializerName]] |
一个字符串、一个Symbol、一个 |
如果函数是作为类字段的初始化器创建的,则为字段的 |
[[IsClassConstructor]] | 一个Boolean |
指示函数是否为类 |
所有ECMAScript
ECMAScript
抽象操作PrepareForOrdinaryCall接受参数F(一个ECMAScript
抽象操作OrdinaryCallBindThis接受参数F(一个ECMAScript
尽管字段初始化器构成函数边界,但调用
抽象操作OrdinaryCallEvaluateBody接受参数F(一个ECMAScript
ECMAScript
抽象操作OrdinaryFunctionCreate接受参数functionPrototype(一个Object)、sourceText(Unicode代码点序列)、ParameterList(一个
抽象操作AddRestrictedFunctionProperties接受参数F(一个
此函数是%ThrowTypeError%内在对象。
调用时执行以下步骤:
此函数的[[Extensible]]内部插槽的值为
此函数的
此函数的
抽象操作MakeConstructor接受参数F(一个ECMAScript
抽象操作MakeClassConstructor接受参数F(一个ECMAScript
抽象操作MakeMethod接受参数F(一个ECMAScript
抽象操作DefineMethodProperty接受参数homeObject(一个Object)、key(一个
抽象操作SetFunctionName接受参数F(一个
抽象操作SetFunctionLength接受参数F(一个
抽象操作FunctionDeclarationInstantiation接受参数func(一个ECMAScript
调用时执行以下步骤:
内置
除了每个
内置
内置
内置
实现可以提供本规范中未定义的其他内置
内置
内置
抽象操作BuiltinCallOrConstruct接受参数F(内置
当从
抽象操作CreateBuiltinFunction接受参数behaviour(
本规范中定义的每个内置函数都是通过调用CreateBuiltinFunction抽象操作创建的。
本规范定义了几种内置
如果对象的[[Call]]和(如果适用)[[Construct]]内部方法使用以下实现,其他基本内部方法使用
内部插槽 | 类型 | 描述 |
---|---|---|
[[BoundTargetFunction]] | 可调用对象 |
被包装的 |
[[BoundThis]] |
|
调用包装函数时总是作为 |
[[BoundArguments]] |
|
一个值列表,其元素用作对包装函数的任何调用的前几个参数。 |
抽象操作BoundFunctionCreate接受参数targetFunction(
数组是一个
如果对象的[[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对象定义一个名为
抽象操作CreateUnmappedArgumentsObject接受参数argumentsList(
抽象操作CreateMappedArgumentsObject接受参数func(对象)、formals(
抽象操作MakeArgGetter接受参数name(字符串)和env(
抽象操作MakeArgSetter接受参数name(字符串)和env(
因为对于任何数字 n,
如果一个对象的 [[PreventExtensions]]、[[GetOwnProperty]]、[[HasProperty]]、[[DefineOwnProperty]]、[[Get]]、[[Set]]、[[Delete]] 和 [[OwnPropertyKeys]] 内部方法使用本节中的定义,并且其他基本内部方法使用
TypedArray
带缓冲区见证记录 是一个用于封装
TypedArray 带缓冲区见证记录具有
字段名称 | 值 | 含义 |
---|---|---|
[[Object]] |
一个 |
其缓冲区字节长度被加载的 |
[[CachedBufferByteLength]] |
一个非负 |
创建 |
抽象操作 MakeTypedArrayWithBufferWitnessRecord 接受参数 obj(一个
抽象操作 TypedArrayCreate 接受参数 prototype(一个对象)并返回一个
抽象操作 TypedArrayByteLength 接受参数 taRecord(一个
抽象操作 TypedArrayLength 接受参数 taRecord(一个
抽象操作 IsTypedArrayOutOfBounds 接受参数 taRecord(一个
抽象操作 IsTypedArrayFixedLength 接受参数 O(一个
抽象操作 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]] 强制执行以下不变量:
代理对象的 [[SetPrototypeOf]] 强制执行以下不变量:
代理对象的 [[IsExtensible]] 强制执行以下不变量:
代理对象的 [[PreventExtensions]] 强制执行以下不变量:
代理对象的 [[GetOwnProperty]] 强制执行以下不变量:
代理对象的 [[HasProperty]] 强制执行以下不变量:
代理对象的 [[Delete]] 强制执行以下不变量:
代理对象的 [[Construct]] 强制执行以下不变量:
抽象操作 ValidateNonRevokedProxy 接受参数 proxy(一个
抽象操作 ProxyCreate 接受参数 target(一个
ECMAScript 源文本是一个 Unicode 码点序列。所有从 U+0000 到 U+10FFFF 的 Unicode
码点值,包括代理码点,都可以出现在 ECMAScript 语法允许的 ECMAScript 源文本中。用于存储和交换 ECMAScript
源文本的实际编码与本规范无关。无论外部源文本编码如何,符合要求的 ECMAScript 实现都会将源文本处理为等效的
组合字符序列的组成部分被视为单独的 Unicode 码点,即使用户可能认为整个序列是一个字符。
在字符串字面量、正则表达式字面量、模板字面量和标识符中,任何 Unicode 码点也可以使用明确表示码点数值的 Unicode 转义序列来表示。在注释中,这样的转义序列作为注释的一部分被有效忽略。
ECMAScript 在 Unicode 转义序列的行为上与 Java 编程语言不同。在 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
代码是该 函数代码 是被解析以提供 ECMAScript
此外,如果上述源文本被解析为:
那么,该声明或表达式的
将
指令序言是作为
Use Strict 指令
是 "use strict"
或 'use strict'
。一个
一个
ECMAScript 句法单元可以使用非限制性或严格模式语法和语义(
eval
的调用是包含在严格模式代码中的 不是严格模式代码的 ECMAScript 代码称为 非严格代码。
抽象操作 IsStrict 接受参数 node(一个
ECMAScript 实现可以支持对函数
ECMAScript
在某些情况下,词法输入元素的识别对消费输入元素的句法语法上下文很敏感。这需要词法语法具有多个
使用多个词法目标确保不存在会影响自动分号插入的词法歧义。例如,不存在既允许前导除法或除法赋值又允许前导
a = b
/hi/g.exec(c).map(d);
其中
a = b / hi / g.exec(c).map(d);
Unicode 格式控制字符(即 Unicode 字符数据库中类别为 "Cf" 的字符,如从左到右标记或从右到左标记)是在缺乏用于此目的的高级协议(如标记语言)的情况下用于控制文本范围格式的控制代码。
允许格式控制字符出现在源文本中是有用的,以便于编辑和显示。所有格式控制字符都可以在注释中以及字符串字面量、模板字面量和正则表达式字面量中使用。
U+FEFF(零宽度无间断空格)是一个格式控制字符,主要用于文本的开头,以将其标记为 Unicode 并允许检测文本的编码和字节顺序。用于此目的的 <ZWNBSP>
字符有时也可能出现在文本开头之后,例如作为连接文件的结果。在
空白码点用于改善源文本的可读性并将标记(不可分割的词法单元)彼此分离,但在其他方面是无关紧要的。空白码点可以出现在任意两个标记之间以及输入的开始或结束处。空白码点可以出现在
ECMAScript 空白码点列在
码点 | 名称 | 缩写 |
---|---|---|
U+0009
|
字符制表符 | <TAB> |
U+000B
|
行制表符 | <VT> |
U+000C
|
换页符 (FF) | <FF> |
U+FEFF
|
零宽度无间断空格 | <ZWNBSP> |
通用类别 "Space_Separator" 中的任何码点 | <USP> |
U+0020(空格)和 U+00A0(无间断空格)码点是 <USP> 的一部分。
除了
与空白码点一样,行终止符码点用于改善源文本的可读性并将标记(不可分割的词法单元)彼此分离。但是,与空白码点不同,行终止符对句法语法的行为有一定影响。通常,行终止符可以出现在任意两个标记之间,但在句法语法禁止的少数地方则不行。行终止符还会影响自动分号插入的过程(
行终止符可以出现在
行终止符被包含在正则表达式中 \s
类匹配的空白码点集合中。
ECMAScript 行终止符码点列在
码点 | Unicode 名称 | 缩写 |
---|---|---|
U+000A
|
换行符 (LF) | <LF> |
U+000D
|
回车符 (CR) | <CR> |
U+2028
|
行分隔符 | <LS> |
U+2029
|
段分隔符 | <PS> |
只有
注释可以是单行或多行的。多行注释不能嵌套。
由于单行注释可以包含除 //
标记到行尾的所有码点组成。但是,行尾的
注释的行为类似空白符并被丢弃,除非
本节中的许多产生式在
Hashbang 注释对位置敏感,与其他类型的注释一样,从句法语法的输入元素流中被丢弃。
本标准规定了特定的码点添加:U+0024(美元符号)和 U+005F(下划线)允许出现在
非终结符
非终结符 _
。
具有 Unicode 属性 "ID_Start" 和 "ID_Continue" 的码点集合分别包括具有 Unicode 属性 "Other_ID_Start" 和 "Other_ID_Continue" 的码点。
Unicode 转义序列在 \
不贡献任何码点。\
根据 Unicode 标准规范等价的两个
关键字是匹配 固定宽度
字体直接出现。ECMAScript 的关键字包括
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
。
条件关键字或 上下文关键字这个术语有时用来指属于后三个类别的关键字,因此可以在某些上下文中用作标识符,在其他上下文中用作关键字。
根据 \
\
els\u{65}
来声明名为 "else" 的变量。
enum
目前在本规范中未用作关键字。它是一个未来保留字,留作未来语言扩展中用作关键字。
类似地,implements
、interface
、package
、private
、protected
和 public
在
紧跟在
例如:3in
是一个错误,而不是两个输入元素 3
和 in
。
数值字面量表示
字符串字面量是用单引号或双引号括起来的 0 个或多个 Unicode 码点。Unicode
码点也可以用转义序列表示。除了结束引号码点、U+005C(反斜杠)、U+000D(回车符)和
U+000A(换行符)之外,所有码点都可以直接出现在字符串字面量中。任何码点都可以以转义序列的形式出现。字符串字面量求值为 ECMAScript String 值。生成这些
String 值时,Unicode 码点按照
非终结符
<LF> 和 <CR> 不能出现在字符串字面量中,除非作为 \n
或 \u000A
。
字符串字面量可能出现在将封闭代码置于
function invalid() { "\7"; "use strict"; }
字符串字面量表示
转义序列 | 码元值 | Unicode 字符名称 | 符号 |
---|---|---|---|
\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 | \ |
下面的产生式描述了正则表达式字面量的语法,并被输入元素扫描器用来找到正则表达式字面量的结尾。包含
实现可以扩展在
正则表达式字面量不能为空;码元序列 //
不是表示空正则表达式字面量,而是开始单行注释。要指定空正则表达式,请使用:/(?:)/
。
大多数 ECMAScript 语句和声明必须以分号结尾。这些分号可以始终显式地出现在源文本中。但是,为了方便起见,在某些情况下可以从源文本中省略这些分号。这些情况通过说分号在这些情况下被自动插入到源代码标记流中来描述。
在以下规则中,"标记"是指使用当前词法
分号插入有三个基本规则:
当从左到右解析源文本时,遇到语法的任何产生式都不允许的标记(称为违规标记),如果满足以下一个或多个条件,则在违规标记之前自动插入分号:
}
。)
,插入的分号将被解析为 do-while 语句的终止分号(但是,前述规则有一个额外的覆盖条件:如果分号随后会被解析为空语句,或者该分号会成为 for
语句头部中的两个分号之一(参见
以下是语法中唯一的受限产生式:
这些受限产生式的实际效果如下:
++
或 --
标记时,解析器会将其视为后缀运算符,如果在前一个标记和 ++
或
--
标记之间至少有一个 ++
或
--
标记之前自动插入分号。
continue
、break
、return
、throw
或 yield
标记,并且在下一个标记之前遇到 continue
、break
、return
、throw
或
yield
标记之后自动插入分号。
=>
标记之前有 async
标记后面在 function
或 (
标记之前有 async
标记不被视为与后续标记相同表达式或类元素的一部分。async
标记后面在 *
标记之前有 给 ECMAScript 程序员的实际建议是:
++
或 --
运算符应该与其操作数在同一行。return
或 throw
语句中的 yield
表达式中的
return
、throw
或 yield
标记在同一行开始。
break
或 continue
语句中的 break
或 continue
标记在同一行。
=>
应该在同一行。async
标记应该与紧接着的标记在同一行。源代码
{ 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
++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 包含包括"[no
本节的其余部分描述了这个版本的 ECMAScript 中使用"[no
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(一个
模板对象的创建不能导致
本规范的未来版本可能定义模板对象的附加不可枚举属性。
应用于 String.prototype.concat
而不是 +
运算符。
应用于 String.prototype.concat
而不是 +
运算符。
应用于 String.prototype.concat
而不是 +
运算符。
此算法不对 delete
和 typeof
等运算符可以应用于带括号的表达式。
当处理产生式的实例时
使用以下语法细化对
此产生式的存在是为了防止自动分号插入规则(
a?.b
`c`
这样它就不会被解释为两个有效的语句。目的是与没有可选链的类似代码保持一致:
a.b
`c`
这是一个有效的语句,其中不应用自动分号插入。
属性通过名称进行访问,可以使用点记法:
或括号记法:
点记法通过以下语法转换解释:
在行为上等同于
同样地
在行为上等同于
其中 <identifier-name-string> 是
抽象操作 EvaluatePropertyAccessWithExpressionKey 接受参数
baseValue(一个
a[b] = c
的情况下,它将直到 c
求值之后才执行。
抽象操作 EvaluatePropertyAccessWithIdentifierKey 接受参数
baseValue(一个
new
运算符抽象操作 EvaluateNew 接受参数 constructExpr(一个
执行步骤
抽象操作 EvaluateCall 接受参数 func(一个
super
关键字super[b] = c
的情况下,它将直到
c
求值之后才执行。
抽象操作 GetSuperConstructor 不接受参数,返回一个
抽象操作 MakeSuperPropertyReference 接受参数 actualThis(一个
参数列表的求值产生一个值的
?.
开始。抽象操作 EvaluateImportCall 接受参数 specifierExpression(一个
抽象操作 ContinueDynamicImport 接受参数 promiseCapability(一个 import()
标记模板是一个函数调用,其中调用的参数来源于
import.meta
返回的对象提供
HostGetImportMetaProperties 的默认实现是返回新的空
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
的求值顺序。
相等运算符并不总是传递的。例如,可能有两个不同的 String 对象,每个代表相同的 String 值;每个 String 对象都会被 ==
运算符认为等于 String 值,但两个 String 对象彼此不相等。例如:
new String("a") == "a"
和 "a" == new String("a")
都是
new String("a") == new String("a")
是 字符串的比较使用简单的代码单元值序列相等性测试。没有尝试使用 Unicode 规范中定义的更复杂的、面向语义的字符或字符串相等性和排序定义。因此,根据 Unicode 标准规范相等的字符串值可能测试为不相等。实际上,此算法假设两个字符串都已经是规范化形式。
&&
或 ||
运算符产生的值不一定是布尔类型。产生的值总是两个操作数表达式之一的值。
? :
)ECMAScript 中
assignmentOpText | opText |
---|---|
**= |
** |
*= |
* |
/= |
/ |
%= |
% |
+= |
+ |
-= |
- |
<<= |
<< |
>>= |
>> |
>>>= |
>>> |
&= |
& |
^= |
^ |
|= |
| |
抽象操作 ApplyStringOrNumericBinaryOperator 接受参数 lVal(一个**
、*
、/
、%
、
+
、-
、<<
、>>
、
>>>
、&
、^
或 |
)和
rVal(一个
+
,则**
,返回 ? /
,返回 ? %
,返回 ? >>>
,返回 ? opText | operation |
---|---|
* |
|
+ |
|
- |
|
<< |
|
>> |
|
& |
|
^ |
|
| |
|
opText | operation |
---|---|
** |
|
* |
|
/ |
|
% |
|
+ |
|
- |
|
<< |
|
>> |
|
>>> |
|
& |
|
^ |
|
| |
|
在步骤
步骤
抽象操作 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(一个
在
do
-while
语句只有在实现
while
语句只有在实现
for
语句只有在实现
抽象操作 ForBodyEvaluation 接受参数 test(一个
抽象操作 CreatePerIterationEnvironment 接受参数
perIterationBindings(一个