ES6 到 ES5:Babel 对 class 扩展的实现
ES6 to ES5: Babel's implementation of class extension
由于旧浏览器的支持,我们都使用babeljs将ES6转译为ES5。当 babel 编译一个从另一个 class 扩展而来的 class 时。编译代码的一部分是类似这样的:
...
if (superClass)
Object.setPrototypeOf
? Object.setPrototypeOf(subClass, superClass)
: (subClass.__proto__ = superClass);
...
顶部代码块用于从 parent class 扩展静态属性。他们用Object.setPrototypeOf
改变了childclass的[[Prototype]]
。不要混淆 .prototype
和 [[Prototype]]
是完全不同的东西。
MDN 在其参考中关于使用 Object.setPrototypeOf
的内容如下:
Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine.
我的问题出现在这里:如果我们可以用另一种方式达到相同的结果,为什么 Babel 使用 Object.setPrototypeOf
?我试图通过循环构造函数 object.
从 parent class (我之前分配给它)复制所有静态方法
...
var parentStaticProps = parentClass.prototype.constructor;
for (var prop in parentStaticProps) {
childClass.prototype.constructor[prop] = parentStaticProps[prop];
}
...
而且比babel的实现速度还快!我创建了一些类似于 babel 扩展 class 并在 jsPerf 中测试它的东西。
我的前 5 名测试 运行 结果非常令人失望 Object.setPrototypeOf
:慢 19%,慢 20%,慢三倍 21%。
我知道 Object.setPrototypeOf
可能需要使用肯定有一些原因。我想知道。如果是关于 non-enumerable 属性那么我们肯定可以使用一些其他方法。
If we can achieve the same result with another way why Babel uses Object.setPrototypeOf
?
很简单,因为没有其他方法可以达到相同的结果。仅仅复制所有属性的当前值与从另一个对象动态继承是不同的。 Babel 的目标是正确,而不是快速。
And it is also faster than babel's implementation! I have created something similar what babel does to extend a class and tested it in jsPerf.
好吧,创建和扩展 类 是 慢,但这并不重要。 使用 那些 类 - 例如访问静态属性 - 是这里的重要方面。通常没有问题的是你改变一个新的(尚未使用的)对象的 [[prototype]] - 警告更关心在对象生命周期的中间进行突变。
由于旧浏览器的支持,我们都使用babeljs将ES6转译为ES5。当 babel 编译一个从另一个 class 扩展而来的 class 时。编译代码的一部分是类似这样的:
...
if (superClass)
Object.setPrototypeOf
? Object.setPrototypeOf(subClass, superClass)
: (subClass.__proto__ = superClass);
...
顶部代码块用于从 parent class 扩展静态属性。他们用Object.setPrototypeOf
改变了childclass的[[Prototype]]
。不要混淆 .prototype
和 [[Prototype]]
是完全不同的东西。
MDN 在其参考中关于使用 Object.setPrototypeOf
的内容如下:
Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine.
我的问题出现在这里:如果我们可以用另一种方式达到相同的结果,为什么 Babel 使用 Object.setPrototypeOf
?我试图通过循环构造函数 object.
...
var parentStaticProps = parentClass.prototype.constructor;
for (var prop in parentStaticProps) {
childClass.prototype.constructor[prop] = parentStaticProps[prop];
}
...
而且比babel的实现速度还快!我创建了一些类似于 babel 扩展 class 并在 jsPerf 中测试它的东西。
我的前 5 名测试 运行 结果非常令人失望 Object.setPrototypeOf
:慢 19%,慢 20%,慢三倍 21%。
我知道 Object.setPrototypeOf
可能需要使用肯定有一些原因。我想知道。如果是关于 non-enumerable 属性那么我们肯定可以使用一些其他方法。
If we can achieve the same result with another way why Babel uses
Object.setPrototypeOf
?
很简单,因为没有其他方法可以达到相同的结果。仅仅复制所有属性的当前值与从另一个对象动态继承是不同的。 Babel 的目标是正确,而不是快速。
And it is also faster than babel's implementation! I have created something similar what babel does to extend a class and tested it in jsPerf.
好吧,创建和扩展 类 是 慢,但这并不重要。 使用 那些 类 - 例如访问静态属性 - 是这里的重要方面。通常没有问题的是你改变一个新的(尚未使用的)对象的 [[prototype]] - 警告更关心在对象生命周期的中间进行突变。