【发布时间】:2013-01-08 10:38:20
【问题描述】:
我一直在查看 my.class.js 的源代码,以了解是什么使它在 Firefox 上如此 fast。这是用于创建类的代码的 sn-p:
my.Class = function () {
var len = arguments.length;
var body = arguments[len - 1];
var SuperClass = len > 1 ? arguments[0] : null;
var hasImplementClasses = len > 2;
var Class, SuperClassEmpty;
if (body.constructor === Object) {
Class = function () {};
} else {
Class = body.constructor;
delete body.constructor;
}
if (SuperClass) {
SuperClassEmpty = function() {};
SuperClassEmpty.prototype = SuperClass.prototype;
Class.prototype = new SuperClassEmpty();
Class.prototype.constructor = Class;
Class.Super = SuperClass;
extend(Class, SuperClass, false);
}
if (hasImplementClasses)
for (var i = 1; i < len - 1; i++)
extend(Class.prototype, arguments[i].prototype, false);
extendClass(Class, body);
return Class;
};
extend 函数仅用于将第二个对象的属性复制到第一个对象上(可选择覆盖现有属性):
var extend = function (obj, extension, override) {
var prop;
if (override === false) {
for (prop in extension)
if (!(prop in obj))
obj[prop] = extension[prop];
} else {
for (prop in extension)
obj[prop] = extension[prop];
if (extension.toString !== Object.prototype.toString)
obj.toString = extension.toString;
}
};
extendClass 函数将所有静态属性复制到类中,以及将所有公共属性复制到类的原型中:
var extendClass = my.extendClass = function (Class, extension, override) {
if (extension.STATIC) {
extend(Class, extension.STATIC, override);
delete extension.STATIC;
}
extend(Class.prototype, extension, override);
};
这一切都很简单。当你创建一个类时,它只是返回你提供给它的构造函数。
然而,让我无法理解的是,创建此构造函数的实例 execute faster 与创建用 Vapor.js 编写的相同构造函数的实例相比如何。
这就是我想要理解的:
- 像 my.class.js 这样的库的构造函数如何在 Firefox 上如此快速地创建这么多实例?库的构造函数都非常相似。执行时间不应该也差不多吧?
- 为什么类的创建方式会影响实例化的执行速度?定义和实例化不是分开的过程吗?
- my.class.js 从哪里获得这种速度提升?我没有看到构造函数代码的任何部分应该使它执行得更快。事实上,遍历像
MyFrenchGuy.Super.prototype.setAddress.call这样的长原型链应该会显着减慢速度。 - 构造函数是否被 JIT 编译?如果是这样,那么为什么其他库的构造函数也不被 JIT 编译?
【问题讨论】:
-
导致 my.class.js 更快的一个方面是扩展函数不执行
hasOwnProperty检查。 --- 但是当您考虑到它每秒执行数百万次操作的事实时,jsperf 测试中快速执行库之间的差异很小。如果您创建了这么多对象实例,那么您已经遇到了与内存占用和垃圾收集有关的其他问题。
标签: javascript oop instantiation jsperf