ECMAScript 2022 正式发布,有哪些新特性?(上)

简介: ECMAScript 2022 正式发布,有哪些新特性?(上)

大家好,我是 CUGGZ。

2022 年 6 月 22 日,第 123 届 ECMA 大会批准了 ECMAScript 2022 语言规范,这意味着它现在正式成为标准。下面就来看看 ECMAScript 2022 新增了哪些特性!


1.webp (1).jpg


总览:

  1. Top-level Await
  2. Object.hasOwn()
  3. at()
  4. error.cause
  5. 正则表达式匹配索引
  6. 类的实例成员


1. Top-level Await


在ES2017中,引入了 async 函数和 await 关键字,以简化 Promise 的使用,但是 await 关键字只能在 async 函数内部使用。尝试在异步函数之外使用 await 就会报错:SyntaxError - SyntaxError: await is only valid in async function

顶层 await 允许我们在 async 函数外面使用 await 关键字。它允许模块充当大型异步函数,通过顶层 await,这些 ECMAScript 模块可以等待资源加载。这样其他导入这些模块的模块在执行代码之前要等待资源加载完再去执行。

由于 await 仅在 async 函数中可用,因此模块可以通过将代码包装在 async 函数中来在代码中包含 await


  // a.js
  import fetch  from "node-fetch";
  let users;
  export const fetchUsers = async () => {
    const resp = await fetch('https://jsonplaceholder.typicode.com/users');
    users =  resp.json();
  }
  fetchUsers();
  export { users };
  // usingAwait.js
  import {users} from './a.js';
  console.log('users: ', users);
  console.log('usingAwait module');

我们还可以立即调用顶层async函数(IIAFE):

import fetch  from "node-fetch";
  (async () => {
    const resp = await fetch('https://jsonplaceholder.typicode.com/users');
    users = resp.json();
  })();
  export { users };

这样会有一个缺点,直接导入的 usersundefined,需要在异步执行完成之后才能访问它:

// usingAwait.js
import {users} from './a.js';
console.log('users:', users); // undefined
setTimeout(() => {
  console.log('users:', users);
}, 100);
console.log('usingAwait module');

当然,这种方法并不安全,因为如果异步函数执行花费的时间超过100毫秒, 它就不会起作用了,users 仍然是 undefined

另一个方法是导出一个 promise,让导入模块知道数据已经准备好了:

//a.js
import fetch  from "node-fetch";
export default (async () => {
  const resp = await fetch('https://jsonplaceholder.typicode.com/users');
  users = resp.json();
})();
export { users };
//usingAwait.js
import promise, {users} from './a.js';
promise.then(() => { 
  console.log('usingAwait module');
  setTimeout(() => console.log('users:', users), 100); 
});

虽然这种方法似乎是给出了预期的结果,但是有一定的局限性:导入模块必须了解这种模式才能正确使用它

而顶层await就可以解决这些问题:

  // a.js
  const resp = await fetch('https://jsonplaceholder.typicode.com/users');
  const users = resp.json();
  export { users};
  // usingAwait.js
  import {users} from './a.mjs';
  console.log(users);
  console.log('usingAwait module');

顶级 await 在以下场景中将非常有用:

  • 动态加载模块:


const strings = awaitimport(`/i18n/${navigator.language}`);
  • 资源初始化:


const connection = awaitdbConnector();
  • 依赖回退:
let translations;
try {
  translations = await import('https://app.fr.json');
} catch {
  translations = await import('https://fallback.en.json');
}

该特性的浏览器支持如下:1234.webp.jpg


2. Object.hasOwn()


在ES2022之前,可以使用 Object.prototype.hasOwnProperty() 来检查一个属性是否属于对象。

Object.hasOwn 特性是一种更简洁、更可靠的检查属性是否直接设置在对象上的方法:


const example = {
  property: '123'
};
console.log(Object.prototype.hasOwnProperty.call(example, 'property'));
console.log(Object.hasOwn(example, 'property'));

该特性的浏览器支持如下:

4321.webp.jpg


3. at()


at() 是一个数组方法,用于通过给定索引来获取数组元素。当给定索引为正时,这种新方法与使用括号表示法访问具有相同的行为。当给出负整数索引时,就会从数组的最后一项开始检索:

const array = [0,1,2,3,4,5];
console.log(array[array.length-1]);  // 5
console.log(array.at(-1));  // 5
console.log(array[array.lenght-2]);  // 4
console.log(array.at(-2));  // 4

