ES 13 来了,盘点 ECMAScript 2022 新特性

8,135 阅读4分钟

ES 13 来了,大家可以学习起来了

前言

  • es13 来了,今天我们一起来学习下新的特性,学会了,面试的时候又可以装逼了

  • ECMAScript 2022, the 13th edition, introduced top-level await, allowing the keyword to be used at the top level of modules;

  • new class elements: public and private instance fields, public and private static fields, private instance methods and accessors, and private static methods and accessors; static blocks inside classes, to perform per-class evaluation initialization;

  • the #x in obj syntax, to test for presence of private fields on objects;

  • regular expression match indices via the /d flag, which provides start and end indices for matched substrings;

  • the cause property on Error objects, which can be used to record a causation chain in errors;

  • the at method for Strings, Arrays, and TypedArrays, which allows relative indexing;

  • and Object.hasOwn, a convenient alternative to Object.prototype.hasOwnProperty.

  • 前面介绍过 es6 ~ es12 的文章,有兴趣的可以去看一下

es6 ~ es12 讲解文章链接

ECMAScript 2022, the 13th edition(ES13)

  • 下面我们逐个来分析一下上面的文字
await
  • 引入了顶层 await,允许关键词 在模块的顶层使用

  • 之前要想使用 await 必须在函数外面使用 async 关键字,否则报错,新的特性支持在顶层写 await 了

// 之前使用
const request = async () => {
  await axios.get('');
};

// 现在使用,可以直接在顶层使用
const fun = (timeout) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, timeout);
  });
};

await fun(3000);
类 Class
类的私有字段
  • 通过 # 关键字,可以创建私有字段或者方法,不可以在外部被访问到,内部可以访问
class Breeze {
  constructor() {
    this.age = 18;
  }
  name = 'zhang';
  #girl = 'bao';
  #eat() {
    console.log('eating');
  }
  miss() {
    console.log(this.#girl);
  }
  meet() {
    this.#eat();
  }
}

const boy = new Breeze();
console.log(boy.#girl); // Uncaught SyntaxError: Private field '#girl' must be declared in an enclosing class
console.log(boy.miss()); // bao
console.log(boy.meet()); // eating
  • 如果给 私有属性或者方法加上 static 关键字
  • 加上 static 只能通过类名来调用,不能被实例对象调用(和之前的概念没有差别)
class Breeze {
  constructor() {
    this.age = 18;
  }
  static name = 'zhang';
  static #girl = 'bao';
  static #eat() {
    console.log('eating');
    console.log(this.#girl); // this 指向构造函数
    this.#miss(); // 同样带有 static 才可以访问
  }
  static #miss() {
    console.log(this.#girl);
  }
  meet() {
    this.constructor.#eat(); // 没加 static 关键字,需要加上 constructor,这边的 this 指向实例
  }
}

const boy = new Breeze();
console.log(boy.meet());
使用 in 判断是否是对象的私有属性
  • 接着上面的代码
class Breeze {
  constructor() {
    this.age = 18;
  }
  name = 'zhang';
  #girl = 'bao';
  #eat() {
    console.log('eating');
  }
  testEat() {
    return #eat in this;
  }
}
const boy = new Breeze();
console.log(boy.testEat()) // true
console.log('name' in boy) // true
类内的静态块(static blocks inside classes)
  • 类内的静态块,用于执行每个类的评估初始化
  • 可以在类中包含静态块,可以做初始化处理,比如在外部如何获取到内部的私有字段
  • 可以声明多个静态块
let getPrivateField;
class Breeze {
  constructor() {
    this.age = 18;
  }
  name = 'zhang';
  #girl = 'bao';
  static {
    console.log(1);
  }
  static {
    console.log(2);
    getPrivateField = (el) => el.#girl; // 内部可以访问到私有属性
  }
}
const boy = new Breeze();
console.log(getPrivateField(boy)); // bao
/d 正则
  • 正则表达式通过/d 标志匹配索引,该标志为匹配的子字符串提供开始和结束索引
  • 用人话讲就是提供了一个字段 indices,值为数组,分别标志了匹配到的字符串的开始和结束位置,下面来看一看
const str = 'Hello world!';
//查找"Hello"
const patt = /Hello/;
const res = patt.exec(str);
console.log(res); // ['Hello', index: 0, input: 'Hello world!', groups: undefined]

// 加上 d
const patt = /Hello/d;
const res = patt.exec(str);
console.log(res); // ['Hello', index: 0, input: 'Hello world!', groups: undefined, indices: [[0, 5], groups: undefined]]
console.log(res.indices); // [[0, 5], groups: undefined]
Error 对象的 cause 属性
  • 可用于记录错误的因果链
  • 就是可以传递我们错误信息,易于理解深度嵌套的错误
function capture() {
  try {
    fun();
  } catch (err) {
    throw new Error('error message', { cause: err });
  }
}

// 调用
try {
  capture();
} catch (err) {
  console.log(err);
  console.log(`Cause by: ${err.cause}`);
}
at
  • 这个方法支持相对索引
  • 一直以来 js 的数组只支持正序索引,要是想拿到 arr 数组最后一个元素只能 arr[arr.length - 1],不方便
const arr = [1, 2, 3, 4, 5];
arr[0]; // 1
arr.at(0); // 1
arr.at(-1); // 5
  • at 方法不仅支持数组,同样可以在字符串中使用
const str = 'hello';
str.at(0); // h
str.at(-1); // o
Object.hasOwn
  • 一个替代 Object.prototype.hasOwnProperty 的方案
const obj = { name: 'breeze' };
// 原先用法
Object.prototype.hasOwnProperty.call(obj, 'name'); // true
// 现在
Object.hasOwn(obj, 'name');

总结

  • 新加的类内的静态块,可以做一些初始化的操作还是非常有用的
  • 数组加了倒叙索引,有实用性
  • Error 对象的 cause 可以帮助我们传递错误信息,方便排查
  • await 可以用在顶层,在一些模块化异步加载方面很实用,但是不能滥用,导致异常