Я внесу здесь один антишаблон, который представляет собой утечку «средней цепи».
Одной из сильных сторон jQuery является его API цепочки, который позволяет вам продолжать изменять, фильтровать и манипулироватьэлементы:
$(".message").addClass("unread").find(".author").addClass("noob");
В конце этой цепочки у вас есть объект jQuery со всеми элементами ".message .author", но , на который ссылается объект , и объект соригинальные элементы ".message".Вы можете получить к ним метод .end()
и что-то с ними сделать:
$(".message")
.find(".author")
.addClass("prolific")
.end()
.addClass("unread");
Теперь при использовании этого способа проблем с утечками нет.Однако, если вы присваиваете результат цепочки переменной, имеющей длительный срок службы, обратные ссылки на более ранние наборы сохраняются и не могут быть собраны сборщиком мусора, пока переменная не выйдет из области видимости.Если эта переменная является глобальной, ссылки никогда не выходят за рамки.
Так, например, предположим, что вы прочитали в каком-то посте в блоге 2008 года, что $("a").find("b")
был "более эффективным", чем $("a b")
(хотя егоне стоит даже думать о такой микрооптимизации).Вы решаете, что вам нужен глобальный элемент для хранения списка авторов, поэтому вы делаете это:
authors = $(".message").find(".author");
Теперь у вас есть объект jQuery со списком авторов, но он также ссылается на jQueryобъект, который является полным списком сообщений.Вы, вероятно, никогда не будете использовать его или даже будете знать, что он там, и он занимает память.
Обратите внимание, что утечки могут происходить только с методами, которые выбирают новые элементы из существующего набора, такие как.find
, .filter
, .children
и т. Д. Документы указывают, когда возвращается новый набор.Простое использование API цепочки не приводит к утечке, если цепочка имеет простые нефильтрующие методы, такие как .css
, так что все в порядке:
authors = $(".message .author").addClass("prolific");