大家好,我是 CUGGZ。,2022 年 6 月 22 日,第 123 届 ECMA 大会批准了 ECMAScript 2022 语言规范,这意味着它现在正式成为标准。下面就来看看 ECMAScript 2022 有哪些新特性!,在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:,我们还可以立即调用顶层async函数(IIAFE):,这样会有一个缺点,直接导入的 users 是 undefined,需要在异步执行完成之后才能访问它:,当然,这种方法并不安全,因为如果异步函数执行花费的时间超过100毫秒, 它就不会起作用了,users 仍然是 undefined。,另一个方法是导出一个 promise,让导入模块知道数据已经准备好了:,虽然这种方法似乎是给出了预期的结果,但是有一定的局限性:导入模块必须了解这种模式才能正确使用它。,而顶层await就可以解决这些问题:,顶级 await 在以下场景中将非常有用:,该特性的浏览器支持如下:,在ES2022之前,可以使用 Object.prototype.hasOwnProperty() 来检查一个属性是否属于对象。,Object.hasOwn 特性是一种更简洁、更可靠的检查属性是否直接设置在对象上的方法:,该特性的浏览器支持如下:,at() 是一个数组方法,用于通过给定索引来获取数组元素。当给定索引为正时,这种新方法与使用括号表示法访问具有相同的行为。当给出负整数索引时,就会从数组的最后一项开始检索:,除了数组,字符串也可以使用at()方法进行索引:,在 ECMAScript 2022 规范中,new Error() 中可以指定导致它的原因:,该特性允许我们利用 d 字符来表示我们想要匹配字符串的开始和结束索引。以前,只能在字符串匹配操作期间获得一个包含提取的字符串和索引信息的数组。在某些情况下,这是不够的。因此,在这个规范中,如果设置标志 /d,将额外获得一个带有开始和结束索引的数组。,由于 /d 标识的存在,matchObj还有一个属性.indices,它用来记录捕获的每个编号组:,我们还可以使用命名组:,这里给两个字符匹配分别命名为as和bs,然后就可以通过groups来获取到这两个命名分别匹配到的字符串。,它们的索引存储在 matchObj.indices.groups 中:,匹配索引的一个重要用途就是指向语法错误所在位置的解析器。下面的代码解决了一个相关问题:它指向引用内容的开始和结束位置。,公共类字段允许我们使用赋值运算符 (=) 将实例属性添加到类定义中。下面是一个计数器的例子:,在这个例子中,在构造函数中定义了实例字段和绑定方法,通过新的类语法,可以使代码更加直观。新的公共类字段语法允许我们直接将实例属性作为属性添加到类上,而无需使用构造函数方法。这样就简化了类的定义,使代码更加简洁、可读:,有些小伙伴可能就疑问了,这个功能很早就可以使用了呀。但是它现在还不是标准的 ECMAScript,默认是不开启的,如果使用 create-react-app 创建 React 项目,那么它默认是启用的,否则我们必须使用正确的babel插件才能正常使用(@babel/preset-env)。,下面来看看关于公共实例字段的注意事项:,默认情况下,ES6 中所有属性都是公共的,可以在类外检查或修改。下面来看一个例子:,可以看到,在类中没有任何措施可以防止在不调用 setter 的情况下更改属性。,而私有类字段将使用哈希#前缀定义,从上面的示例中,可以修改它以包含私有类字段,以防止在类方法之外更改属性:,当尝试在 setter 方法之外修改私有类字段时,就会报错:,还可以将方法或 getter/setter 设为私有,只需要给这些方法名称前面加#即可:,由于尝试访问对象上不存在的私有字段会发生异常,因此需要能够检查对象是否具有给定的私有字段。可以使用 in 运算符来检查对象上是否有私有字段:,在ES6中,不能在类的每个实例中访问静态字段或方法,只能在原型中访问。ES 2022 提供了一种在 JavaScript 中使用 static 关键字声明静态类字段的方法。下面来看一个例子:,可以从类本身访问静态字段和方法:,实例不能访问静态字段和方法:,静态字段只能通过静态方法访问:,这里的 Shape.getMessage() 就报错了,因为 getMessage 不是一个静态函数,所以它不能通过类名 Shape 访问。可以通过以下方式来解决这个问题:,静态字段和方法是从父类继承的:,与私有实例字段和方法一样,静态私有字段和方法也使用哈希 (#) 前缀来定义:,私有静态字段有一个限制:只有定义私有静态字段的类才能访问该字段。这可能在使用 this 时导致出乎意料的情况:,在这个例子中,this 指向的是 Rectangle 类,它无权访问私有字段 #color。当我们尝试调用 Rectangle.getMessage() 时,它无法读取 #color 并抛出了 TypeError。可以这样来进行修改:,静态私有和公共字段只能让我们在类定义期间执行静态成员的每个字段初始化。如果我们需要在初始化期间像 try…catch 一样进行异常处理,就不得不在类之外编写此逻辑。该规范就提供了一种在类声明/定义期间评估静态初始化代码块的优雅方法,可以访问类的私有字段。,先来看一个例子:,上面的代码就会引发错误,可以使用类静态块来重构它,只需将try...catch包裹在 static 中即可:,此外,类静态块提供对词法范围的私有字段和方法的特权访问。这里需要在具有实例私有字段的类和同一范围内的函数之间共享信息的情况下很有用。,这里,Person 类与 readPrivateData 函数共享了私有实例属性。
© 版权声明
文章版权归作者所有,未经允许请勿转载。