Одно из рекомендуемых преимуществ jQuery.data по сравнению с необработанными свойствами expando (произвольные атрибуты, которые вы можете назначить узлам DOM) состоит в том, что jQuery.data является "безопасным от циклических ссылок и, следовательно, свободным от утечек памяти". Статья из Google под названием "Оптимизация кода JavaScript" приводится более подробно:
Наиболее распространенные утечки памяти для веб-приложений включают в себя круговые ссылки между движком JavaScript script и браузерами С++ объекты, реализующие DOM (например, между JavaScript scriptдвигателя и Internet Explorer COM, или между JavaScript-движок и инфраструктура Firefox XPCOM).
В нем перечислены два примера круговых эталонных шаблонов:
-
Элемент DOM → обработчик событий → область охвата → DOM
-
Элемент DOM → через expando → промежуточный объект → Элемент DOM
Однако, если опорный цикл между DOM node и объектом JavaScript вызывает утечку памяти, не означает ли это, что любой нетривиальный обработчик событий (например, onclick
) приведет к такой утечке? Я не вижу, как это возможно для обработчика событий, чтобы избежать эталонного цикла, потому что я его вижу:
-
Элемент DOM ссылается на обработчик событий.
-
Обработчик событий ссылается на DOM (прямо или косвенно). В любом случае почти невозможно избежать ссылки
window
в любом интересном обработчике событий, не записывая циклsetInterval
, который читает действия из глобальной очереди.
Может ли кто-то дать точное описание JavaScript & harr; DOM круговая справочная проблема? Что я хотел бы уточнить:
-
Какие браузеры выполняются? Комментарий в источнике jQuery специально упоминает IE6-7, но статья Google предполагает, что Firefox также затронут.
-
Являются ли свойства expando и обработчики событий как-то разными в отношении утечек памяти? Или оба эти фрагмента кода восприимчивы к утечке памяти такого же типа?
// Create an expando that references to its own element. var elem = document.getElementById('foo'); elem.myself = elem; // Create an event handler that references its own element. var elem = document.getElementById('foo'); elem.onclick = function() { elem.style.display = 'none'; };
-
Если страница теряет память из-за циклической ссылки, сохраняется ли утечка до закрытия всего приложения браузера или освобождается ли память при закрытии окна/вкладки?