ES2022与ES2023特性一览

2024/04更新:将ES2023标准特性补充完整

ECMAScript 2022 标准

class fields

类相关特性的集合

private instance methods and accessors

私有实例方法和访问器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class People {
name = "zhangsan";
// 私有实例方法
#say() {
console.log("hello");
}
// 私有访问器
get #getName() {
return this.name;
}
}

const zhangsan = new People();
console.log(zhangsan.#say); // 报错
console.log(zhangsan.#getName); // 报错

private Instance Fields

私有实例字段

1
2
3
4
5
6
7
8
9
10
11
class People {
#name;
constructor() {
this.#name = "zhangsan";
}
getName() {
return this.#name;
}
}
const zhangsan = new People();
zhangsan.#name; // 报错

public Instance Fields

公有实例字段

1
2
3
4
5
6
7
8
9
10
11
// before
class People {
contructor() {
this.name = "zhangsan";
}
}

// after
class People2 {
name = "zhangsan";
}

static class fields and methods

静态类字段和方法

1
2
3
4
5
6
class People {
static name = "zhangsan";
static getName() {
console.log(this.name);
}
}

private static fields and methods

私有静态字段和方法

1
2
3
4
5
6
7
8
class People {
// 静态私有字段
static #name = "zhangsan";
// 静态私有方法
static #getName() {
console.log(People.#name);
}
}

RegExp Match Indices

正则匹配,新增/d修饰符,exec 方法返回的结果数组就会多出一个indices属性,用来返回匹配结果的开始索引和结束索引。

1
2
3
4
5
6
const str = "foo-bar-foo";
const reg = /foo/d;
const match = reg.exec(str);
const matchIndexArr = match.indices[0];
//加上/d修饰符,存在indices属性
console.log(matchIndexArr); // [0, 3]

class static block

类里面的静态区块

1
2
3
4
5
class {
static {
// any static fields & methods
}
}

Top-level await

顶级区块使用 await

1
2
3
4
5
async function getData() {
return await Promise.resolve("value");
}
const data = await getData();
console.log(data, "top-level await");

Ergonomic brand checks for Private Fields

检测实例的类中是否含有私有属性

1
2
3
4
5
6
7
8
9
10
11
12
13
class People {
#name = "zhangsan";
#say() {
console.log("hello");
}
get #getName() {}
static hasPrivateFields(obj) {
return #name in obj && #say in obj && #getName in obj;
}
}

const zhangsan = new People();
console.log(People.hasPrivateFields(zhangsan));

hasOwn

Object 新增hasOwn方法替换原有的hasOwnProperty,判断某个属性是对象本身的属性,还是原型链上的属性,Object.hasOwn() 方法是比 Object.prototype.hasOwnProperty() 方法更加 便捷安全 的策略。当 Object.create(null) 创建一个不继承自 Object.prototype 的对象,使 hasOwnProperty 方法无法访问。

1
2
3
4
5
6
7
8
9
let object = { foo: false };
Object.hasOwn(object, "foo"); // true

let object2 = Object.create({ foo: true });
Object.hasOwn(object2, "foo"); // false

let object3 = Object.create(null);
Object.hasOwn(object3, "foo"); // false
Object.create(null).hasOwnProperty("foo"); // Uncaught TypeError: Object.create(...).hasOwnProperty is not a function

at

数组新增at方法

1
2
3
const array = [1, 2, 3, 4];
array.at(-1); // 4
array.at(0); // 1

Error Cause

Error构造函数新增一个cause附加参数

1
2
3
4
5
6
7
8
try {
throw new Error("this is error message", {
// cause: "this is error cause",
cause: { err: "is error obj" },
});
} catch (error) {
console.log(error.cause);
}

ECMAScript 2023 标准

findLast 和 findLastIndex

数组新增两个查找方法

  • findLast
    从后往前查找符合要求的数据

  • findLastIndex
    从后往前查找符合要求的数据的 Index

1
2
3
4
5
6
7
8
const array = [{ value: 1 }, { value: 2 }, { value: 3 }, { value: 4 }];

// find
array.findLast((n) => n.value % 2 === 1); // { value: 3 }

// find
array.findLastIndex((n) => n.value % 2 === 1); // 2
array.findLastIndex((n) => n.value === 42); // -1

Hashbang 语法

在文件头加入Hashbang #!/usr/bin/env node,你可以在命令行中直接键入./hello.js运行以下脚本(脚本文件名:hello.js),而无需使用node ./hello.js

1
2
3
#!/usr/bin/env node
let str = 'Hello World!'
console.log(str);

Symbols as WeakMap keys

扩展了WeakMap,允许使用Symbol作为key

1
2
3
4
5
6
7
const weak = new WeakMap();
const key = Symbol('my ref');
const someObject = {
/* data data data */
};

weak.set(key, someObject);

Change Array by copy

提供一些通过复制的方式(不直接修改原数组)更改数组的方法

  • toReversed()

数组反转方法,reverse的复制版本,区别在于toReversed会返回一个新的数组,原数组不会改变

1
2
3
4
5
6
7
8
9
10
11
12
13
// 原来的方式
const sequence_origin = [1, 2, 3];
// 数组反转
sequence_origin.reverse(); // => [3, 2, 1]
// 会改变原始数组
sequence_origin; // => [3, 2, 1]

// 现在的方式
const sequence = [1, 2, 3];
// 数组反转
sequence.toReversed(); // => [3, 2, 1]
// 不改变原始数组
sequence; // => [1, 2, 3]
  • toSorted(compareFn)

数组排序方法,sort的复制版本,区别在于toSorted会返回一个新的数组,原数组不会改变

1
2
3
4
const outOfOrder = [3, 1, 2];
outOfOrder.toSorted(); // => [1, 2, 3]
outOfOrder; // => [3, 1, 2]

  • toSpliced(start, deleteCount, ...items)

就地移除或者替换已存在的元素和/或添加新的元素,splice的复制版本,区别在于toSpliced会返回一个新的数组,原数组不会改变

1
2
3
4
5
6
const months = ["Jan", "Mar", "Apr", "May"];
// 在索引 1 处添加一个元素
const months2 = months.toSpliced(1, 0, "Feb");
console.log(months2); // ["Jan", "Feb", "Mar", "Apr", "May"]
// 原数组不会被修改
console.log(months); // ["Jan", "Mar", "Apr", "May"]
  • with(index, value)

with() 通过返回一个指定索引处的值被新值替换的新数组,来改变数组中指定索引处的值,原数组不会被修改。

1
2
3
4
5
const correctionNeeded = [1, 1, 3];
// 修改指定索引处的值
correctionNeeded.with(1, 4); // => [1, 4, 3]
// 原数组不会被修改
correctionNeeded; // => [1, 1, 3]

参考

TC39 提案

ES2022 新特性必知必会

— END —