Ответ 1
Из того, что я понимаю, управление памятью в javascript выполняется подсчетом ссылок - пока ссылка на объект все еще существует, он не будет освобожден. Это означает, что создание утечки памяти в одностраничном приложении является тривиальным и может отключать функции использования, исходящие из фона java. Это не относится к JQuery. Возьмите следующий код, например:
function MyObject = function(){
var _this = this;
this.count = 0;
this.getAndIncrement = function(){
_this.count++;
return _this.count;
}
}
for(var i = 0; i < 10000; i++){
var obj = new MyObject();
obj.getAndIncrement();
}
Это будет выглядеть нормально, пока вы не посмотрите на использование памяти. Экземпляры MyObject никогда не освобождаются, пока страница активна, из-за указателя "_this" (увеличьте максимальное значение i, чтобы увидеть его более резко). (В старых версиях IE они никогда не были освобождены до выхода программы.) Поскольку объекты javascript могут быть разделены между фреймами (я не рекомендую попробовать это, поскольку это серьезно темпераментно), бывают случаи, когда даже в современном браузере javascript объекты могут зависнуть намного дольше, чем они предназначены.
В контексте jquery ссылки часто сохраняются для сохранения накладных расходов на поиск dom - например:
function run(){
var domObjects = $(".myClass");
domObjects.click(function(){
domObjects.addClass(".myOtherClass");
});
}
Этот код будет храниться на domObject (и все его содержимое) навсегда, из-за ссылки на него в функции обратного вызова.
Если авторы jquery пропустили такие экземпляры, как это внутренне, тогда сама библиотека протекает, но чаще всего это код клиента.
Второй пример может быть исправлен путем явной очистки указателя, когда он больше не требуется:
function run(){
var domObjects = $(".myClass");
domObjects.click(function(){
if(domObjects){
domObjects.addClass(".myOtherClass");
domObjects = null;
}
});
}
или повторите поиск:
function run(){
$(".myClass").click(function(){
$(".myClass").addClass(".myOtherClass");
});
}
Хорошее эмпирическое правило заключается в том, чтобы быть осторожным, когда вы определяете свои функции обратного вызова и избегаете слишком большого количества гнездования, где это возможно.
Изменить: как было указано в комментариях Эрика, вы также можете использовать этот указатель, чтобы избежать поиска ненужного dom:
function run(){
$(".myClass").click(function(){
$(this).addClass(".myOtherClass");
});
}