一杯卡布奇诺的时间看看ES2022(ES13)

314 阅读6分钟

一叶蔽目,不见泰山;两豆塞耳,不闻雷霆。    ——《鹖冠子·天则》

疫情当下,寝食难安,何以解忧,唯有学习。截止2022年6月,ECMA大会已经批准了ES2022语言规范。于是决定跟随大家一起点一杯☕️,在这个悠闲的下午一起,喝喝咖啡聊聊天学习学习ES2022。

释义

ES2022提议的新功能到达TC39第四阶段之后,意味着ES2022 以下列出的功能在常用的浏览器环境上都可以使用啦。

TC39 流程的所有阶段可参考,Introducing All Stages of the TC39 Process

正文

.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()方法和数组以及字符串的[]方法类似,只是支持了索引为负数进行获取和类数组数据类型获取。

我们使用async 和 await处理异步任务已经很长一段时间了。但是我们还是不能在异步函数之外是用await关键字。ES2022规范实施之后我们可以在顶级使用await了。 如果在顶级使用await 这就意味着我们可以:

  1. 延迟当前模块 和 父模块的执行,直到我们await 的模块加载完成
  2. 模块可以在运行时来确定关系
  3. 可以使用模块版本备用,保证模块加载顺利

示例:

  • 在模块最顶层可以直接使用
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')
}

在过去的版本中,我们使用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怎么实施,这里不做具体阐述。

在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;

在ES6 中明确规定,Class 内部使用static只能用于静态方法,不能用static表示静态属性,如果要写一个类的静态属性,那么要通过如下方法:

class People {}

People.name = 'Jay'
People.age = 33

而ES2022 之后,static表示类的静态属性提案已经通过,所以之后我们可以直接用如下方式来表示类的静态属性:

class People {
   static name = 'Jay'
   static age = 33
}

有时候我们访问一个对象的私有属性,这个时候会抛出异常,报错反应是一个正确的反应。 但是有时候我们希望有一种方法能够检查对象是否有私有属性。 使用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())

在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()方法可以更好的检查对象本身是否有某个属性。

正则表达式 有/i /g /m /gi /ig修饰符, 释义如下:

  • /i: 匹配忽略大小写
  • /g:输入字符串中查找所有可能的匹配,返回的结果可以是多个。如果不加/g最多只会匹配一个
  • /m:多行匹配(匹配换行符两端的潜在匹配)
  • /gi:忽略大小写查找所有可能的匹配
  • /ig:忽略大小写查找所有可能的匹配

最新的 /d 修饰符是用来表示想要匹配字符串的开始和结束索引信息。

示例一:

const reg1 = /a+(b)?/;
const reg2 = /a+(b)?/d;

image.png

image.png

我们能够发现它多了一个indices属性,该属性本身是一个索引数组,其中包含每个捕获的子字符串的一对开始索引和结束索引

示例二:存在命名组的匹配索引

const reg1 = /a+(?<B>b)?/;
const reg2 = /a+(?<B>b)?/d;

image.png

从上可以得出 匹配命名组的索引开始和结束索引信息存储在indices.groups属性中

ES2022 新增了error.cause 来规范化错误的抛出和收集,这里其实是 在我们实例化Error的时候,将错误原因以参数形式传入,让我们可以不用处理error数据的过程。

try {
  const result = 1;
  result = 2;
} catch (error) {
  throw new Error('Assignment to constant variable.', {cause: error})
}

参考资料

相关文章推荐

小结一下


以上便是ES2022最新的内容,我们已经可以在开发中使用,如果需要兼容低版本浏览器,请使用babel等编译工具。

写作不易,如果有帮助请动动小手点赞♥收藏哈,感谢诸君。

image.png