ECMA 大会批准发布 ECMAScript 2022:添加了什么新功能?
2022 年 6 月 22 日,ECMA 批准 ECMAScript 2022 语言规范 Ecma International approves new standards,意味着 ES2022 现在是正式的标准。
ECMAScript 2022 的编写者
参与这次发布的编写者是:
ECMAScript 2022 支持的新特性
类的新成员
class MyClass {
instancePublicField = 1
static staticPublicField = 2
#instancePrivateField = 3
static #staticPrivateField = 4
#nonStaticPrivateMethod() {}
get #nonStaticPrivateAccessor() {}
set #nonStaticPrivateAccessor(value) {}
static #staticPrivateMethod() {}
static get #staticPrivateAccessor() {}
static set #staticPrivateAccessor(value) {}
static {
// Static initialization block
}
}
通过 in
操作符检查私有成员
私有成员检查也被称作“私有成员变量的类型构成检查(ergonomic brand checks for private fields)”。下面的表达式展示一次检查,该表达式确定 obj
是否拥有一个私有成员 #privateSlot
:
#privateSlot in obj;
下面是实际使用范例:
class ClassWithPrivateSlot {
#privateSlot = true
static hasPrivateSlot(obj) {
return #privateSlot in obj
}
}
const obj1 = new ClassWithPrivateSlot()
assert.equal(ClassWithPrivateSlot.hasPrivateSlot(obj1), true)
const obj2 = {}
assert.equal(ClassWithPrivateSlot.hasPrivateSlot(obj2), false)
请注意我们只能够在私有成员声明的作用域内引用它。
模块中的顶层 await
(Top-level await)
现在我们可以在 ES 模块的顶层直接使用 await
语法,并不仅仅限制在 async
函数或方法上:
// my-module.mjs
const response = await fetch('https://example.com')
const text = await response.text()
console.log(text)
error.cause
现在 Error
和它的子类可以标记造成的错误原因:
try {
// 一些代码
} catch (otherError) {
throw new Error('Something went wrong', { cause: otherError })
}
错误 err
的错误堆栈可以通过 err.cause
访问。
用于可索引的值获取的方法 .at()
方法 .at()
让我们通过索引读取变量的值(类似于中括号操作符 []
),并且支持负值索引访问,这点与 []
操作符不同:
['a', 'b', 'c'].at(0); // -> 'a'
['a', 'b', 'c'].at(-1) // -> 'c'
下面这些可索引的类型拥有方法 .at()
:
String
Array
- 全部类数组的类:
Unit8Array
等。
正则表达式的索引匹配
如果我们在正则表达式中添加标记 /d
,使用它就会产生匹配对象,记录着每个组捕获的开始和结束索引(行 A 和 B)。
const matchObj = /(a+)(b+)/d.exec('aaaabb')
assert.equal(matchObj[1], 'aaaa')
assert.deepEqual(
matchObj.indices[1],
[0, 4] // (A)
)
assert.equal(matchObj[2], 'bb')
assert.deepEqual(
matchObj.indices[2],
[4, 6] // (B)
)
Object.hasOwn(obj, propKey)
Object.hasOwn(obj, propKey)
是一种安全的检查对象 obj
是否拥有非继承的成员 propKey
:
const proto = {
protoProp: 'protoProp',
}
const obj = {
__proto__: proto,
objProp: 'objProp',
}
assert.equal('protoProp' in obj, true) // (A)
assert.equal(Object.hasOwn(obj, 'protoProp'), false) // (B)
assert.equal(Object.hasOwn(proto, 'protoProp'), true) // (C)
注意操作符 in
检查了继承属性(行 A),但是 Object.hasOwn()
仅仅检查了对象的自有属性(行 B 和 C)。
一些问题
JavaScript 与 ECMAScript 之间有什么不同?
- 通俗来说:
- JavaScript 是各种平台(诸如浏览器,Node.js,Deno 等)实现的编程语言。
- ECMAScript 是语言标准,由 the ECMAScript language specification 描述声明。
- 长篇讨论请看章节 “Standardizing JavaScript” in “JavaScript for impatient programmers”。
谁设计 ECMAScript?TC39 - Ecma Technical Committee 39
ECMAScript 是由标准组织 Ecma International 的技术委员会 39(Technical Committee 39 - TC39)设计的。
严格来说,其成员是公司:Adobe、Apple、Facebook、谷歌、微软、Mozilla、Opera、Twitter 和其他公司。也就是说,那些通常是竞争对手的公司正在共同研究 JavaScript。
每两个月,TC39 都会召开会议,由成员指定的代表和邀请的专家参加。这些会议的记录在 GitHub 存储库中公开。
在会议之外,TC39 还与 JavaScript 社区的各个成员和团体进行合作。
功能是如何添加进 ECMAScript?
新的 ECMAScript 功能必须向 TC39 提出。它们经历了几个阶段。
-
从第 0 阶段(使 TC39 能够对提案发表意见)
-
到第 4 阶段(提议的特性已经准备好加入 ECMAScript)。
-
一旦某项功能达到第 4 阶段,它就被安排加入 ECMAScript 中。ECMAScript 版本的功能集通常在每年的 3 月被冻结。在该期限之后达到第四阶段的功能将被添加到明年的 ECMAScript 版本中。
ECMAScript 版本如何重要?
自从 TC39 程序建立以来,ECMAScript 版本的重要性已经大大降低。现在真正重要的是一个提议的功能处于什么阶段。一旦达到第四阶段,就可以安全使用了。但即使如此,你仍然要检查你所针对的引擎是否支持它。
“我最喜欢的功能建议”进展如何?
如果你想知道各种提议的功能处于什么阶段,请看 TC39 提案仓库。
我在哪里可以查到某个 ECMAScript 版本中增加了哪些功能?
我们有几个地方可以查到每个 ECMAScript 版本的新特性:
- 在“JavaScript for impatient programmers”中,有一节列出了每个 ECMAScript 版本中的新功能。它还提供了解释的链接。
- TC39 资源库中有一个已完成提案的表格,其中说明了它们在哪个 ECMAScript 版本中被引入(或将被引入)。
- ECMAScript 语言规范的“介绍”部分列出了每个 ECMAScript 版本的新特性。
- ECMA-262 资源库有一个包含发布的版本页面。
本文由 吳文俊 翻译,原文地址 Ecma International approves ECMAScript 2022: What’s new?