ES2022新特性一览

新增内置索引方法.at()方法

新增内置索引方法.at()方法📕

1
2
3
4
5
6
7
8
9
10
11
const cart = ['🍎', '🍌', '🍍'];

// 第一个元素
cart.at(0); // '🍎'

// 最后一个元素
cart.at(-1); // '🍍'

// 越界了
cart.at(-100); // undefined
cart.at(100); // undefined
1
2
3
4
5
6
7
8
9
10
11
const int8 = new Int8Array([0, 10, 42, -10]);

// 第一个元素
int8.at(0); // 0

// 最后一个元素
int8.at(-1); // -10

// 越界了
int8.at(-100) // undefined
int8.at(100) // undefined
1
2
3
4
5
6
7
8
9
10
11
const sentence = 'This is a sample sentence'

// 第一个元素
sentence.at(0); // 'T'

// 最后一个元素
sentence.at(-1); // 'e'

// 越界了
sentence.at(-100) // undefined
sentence.at(100) // undefined

正则表达式匹配指标

捕获字符串开始和结束额外信息的指标 📕

1
2
3
4
5
6
7
8
9
/(?<xs>x+)(?<ys>y+)/.exec('xxxyyxx');
/*[
'xxxyy',
'xxx',
'yy',
index: 0,
input: 'xxxyyxx',
groups: [Object: null prototype] { xs: 'xxx', ys: 'yy' }
]*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
let input = "abcd";
let match = /b(c)/.exec(input);
let indices = match.indices;

// `indices` has the same length as match
indices.length === match.length

// The first element of `indices` contains the start/end indices of the match
indices[0]; // [1, 3];
input.slice(indices[0][0], indices[0][1]); // same as match[0]

// The second element of `indices` contains the start/end indices of the first capture
indices[1]; // [2, 3];
input.slice(indices[1][0], indices[1][1]); // same as match[1]);

Object.hasOwn

Objext.hasOwn 📕

1
2
3
4
5
6
7
8
9
10
11
12
let books = {}
books.prop = 'exists';

// `hasOwn` 对直接显性原型属性返回true
Object.hasOwn(books, 'prop'); // returns true
Object.hasOwn(books, 'toString'); // returns false
Object.hasOwn(books, 'hasOwnProperty'); // returns false

// The `in` 对继承属性和直接属性都返回true
'prop' in books; // returns true
'toString' in books; // returns true
'hasOwnProperty' in books; // returns true

Error cause 错误原因

cause 属性为来表明错误的原因📕

1
2
3
4
const actual = new Error('a better error!', { cause: 'Error cause' });

actual instanceof Error; // true
actual.cause; // 'Error cause'
1
2
3
4
5
try {
maybeWorks();
} catch (err) {
throw new Error('maybeWorks failed!', { cause: err });
}

顶级await

在模块方法外面的await 📕

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 这是index.mjs

// 失败
await Promise.resolve('🍎');
// → SyntaxError: await is only valid in async function

// 使用匿名函数包裹
(async function() {
await Promise.resolve('🍎');
// → 🎉
}());

// to top-level await 支持使用顶级await
await Promise.resolve('🍎') // '🍎'
1
const i18n = await import(`./content-${language}.mjs`);

Class属性声明

公共属性和私有属性组合混合使用声明 📕

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class SampleClass {
/*
代替:
constructor() { this.publicID = 42; }
*/
publicID = 42; // public field

/*
代替:
static get staticPublicField() { return -1 }
*/
static staticPublicField = -1;

// static private field 静态私有属性
static #staticPrivateField = 'private';

//使用方法
#privateMethod() {}

// static block
static {
// executed when the class is created 当class创建的时候执行
}
}

符合语义的检测私有属性方式

无须表达式的检查类型 📕

1
2
3
4
5
6
7
8
9
10
11
12
class C {
#brand;

#method() {}

get #getter() {}

static isC(obj) {
// in keyword to check
return #brand in obj && #method in obj && #getter in obj;
}
}

原文:https://h3manth.com/ES2022/