Skip to content

ECMAScript 2018 (9)

特性一览

异步迭代

异步迭代器是一个对象,它有一个可迭代方法 [Symbol.asyncIterator],并返回一个包含异步迭代方法 next() 的对象。

异步迭代方法 next() 返回一个 Promise 对象,该对象解析为一个包含 donevalue 两个属性的对象,类似于同步迭代器。

使用异步迭代器的语法如下:

javascript
async function iterateAsync(iterable) {
  const asyncIterator = iterable[Symbol.asyncIterator]();
  while (true) {
    const { done, value } = await asyncIterator.next();
    if (done) break;
    console.log(value);
  }
}

const asyncIterable = {
  async *[Symbol.asyncIterator]() {
    yield Promise.resolve(1);
    yield Promise.resolve(2);
    yield Promise.resolve(3);
  },
};

await iterateAsync(asyncIterable);

在使用异步迭代器的过程中,必须使用 await 关键字等待异步操作完成后才能进行下一步迭代,否则会导致迭代顺序出现错误。

对象的展开和剩余参数语法

用于处理可迭代对象的元素和属性。

对象的展开语法可以将对象的属性展开为单独的变量,或者将一个对象合并到另一个对象中。

js
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const mergedObj = { ...obj1, ...obj2 };
console.log(mergedObj); // { a: 1, b: 2, c: 3, d: 4 }

剩余参数语法可以用来捕获函数的参数,将其存储在数组中,同时可以使用展开语法将它们传递给其他函数。

js
function myFunction(...args) {
  console.log(args);
}
myFunction(1, 2, 3); // [1, 2, 3]

function anotherFunction(x, y, z) {
  console.log(x, y, z);
}
const myArgs = [1, 2, 3];
anotherFunction(...myArgs); // 1 2 3

新的正则表达式语法

  • 命名捕获组

使用(?<name>pattern)语法来定义捕获组,其中name是捕获组的名称,pattern是正则表达式模式。

js
const regex = /(?<month>\d{2})\/(?<day>\d{2})\/(?<year>\d{4})/;

const match = regex.exec("02/27/2021");

console.log(match.groups);
// 输出:{ month: '02', day: '27', year: '2021' }
  • 向前查找断言

使用(?<= )语法来定义向前查找。这表明在bar前面必须有foo

js
const regex = /(?<=foo)bar/;

console.log(regex.test("foobar")); // 输出:true
console.log(regex.test("barfoo")); // 输出:false
  • Unicode 属性转义

使用\p{property}语法来匹配具有特定 Unicode 属性的字符。

Sc代表货币符号,使用u标志来启用 Unicode 模式。

js
const regex = /\p{Sc}/gu;

console.log(regex.test("$")); // 输出:true(因为美元符号是货币符号)

console.log(regex.test("a")); // 输出:false

Promise.finally

允许在Promise链式调用中,无论Promise状态如何,都执行一些代码。

finally方法的基本语法为:

js
new Promise((resolve, reject) => {
  resolve();
  reject();
})
  .then()
  .catch()
  .finally(() => {
    //finally
  });

promise状态变为resolvedrejected时都会被执行。

共享内存

ES2018 引入了 SharedArrayBuffer 对象和 Atomics 对象,允许多个 JavaScript 线程共享内存,以帮助开发者创建更高效的并发程序。SharedArrayBuffer 对象允许线程共享内存,而 Atomics 对象定义了许多原子操作来保证线程安全。

其中多个线程可以同时访问同一块内存,并且可以使用原子操作确保操作是有序和线程安全的。这可以用于加速复杂的算法,例如机器学习和图像处理,以及在处理大型数据集时实现更高效的并发。

通过多个线程对数组进行归并排序。

创建一个 SharedArrayBuffer 对象来存储数组:

javascript
const buffer = new SharedArrayBuffer(1024);
const arr = new Int32Array(buffer);

然后将数组拆分成多个较小的子数组,并将每个子数组分配给不同的线程。线程可以同时访问共享的缓冲区,并使用 Atomics 操作确保对数组的访问是有序和线程安全的。

在归并排序的每个阶段中,每个线程可以对其分配的子数组执行排序操作,并使用 Atomics 对象来获取和释放锁,以确保线程安全。

最后,线程可以合并它们拥有的已排序子数组,以产生最终的已排序数组。在这个过程中,多个线程同时访问同一块共享内存,以实现更高效的并行处理。

解除模板文字限制

允许在模板文字中使用任意表达式,而不仅仅是简单变量。

以前,在模板文字中只能使用简单变量

js
const name = "Alice";
const message = `Hello, ${name}!`;

现在,可以使用任意表达式(比如对象属性、函数调用等)

js
const user = {
  name: "Alice",
  age: 18,
};

function formatUser(user) {
  return `Name: ${user.name}, Age: ${user.age}, Address: ${user.address}`;
}

const message = `User Info: ${formatUser(user)}`;