鲸腾FE,来自鲸腾网络。是一支专注于 web 前端的开发团队,并在 web 前端领域积累了多年疑难问题解决经验。崇尚高效、优质、成长、自由、快乐。
ES2022 可能会在 2022 年 6 月成为标准,我们来看看将成为 ES2022 一部分的特性。
Class Fields
Public Instance Fields(公有实例字段)
公有实例字段存在于类的每一个实例中。公有实例字段可以在基类的构造过程中(构造函数主体运行前)使用 Object.defineProperty 添加,也可以在子类构造函数中的 super() 函数结束后添加。
const PREFIX = 'prefix';
class ClassWithComputedFieldName {
[`${PREFIX}Field`] = 'prefixed field';
instanceField;
}
const instance = new ClassWithComputedFieldName();
console.log(instance.prefixField);
// 预期输出值: "prefixed field"
console.log(instance.instanceField);
// 预期输出值: "undefined"
Private Instance Fields(私有实例字段)
私有实例字段使用 # 名称(发音为“哈希名称”)声明,这些名称以 # 开头。即 # 是名称本身的一部分,声明和访问时也需要加上。私有字段在类声明的构造方法中就可被访问。
从作用域之外引用 # 名称、内部在未声明的情况下引用私有字段、或尝试使用 delete 移除声明的字段都会抛出语法错误。
class ClassWithPrivateField {
#privateField;
constructor() {
this.#privateField = 42;
delete this.#privateField; // 语法错误
this.#undeclaredField = 444; // 语法错误
}
}
const instance = new ClassWithPrivateField()
instance.#privateField === 42; // 语法错误
Static class fields and private static methods(静态类字段和私有静态方法)
类(class)通过 static 关键字定义静态方法。不能在类的实例上调用静态方法,而应该通过类本身调用。
class ClassWithStaticMethod {
static #PRIVATE_STATIC_FIELD;
static staticProperty = 'someValue';
static staticMethod() {
return 'static method has been called.';
}
static publicStaticMethod() {
ClassWithStaticMethod.#PRIVATE_STATIC_FIELD = 42;
return ClassWithStaticMethod.#PRIVATE_STATIC_FIELD;
}
static {
console.log('Class static initialization block called');
}
}
// 预期输出值: "Class static initialization block called"
console.log(ClassWithStaticMethod.staticProperty);
// 预期输出值: "someValue"
console.log(ClassWithStaticMethod.staticMethod());
// 预期输出值: "static method has been called."
console.log(ClassWithStaticMethod.publicStaticMethod() === 42);
// 预期输出值: true
Private instance methods and accessors(私有实例方法)
私有实例方法是类实例上可用的方法,它们的访问方式与私有实例字段相同。
私有实例方法可以是生成器、异步或者异步生成器函数,私有getter和setter。
class ClassWithPrivateAccessor {
#message;
get #decoratedMessage() {
return `${this.#message}`;
}
set #decoratedMessage(msg) {
this.#message = msg;
}
constructor() {
this.#decoratedMessage = 'hello world';
console.log(this.#decoratedMessage);
}
}
new ClassWithPrivateAccessor();
// 预期输出值: "hello world"
RegExp Match Indices
正则表达式匹配索引。向正则表达式添加标志 /d 会生成记录每个组捕获的开始和结束的匹配对象。
从上图可以看到输出的对象中增加了 indices 属性,包含匹配组的开始和结束索引。
除了索引值,还可以通过命名来获取匹配的组,如上图所示。
Top-level await
顶级 await 模块。可以在模块的顶层使用 await 并且不再需要输入异步函数或方法。
动态加载模块
let lodash;
try {
lodash = await import('https://primary.example.com/lodash');
} catch {
lodash = await import('https://secondary.example.com/lodash');
}
使用加载速度最快的资源
const resource = await Promise.any([
fetch('http://example.com/first.txt')
.then(response => response.text()),
fetch('http://example.com/second.txt')
.then(response => response.text()),
]);
.at()
Accessible Object.prototype.hasOwnProperty
即 Object.hasOwn(obj, propKey),可以安全的检查 own 属性,支持所有对象类型。
const proto = {
protoProp: 'protoProp',
};
const obj = {
__proto__: proto,
objProp: 'objProp',
};
console.log('protoProp' in obj);
// 预期输出值: true
console.log(Object.hasOwn(obj, 'protoProp'));
// 预期输出值: false
console.log(Object.hasOwn(proto, 'protoProp'));
// 预期输出值: true
Error Cause
错误及其子类可以指定错误的原因。在深度嵌套函数中很有用,可以将错误链接起来以快速找到错误。
function doWork() {
try {
doSomeWork();
} catch (err) {
throw new Error('Some work failed', { cause: err });
}
try {
doMoreWork();
} catch (err) {
throw new Error('More work failed', { cause: err });
}
}
try {
doWork();
} catch (err) {
switch(err.message) {
case 'Some work failed':
handleSomeWorkFailure(err.cause);
break;
case 'More work failed':
handleMoreWorkFailure(err.cause);
break;
}
}