v9.4
发布信息
发布时间:2021.09.06
Chrome 同步版本:Chrome 94
链接:V8 release v9.4
JavaScript 新特性
1. class 支持类静态初始化块
新的类静态初始化块语法,提供了一个单独的位置,来存放给定的类初始化时应该运行一次的代码。
class MyPRNG {
constructor(seed) {
console.log('constructor');
if (seed === undefined) {
if (MyPRNG.entropyPool.length === 0) {
throw new Error('Entropy pool exhausted');
}
seed = MyPRNG.entropyPool.pop();
}
this.seed = seed;
}
static entropyPool = [];
static {
for (let i = 0; i < 512; i++) {
this.entropyPool.push(i);
}
console.log('static block');
}
}
可以看到类静态初始化块,在类 MyPRNG
初始化时就进行了块内的计算:
从 v9.4开始,类静态初始化块将不需要 -- harmony-class-static-blocks
标志。
v9.3
发布信息
发布时间:2021.08.09
Chrome 同步版本:Chrome 93
链接:V8 release v9.3
JavaScript 新特性
1. Sparkplug 批量编译
V8 在 v9.1 中发布了超快的新中间层 JIT 编译器 Sparkplug。出于安全原因,V8 write-protectes (W^X) 代码内存生成时,要求在可写 (编译期间) 和可执行之间翻转权限。这是当前使用 mprotect
调用实现的。然而,由于 Sparkplug 生成代码的速度非常快,因此为每个单独的编译函数调用 mprotect 的成本成为编译时间的主要瓶颈。在 V8 v9.3中,我们引入了 Sparkplug 的批量编译: 我们不是单独编译每个函数,而是在批量中编译多个函数。这可以通过每批只翻转一次内存页面权限来分摊这种操作的成本。
批量编译可以减少总的编译时间 (Ignition + Sparkplug) 高达44% ,而无需回溯 JavaScript 的执行。如果我们只看编译 Sparkplug 代码的成本,影响显然更大,例如 Win 10上的 docs_scrolling
基准 (见下文) 减少了82% 。令人惊讶的是,批处理编译比 W^X 的成本提高了更多的编译性能,因为将类似的操作批处理在一起对 CPU 来说更好。在下图中,你可以看到 W^X 对编译时间的影响 (Ignition + Sparkplug)) ,以及批量编译如何减轻这种开销。
2. Object.hasOwn
Object.hasOwn
是 Object.prototype.hasOwnProperty.call
更易记的别名(查看特性解释)。
Object.hasOwn({ prop: 42 }, 'prop')
// → true
3. Error 新增属性 cause
从 v9.3 开始,对各种内置的 Error
构造函数进行了扩展,可以接受第二个参数包含 cause
属性的可选项。如果传递了这样的可选项,则 cause
属性的值将作为 Error
实例上自己的属性。这为错误链提供了一种标准化的方法(查看特性解释):
const parentError = new Error('parent');
const error = new Error('parent', { cause: parentError });
console.log(error.cause === parentError);
// → true
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;
}
}