Я прочитал здесь (Дуглас Крокфорд) , используя оператор-прототип для добавления методов в классы Javascript , экономит также память .
Затем я прочитал в эту статью Джона Резига «Создание функции со множеством свойств прототипа - очень, очень, быстро » , но он говорит об использовании прототипа стандартным способом, или он говорит о своем конкретном примере в своей статье?
Например, создает ли этот объект:
function Class1()
{
this.showMsg = function(string) { alert(string); }
}
var c = new Class1();
c.showMsg();
медленнее, чем создание этого объекта, тогда?
function Class1() {}
Class1.prototype.showMsg = function(string) { alert(string); }
var c = new Class1();
c.showMsg();
PS
Я знаю, что прототип используется для создания объекта наследования, одноэлементного объекта и т. Д. Но этот вопрос не имеет ничего общего с этими субъектами.
РЕДАКТИРОВАТЬ: кому он также может быть интересен для сравнения производительности между JS object и JS static objet могут прочитать этот ответ ниже . Статические объекты определенно быстрее , очевидно, их можно использовать только тогда, когда вам не нужно более одного экземпляра объекта.
Это был интересный вопрос, поэтому я провел несколько очень простых тестов (мне следовало перезапустить браузеры, чтобы очистить память, но я этого не сделал; считайте, что это того стоит). Похоже, что по крайней мере в Safari и Firefox prototype
работает значительно быстрее [edit: не в 20 раз, как говорилось ранее]. Я уверен, что реальный тест с полнофункциональными объектами был бы лучшим сравнением. Код, который я прогнал, выглядел так (я прогнал тесты несколько раз, по отдельности):
var X,Y, x,y, i, intNow;
X = function() {};
X.prototype.message = function(s) { var mymessage = s + "";}
X.prototype.addition = function(i,j) { return (i *2 + j * 2) / 2; }
Y = function() {
this.message = function(s) { var mymessage = s + "";}
this.addition = function(i,j) { return (i *2 + j * 2) / 2; }
};
intNow = (new Date()).getTime();
for (i = 0; i < 1000000; i++) {
y = new Y();
y.message('hi');
y.addition(i,2)
}
console.log((new Date()).getTime() - intNow); //FF=5206ms; Safari=1554
intNow = (new Date()).getTime();
for (i = 0; i < 1000000; i++) {
x = new X();
x.message('hi');
x.addition(i,2)
}
console.log((new Date()).getTime() - intNow);//FF=3894ms;Safari=606
Это очень обидно, потому что я действительно ненавижу использовать prototype
. Мне нравится, когда мой объектный код самоинкапсулируется, и ему не дают дрейфовать. Однако, когда важна скорость, у меня нет выбора. Черт.
[Edit] Большое спасибо @Kevin, который указал, что мой предыдущий код был неправильным, что дало огромный толчок к заявленной скорости метода prototype
. После исправления прототип по-прежнему работает значительно быстрее, но разница уже не такая огромная.
Я уверен, что создание экземпляра объекта намного быстрее и потребляет меньше памяти, в этом нет никаких сомнений, но я бы подумал, что движку javascript нужно перебрать все свойства объекта, чтобы определить, является ли вызываемое свойство / метод частью этого объекта, а если нет, то проверьте прототип. Я не уверен в этом на 100%, но предполагаю, как это работает, и если да, то в НЕКОТОРЫХ случаях, когда к вашему объекту добавлено МНОГО методов, созданных только один раз и интенсивно используемых, тогда это может быть немного медленнее, но это всего лишь предположение, что я ничего не тестировал.
Но, в конце концов, я все же согласен с тем, что, как правило, использование прототипа будет быстрее.
Интуитивно кажется, что было бы более эффективно с точки зрения памяти и быстрее создавать функции на прототипе: функция создается только один раз, не каждый раз, когда создается новый экземпляр.
Однако будет небольшая разница в производительности, когда придет время получить доступ к функции. При ссылке на c.showMsg
среда выполнения JavaScript сначала проверяет свойство на c
. Если он не найден, проверяется прототип c
.
Таким образом, создание свойства в экземпляре приведет к несколько более быстрому доступу, но это может быть проблемой только для очень глубокой иерархии прототипов.