一叶蔽目,不见泰山;两豆塞耳,不闻雷霆。 ——《鹖冠子·天则》
疫情当下,寝食难安,何以解忧,唯有学习。截止2022年6月,ECMA大会已经批准了ES2022语言规范。于是决定跟随大家一起点一杯☕️,在这个悠闲的下午一起,喝喝咖啡聊聊天学习学习ES2022。
释义
ES2022提议的新功能到达TC39第四阶段之后,意味着ES2022 以下列出的功能在常用的浏览器环境上都可以使用啦。
TC39 流程的所有阶段可参考,Introducing All Stages of the TC39 Process。
正文
1.at()
.at() 方法可以用于我们读取索引处的元素,并且可以接受负数来对给定数据类型从末尾位置往前读取。
支持此功能的数据类型有:
- String
- Array
- 以及所有的类数组类型数据例如 Unit8Array 等。
示例:
const arr = ['apple', 'orange', 'grapefruit', 'pear'];
const str = 'abcdefg';
console.log(arr.at(0)) // apple
console.log(arr.at(-2)) // grapefruit
console.log(str.at(0)) // a
console.log(str.at(-2)) // f
小结: .at()方法和数组以及字符串的[]方法类似,只是支持了索引为负数进行获取和类数组数据类型获取。
2. await运算符可以在顶级使用()
我们使用async 和 await处理异步任务已经很长一段时间了。但是我们还是不能在异步函数之外是用await关键字。ES2022规范实施之后我们可以在顶级使用await了。 如果在顶级使用await 这就意味着我们可以:
- 延迟当前模块 和 父模块的执行,直到我们await 的模块加载完成
- 模块可以在运行时来确定关系
- 可以使用模块版本备用,保证模块加载顺利
示例:
- 在模块最顶层可以直接使用
const res = await fetch('https://somelink')
const text = res.text();
- 模块加载失败可以使用老版本模块替换加载
let lodash;
try {
lodash = await import('**旧版本链接**')
} catch {
lodash = await import('**新版本链接**')
}
- 使用加载最快的资源
const pkg = await Promise.any([fetch('**资源1**'), fetch('**资源2**')])
- 根据 (运行时 环境 等)条件加载想要的资源
let data;
if (env === 'project') {
data = await import('https://somelink')
} else {
data = await import('https://somelink')
}
3. Class 自定义公共属性方式
在过去的版本中,我们使用Class类定义属性的方式如下:
class People {
constructor() {
this.a = 0;
this.b = 1;
}
click () {
this.a++;
this.b--;
}
}
const people = new People();
people.click()
console.log(people.a, people.b) // 1 0
而在ES2022 之后我们可以这样写
class People {
a = 0;
b = 1;
click () {
this.a++;
this.b--;
}
}
const people = new People();
people.click()
console.log(people.a, people.b) // 1 0
聪明的同学可能早就发现了,这个功能我们其实早就在用了,但是一直没有去成为标准,在这之前我们都是使用babel编译进行转换来实现上述的例子。 感兴趣的童鞋可以使用 babel在线编译网站去look look怎么实施,这里不做具体阐述。
4. Class使用#实现私有属性和方法
在javascript中Class并没有表示私有属性的方式,过去我们通常在class中属性前置_来语义化表示私有属性或方法。ES2022之后我们可以使用#来表示私有属性或方法。
示例:
class People {
name = 'Jay Chou'
#age = 45
set setAge(age) {
this.#age = age
}
}
const people = new People()
people.#age = 18; // Uncaught SyntaxError: Private field '#age' must be declared in an enclosing class (at
people.setAge = 18;
5. Class 使用static实现静态属性
在ES6 中明确规定,Class 内部使用static只能用于静态方法,不能用static表示静态属性,如果要写一个类的静态属性,那么要通过如下方法:
class People {}
People.name = 'Jay'
People.age = 33
而ES2022 之后,static表示类的静态属性提案已经通过,所以之后我们可以直接用如下方式来表示类的静态属性:
class People {
static name = 'Jay'
static age = 33
}
6. 使用in可以对私有属性进行检查
有时候我们访问一个对象的私有属性,这个时候会抛出异常,报错反应是一个正确的反应。 但是有时候我们希望有一种方法能够检查对象是否有私有属性。 使用in 可以对对象的私有属性或私有方法进行检查。
示例:
class People {
#test = 1
#getTest(){
return this.#test
}
static check(obj){
console.log(#test in obj) // true
console.log(#getTest in obj) // true
console.log(#test2 in obj) // Private field '#test2' must be declared in an enclosing class
}
}
People.check(new People())
7. Object.hasOwn()
在ES2022中在Object上新增了hasOwn 方法,判断对象本身(不含原型链上)是否存在某个属性,它是Object.prototype.hasOwnProperty的进化版。
众所周知,当使用Object.create(null)创建一个没有继承 Object.prototype(就是原型链上没有属性) 的对象时,使用hasOwnProperty方法对该对象进行检查会报错,如下:
const c = Object.create(null)
c.test = 1
c.hasOwnProperty('test') // Uncaught TypeError: c.hasOwnProperty is not a function
// 可以使用以下方法进行
Object.prototype.hasOwnProperty.call(c, 'test') // true
- 两种方法对比:
const c = Object.create({fruit: 'apple'})
c.vegetable = 'tomato'
c.hasOwnProperty('vegetable') // true
c.hasOwnProperty('fruit') // false
Object.hasOwn(c, 'vegetable') // true
Object.hasOwn(c, 'fruit') // false
const d = Object.create(null)
d.vegetable = 'tomato'
d.hasOwnProperty('vegetable') // Uncaught TypeError: d.hasOwnProperty is not a function
d.hasOwnProperty('fruit') // Uncaught TypeError: d.hasOwnProperty is not a function
Object.hasOwn(d, 'vegetable') // true
Object.hasOwn(d, 'fruit') // false
- 小结 Object.hasOwn()方法可以更好的检查对象本身是否有某个属性。
8. 正则表达式`/d`修饰符
正则表达式 有/i /g /m /gi /ig修饰符, 释义如下:
/i: 匹配忽略大小写/g:输入字符串中查找所有可能的匹配,返回的结果可以是多个。如果不加/g最多只会匹配一个/m:多行匹配(匹配换行符两端的潜在匹配)/gi:忽略大小写查找所有可能的匹配/ig:忽略大小写查找所有可能的匹配
最新的 /d 修饰符是用来表示想要匹配字符串的开始和结束索引信息。
示例一:
const reg1 = /a+(b)?/;
const reg2 = /a+(b)?/d;
我们能够发现它多了一个indices属性,该属性本身是一个索引数组,其中包含每个捕获的子字符串的一对开始索引和结束索引
示例二:存在命名组的匹配索引
const reg1 = /a+(?<B>b)?/;
const reg2 = /a+(?<B>b)?/d;
从上可以得出 匹配命名组的索引开始和结束索引信息存储在indices.groups属性中
9. error.cause
ES2022 新增了error.cause 来规范化错误的抛出和收集,这里其实是 在我们实例化Error的时候,将错误原因以参数形式传入,让我们可以不用处理error数据的过程。
try {
const result = 1;
result = 2;
} catch (error) {
throw new Error('Assignment to constant variable.', {cause: error})
}
参考资料
相关文章推荐
小结一下
以上便是ES2022最新的内容,我们已经可以在开发中使用,如果需要兼容低版本浏览器,请使用babel等编译工具。
写作不易,如果有帮助请动动小手点赞♥收藏哈,感谢诸君。