【发布时间】:2018-06-29 20:02:20
【问题描述】:
由于旧的浏览器支持,我们都使用 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 中对其进行了测试。
我对Object.setPrototypeOf 的前 5 次测试运行结果非常令人失望:慢了 19%、慢了 20% 和慢了三倍 21%。
我知道Object.setPrototypeOf 可能需要使用一定有一些原因。我想知道。如果是关于不可枚举的属性,那么我们当然可以使用其他一些方法。
【问题讨论】:
-
在 Edge 中慢了 44%
标签: javascript ecmascript-6 babeljs ecmascript-5