除了数组,字符串也可以使用at()方法进行索引:


const str = "hello world";
console.log(str[str.length - 1]);  // d
console.log(str.at(-1));  // d

4. error.cause


在 ECMAScript 2022 规范中,new Error() 中可以指定导致它的原因:

function readFiles(filePaths) {
  return filePaths.map(
    (filePath) => {
      try {
        // ···
      } catch (error) {
        throw new Error(
          `While processing ${filePath}`,
          {cause: error}
        );
      }
    });
}


5. 正则表达式匹配索引


该特性允许我们利用 d 字符来表示我们想要匹配字符串的开始和结束索引。以前,只能在字符串匹配操作期间获得一个包含提取的字符串和索引信息的数组。在某些情况下,这是不够的。因此,在这个规范中,如果设置标志 /d,将额外获得一个带有开始和结束索引的数组。

const matchObj = /(a+)(b+)/d.exec('aaaabb');
console.log(matchObj[1]) // 'aaaa'
console.log(matchObj[2]) // 'bb'

由于 /d 标识的存在,matchObj还有一个属性.indices,它用来记录捕获的每个编号组:


console.log(matchObj.indices[1])  // [0, 4]console.log(matchObj.indices[2])  // [4, 6]

我们还可以使用命名组:

const matchObj = /(?<as>a+)(?<bs>b+)/d.exec('aaaabb');
console.log(matchObj.groups.as);  // 'aaaa'
console.log(matchObj.groups.bs);  // 'bb'

这里给两个字符匹配分别命名为asbs,然后就可以通过groups来获取到这两个命名分别匹配到的字符串。

它们的索引存储在 matchObj.indices.groups 中:

console.log(matchObj.indices.groups.as);  // [0, 4]
console.log(matchObj.indices.groups.bs);  // [4, 6]

匹配索引的一个重要用途就是指向语法错误所在位置的解析器。下面的代码解决了一个相关问题:它指向引用内容的开始和结束位置。

const reQuoted = /“([^”]+)”/dgu;
function pointToQuotedText(str) {
  const startIndices = new Set();
  const endIndices = new Set();
  for (const match of str.matchAll(reQuoted)) {
    const [start, end] = match.indices[1];
    startIndices.add(start);
    endIndices.add(end);
  }
  let result = '';
  for (let index=0; index < str.length; index++) {
    if (startIndices.has(index)) {
      result += '[';
    } else if (endIndices.has(index+1)) {
      result += ']';
    } else {
      result += ' ';
    }
  }
  return result;
}
console.log(pointToQuotedText('They said “hello” and “goodbye”.'));
// '           [   ]       [     ]  '


ECMAScript 2022 正式发布,有哪些新特性?(下)https://developer.aliyun.com/article/1411127

相关文章
|
4月前
|
自然语言处理 JavaScript 前端开发
ECMAScript 2022 正式发布,有哪些新特性?(下)
ECMAScript 2022 正式发布,有哪些新特性?(下)
|
4月前
|
JavaScript 前端开发 Unix
ECMAScript 2023 正式发布,有哪些新特性?
ECMAScript 2023 正式发布,有哪些新特性?
|
8月前
|
存储 JavaScript 前端开发
ECMAScript 2020(ES11)新特性简介
ECMAScript 2020(ES11)新特性简介
65 0
|
8月前
|
JavaScript 前端开发 索引
ECMA 2022 (es13) 新特性
ECMA 2022 (es13) 新特性
38 0
|
11月前
|
存储 前端开发 JavaScript
ECMAScript 6 新特性详解(下)
ECMAScript 6 新特性详解(下)
|
11月前
|
存储 JSON JavaScript
ECMAScript 6 新特性详解(中)
ECMAScript 6 新特性详解(中)
|
11月前
|
自然语言处理 JavaScript 前端开发
ECMAScript 6 新特性详解(上)
ECMAScript 6 新特性详解(上)
|
前端开发 JavaScript Java
ECMAScript 2021(ES12)新特性简介
ECMAScript 2021(ES12)新特性简介
|
JavaScript 前端开发
ECMAScript 6新特性简介
ECMAScript 6新特性简介
ECMAScript 6新特性简介
|
存储 XML JSON
ECMAScript 2019(ES10)新特性简介
ECMAScript 2019(ES10)新特性简介