1. Допустим, мы на определенные ссылки хотим добавлять аргумент, который будет предаваться на сервер, и который непостоянный и вычисляется определенным образом на странице (в нашем примере он будет статическим;)):
Вот оптимальный вариант:
2. Почему все-таки сейчас преобладает создание имитации классов с определением методов не в обьекте(определение в конструкторе в момент его выполнения), а в его прототипе? Ответ станет очевиден если посмотреть на первый пример, помня о предыдущем примере:
var quantaty = 5;
function addGlobalQueryOnClick(linkRef){
if(linkRef){
linkRef.onclick = function(){
this.href += ('?quantaty='+escape(quantaty));
return true;
};
}
}
Не достаток такого подхода вот в чем. Каждый раз когда мы вызываем эту функцию, то внутри создается НОВАЯ анонимная, которая подхватывает для себя еще и замыкание. Если функция
addGlobalQueryOnClick
будет достаточно много раз вызвана на странице, то будет задействовано кучу лишних ресурсов - созданных анонимных обработчиков и их замыканий со ссылками на свою линку.
Фцнкция же обрабочик события ни чем не отличается для каждой из ссылки, поэтому будет хорошо, если все они будут использовать ее одну, да еще и без существования ненужного замыкания.Вот оптимальный вариант:
var quantaty = 5;
function addGlobalQueryOnClick(linkRef){
if(linkRef){
linkRef.onclick = forAddQueryOnClick;
}
}
function forAddQueryOnClick(){
this.href += ('?quantaty='+escape(quantaty));
return true;
}
2. Почему все-таки сейчас преобладает создание имитации классов с определением методов не в обьекте(определение в конструкторе в момент его выполнения), а в его прототипе? Ответ станет очевиден если посмотреть на первый пример, помня о предыдущем примере:
function ExampleClass(param){
this.method1 = function(){
... // method body.
};
this.method2 = function(){
... // method body.
};
this.method3 = function(){
... // method body.
};
this.publicProp = param;
}
Как мы видим созданется каждый раз при создании обьекта еще и новые обьекты-функций для него, а это вообщето расточительство, и кроме того контекст выполнения конструктора каждый раз сохраняется в замыканиях созданных для каждого метода.
Вот же обьекты-функции(методы) создаются только один раз и размещаются в свойстве контуктора prototype, а все созданные им инстанции получают ссылки на эти обьекты-методы, и их замыкания просто хранят ссылки на глобальный контекст иполнения:
function ExampleConst(param){
this.publicProp = param;
}
ExampleConst.prototype.method1 = function(){
... // method body.
};
ExampleConst.prototype.method2 = function(){
... // method body.
};
ExampleConst.prototype.method3 = function(){
... // method body.
};
3. Циклическая ссылка приводит к утечкам памяти:
Ой!:
function foo(element, a, b) {
element.onclick = function() { /* uses a and b */ };
}
Наша аннонимная функция в своем замыкании хранит ссылки на element( при этом эта переменная даже может и не использоваться в теле функции), на a и на b
Другое дело!:
function foo(element, a, b) {
element.onclick = bar(a, b);
}
function bar(a, b) {
return function() { /* uses a and b */ }
}
Комментариев нет:
Отправить комментарий