为什么 Babel 修改子类的原型而不是复制静态属性?

问题描述 投票:0回答:1

由于旧的浏览器支持,我们都使用babeljs将ES6转译为ES5。当 Babel 编译一个从另一个类扩展的类时。编译后的代码的一部分类似于此:

...
if (superClass)
    Object.setPrototypeOf
      ? Object.setPrototypeOf(subClass, superClass)
      : (subClass.__proto__ = superClass);
...

顶部代码块用于从父类扩展静态属性。他们使用

Object.setPrototypeOf
来更改子类的
[[Prototype]]
。不要混淆
.prototype
[[Prototype]]
是完全不同的事物。

MDN 在其参考文献中关于

Object.setPrototypeOf
的使用的说明如下:

根据现代 JavaScript 引擎优化属性访问方式的本质,在每个浏览器和 JavaScript 引擎中,更改对象的 [[Prototype]] 都是一个非常缓慢的操作。

我的问题出现在这里:如果我们可以用另一种方式达到相同的结果,为什么 Babel 使用

Object.setPrototypeOf
?我尝试通过循环构造函数 Function 对象来复制父类(我之前分配给该父类)的所有静态方法。

...
var parentStaticProps = parentClass.prototype.constructor;

for (var prop in parentStaticProps) {
  childClass.prototype.constructor[prop] = parentStaticProps[prop];
}
...

而且它也比 Babel 的实现速度更快!我创建了类似于 Babel 所做的事情来扩展类,并在 jsPerf 中对其进行了测试。 我的前 5 名测试运行结果非常令人失望,

Object.setPrototypeOf
:慢了 19%,慢了 20%,慢了三倍,慢了 21%。

我知道一定有一些原因为什么

Object.setPrototypeOf
可能需要使用。我想知道。如果是关于不可枚举的属性那么我们绝对可以使用其他一些方法。

javascript ecmascript-6 babeljs ecmascript-5
1个回答
5
投票

如果我们可以用另一种方式达到相同的结果,为什么 Babel 使用

Object.setPrototypeOf

仅仅因为没有其他方法可以达到相同的结果。仅复制所有属性的当前值与从另一个对象动态继承不同。 Babel 的目标是正确,而不是快速。

而且它也比 babel 的实现速度更快!我创建了类似于 babel 的东西来扩展类并在 jsPerf 中测试它。

嗯,创建和扩展类很慢,但这并不重要。 使用这些类 - 例如访问静态属性 - 是这里的重要方面。通常,您对新的(但未使用的)对象的 [[prototype]] 进行突变是没有问题的 - 警告更关心的是在对象生命周期的中间进行突变。

© www.soinside.com 2019 - 2024. All rights reserved.