Я искал исходный код my.class.js, чтобы узнать, что делает его таким быстро в Firefox. Здесь фрагмент кода, используемый для создания класса:
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);
};
Это все довольно просто. Когда вы создаете класс, он просто возвращает функцию-конструктор, которую вы предоставляете.
То, что бьет мое понимание, однако, как создать экземпляр этого конструктора выполнить быстрее, чем создавая экземпляр того же конструктора, написанного в Vapor.js.
Вот что я пытаюсь понять:
- Как конструкторы библиотек, такие как my.class.js, создают так много экземпляров так быстро в Firefox? Конструкторы библиотек очень похожи. Должно ли время выполнения быть аналогичным?
- Почему способ создания класса влияет на скорость выполнения экземпляра? Разве это не определение и создание отдельных процессов?
- Где my.class.js получает повышение этой скорости? Я не вижу никакой части кода конструктора, которая должна заставлять ее выполнять быстрее. Фактически, перемещение длинной прототипной цепи, например
MyFrenchGuy.Super.prototype.setAddress.call
, должно значительно замедлить ее. - Является ли функция конструктора составляющей JIT? Если да, то почему функции конструктора других библиотек также не скомпилированы JIT?