跳至主要內容

ES11新增内容

黄曦大约 3 分钟JavaScriptES11JavaScript

ES11(ECMAScript 2020)新特性

1. String.prototype.matchAll() 方法

允许在字符串上使用正则表达式的全局匹配,并返回一个迭代器,用于访问所有匹配结果。

示例:

const regex = /(\d+)/g;
const str = '2020年和2021年';
const matches = [...str.matchAll(regex)];
// matches: [['2020'], ['2021']]

2. 可选链操作符(Optional Chaining Operator)

允许在访问可能为 nullundefined 的属性或方法时避免产生错误,直接返回 undefined

示例:

const person = {
  name: 'Alice',
  address: {
    city: 'Wonderland'
  }
};

const city = person?.address?.city;
// city: 'Wonderland'

// 在数组上的使用
const arr = [1, 5, 6, 8];
console.log(arr?.[1]); // 5

3. Nullish 合并操作符(Nullish Coalescing Operator)

允许在对可能为 nullundefined 的变量进行赋值时,仅在变量的值为 nullundefined 时使用默认值。

示例:

const defaultValue = 'Default Value';
const userInput = null;
const value = userInput ?? defaultValue;
// value: 'Default Value'

console.log(false ?? true); // false
// 只要不是 null 和 undefined,都是左侧的值

4. Promise.allSettled() 方法

允许在所有的 Promise 完成或拒绝后,返回一个包含每个 Promise 结果状态的数组,不会抛出异常。

示例:

const delay = (value, ms, isReject) => new Promise((resolve, reject) => setTimeout(() => isReject ? reject(new Error(value)) : resolve(value), ms));
const promises = [
  delay('a', 3000),
  delay('b', 2000, true),
];
Promise.allSettled(promises)
  .then(res => console.log(res))

// Output:
[
  { status: 'fulfilled', value: 'a' },
  {
    status: 'rejected',
    reason: Error: b
        at Timeout._onTimeout (/index.js:1:108)
        at listOnTimeout (node:internal/timers:564:17)
        at process.processTimers (node:internal/timers:507:7)
  }
]

5. globalThis 对象

提供了一个标准的方式来获取全局对象,不依赖于当前执行环境。

示例:

console.log(globalThis === window); // 在浏览器环境中输出: true
console.log(global === globalThis); // 在 Node.js 环境中输出: true

6. for-in 机制

ECMA-262 规范没有规定 for (a in b) ... 的遍历顺序,部分原因是所有引擎都有自己特殊的实现。现在很难就 for-in 完整顺序规范达成一致,但规范了一些供参考的实现行为。因此,在不同的引擎下,for-in 循环出来的内容顺序可能是不一样的。

示例:

const obj = { a: 1, b: 2, c: 3 };
for (const key in obj) {
  console.log(key);
}
// 输出顺序可能因环境而异

7. BigInt 类型扩展

允许使用 BigInt 进行构造函数调用和运算。注意不可以和 number 类型混用。其他使用方式基本相同。

示例:

9007199254740995n // BigInt 表示方式一
BigInt('9007199254740995') // BigInt 表示方式二
// BigInt 运算
const bigIntValue = BigInt(1234567890123456789012345678901234567890);
const added = bigIntValue + BigInt(10);

8. 模块新特性

动态导入

当你需要该模块时才会进行加载,返回的是一个 Promise 对象。只有在 ES Modules 模块规范下才支持。

示例:

// index-a.mjs
export default {
  hello () {
    console.log(`hello JavaScript`);
  }
}

// index-b.mjs
import('./index-a.mjs').then(module => {
  module.default.hello(); // hello JavaScript
})

import.meta

只能在模块内部使用,如果在模块外部使用会报错。这个属性返回一个对象,该对象的各种属性就是当前运行的脚本的元信息。具体包含哪些属性,标准没有规定,由各个运行环境自行决定。一般来说,import.meta 至少会有下面两个属性:

  • import.meta.url 返回当前模块的 URL 路径。
  • import.meta.scriptElement 是浏览器特有的元属性,返回加载模块的那个 <script> 元素,相当于 document.currentScript 属性。