ES2022 新特性概览:Top-Level Await, .at(), and more

4 min

引言

随着 TC39 委员会的年度发布流程,JavaScript 语言每年都在不断进化。ECMAScript 2022 (ES2022) 带来了一系列旨在提升开发者体验和代码可读性的新功能。让我们一起来看看其中最亮眼的几个特性。

1. Top-Level await

这是 ES2022 中最受期待的特性之一。在此之前,await 关键字只能在 async 函数内部使用。这在模块的顶层作用域中处理异步操作时非常不便,我们通常需要借助 IIFE (立即调用函数表达式) 来包裹异步代码。

之前 👎:

// data.js
import { fetchData } from './api.js';

let data;
(async () => {
  data = await fetchData();
  // ... 只能在这里使用 data
})();

export { data }; // 导出时 data 还是 undefined

现在 (ES2022) 👍:

// data.js
import { fetchData } from './api.js';

const data = await fetchData();

export { data }; // 模块会等待 await 完成后再被其他模块评估

Top-level await 极大地简化了模块的动态加载、依赖初始化等场景,让异步代码写起来更符合直觉。

2. .at() 数组/字符串索引方法

在 JavaScript 中,获取数组的最后一个元素通常需要写 arr[arr.length - 1],这既冗长又容易出错。ES2022 引入了 .at() 方法,统一了正向和反向索引的体验。

.at() 方法接收一个整数,如果是正数,则返回对应索引的元素;如果是负数,则从末尾开始倒数。

之前 👎:

const arr = [1, 2, 3, 4, 5];
const lastElement = arr[arr.length - 1]; // 5
const secondToLast = arr[arr.length - 2]; // 4

现在 (ES2022) 👍:

const arr = [1, 2, 3, 4, 5];
const lastElement = arr.at(-1); // 5
const secondToLast = arr.at(-2); // 4

// 同样适用于字符串
const str = 'hello';
console.log(str.at(-1)); // 'o'

3. Object.hasOwn(obj, prop)

检查一个对象是否拥有某个自有属性(而不是继承来的属性),我们通常使用 Object.prototype.hasOwnProperty.call(obj, prop)。这种写法非常繁琐,且在某些情况下(如 Object.create(null) 创建的对象)会出错。

Object.hasOwn() 提供了一个更短、更可靠的静态方法。

之前 👎:

const obj = { a: 1 };
console.log(Object.prototype.hasOwnProperty.call(obj, 'a')); // true
console.log(Object.prototype.hasOwnProperty.call(obj, 'toString')); // false

现在 (ES2022) 👍:

const obj = { a: 1 };
console.log(Object.hasOwn(obj, 'a')); // true
console.log(Object.hasOwn(obj, 'toString')); // false

4. 其他值得关注的特性

  • Error Cause: Error 构造函数现在可以接收第二个参数,用于指定错误的“原因”,方便构建更清晰的错误链。
    try {
      // ...
    } catch (err) {
      throw new Error('New error message', { cause: err });
    }
  • RegExp Match Indices (/d flag): 当使用 /d 标志时,正则表达式的匹配结果会额外提供每个捕获组的起始和结束索引。

结论

ES2022 的新特性虽然没有带来颠覆性的变革,但它们在细节上打磨了 JavaScript,解决了许多开发者长期以来的痛点,让代码变得更简洁、更健壮。