ECMA 大会批准发布 ECMAScript 2022:添加了什么新功能?

ECMA 大会批准发布 ECMAScript 2022:添加了什么新功能?

2022 年 6 月 22 日,ECMA 批准 ECMAScript 2022 语言规范 the 123nd Ecma General Assembly approved the ECMAScript 2022 language specification,意味着 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);

了解更多 Top-level await

error.cause

现在 Error 和它的子类可以标记造成的错误原因:

try {
  // 一些代码
} catch (otherError) {
  throw new Error('Something went wrong', { cause: otherError });
}

错误 err 的错误堆栈可以通过 err.cause 访问。

error.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)。

关于 Object.hasOwn() 的更多信息

一些问题

JavaScript 与 ECMAScript 之间有什么不同?

谁设计 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 版本的新特性:

本文作者 Axel Rauschmayer,转载请注明来源链接:

原文链接:https://2ality.com/2022/06/ecmascript-2022.html

本文链接:https://tie.pub/2022/06/ecmascript-2022/