由于旧的浏览器支持,我们都使用babeljs将ES6转换为ES5。当babel编译一个从另一个类扩展的类时。编译代码的一部分与此类似:
...
if (superClass)
Object.setPrototypeOf
? Object.setPrototypeOf(subClass, superClass)
: (subClass.__proto__ = superClass);
...
顶部代码块用于扩展父类的静态属性。他们使用Object.setPrototypeOf
来更改子类的[[Prototype]]
。不要混淆.prototype
和[[Prototype]]
是完全独立的事情。
MDN在其关于使用Object.setPrototypeOf
的参考文献中所说的内容如下:
根据现代JavaScript引擎优化属性访问的性质,改变对象的[[Prototype]],在每个浏览器和JavaScript引擎中都是非常慢的操作。
我的问题出现在这里:如果我们能用另一种方式达到相同的结果,为什么Babel会使用Object.setPrototypeOf
?我试图通过循环构造函数对象来复制父类中的所有静态方法(我之前已经分配给它)。
...
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
可能需要使用的原因。我想知道。如果它是关于非可枚举的属性,那么我们肯定可以使用其他一些方法。
答案 0 :(得分:5)
如果我们可以通过另一种方式获得相同的结果,为什么Babel会使用
Object.setPrototypeOf
?
仅仅因为没有其他方法可以达到相同的效果。只是复制所有属性的当前值与从另一个对象动态继承不同。巴别塔的目标是正确,而不是快速。
它也比babel的实施更快!我创建了类似于babel扩展类并在jsPerf中测试它的东西。
好吧,创建和扩展类 很慢,并不重要。 使用这些类 - 例如访问静态属性 - 是这里的重要方面。通常没有问题是你改变了一个新的(未使用的)对象的[[prototype]] - 警告更关心的是在对象生命周期的中间进行变异。