Одно из разрекламированных преимуществ jQuery.dataпо сравнению с необработанными свойствами расширения (произвольные атрибуты, которые вы можете назначать узлам DOM) это jQuery.data«защищен от циклических ссылок и, следовательно, не имеет утечек памяти». В статье Google под названием «Оптимизация кода JavaScript»приводится более подробная информация:
Наиболее распространенные утечки памяти для веб-приложений связаны с циклическим ссылки между механизмом сценариев JavaScript и C++ браузеров. объекты, реализующие DOM (например, между сценарием JavaScript движок и COM-инфраструктура Internet Explorer, или между Движок JavaScript и инфраструктура Firefox XPCOM).
В нем перечислены два примера шаблонов циклических ссылок:
Элемент DOM → обработчик событий → область замыкания → DOM
Элемент DOM → via Expando → промежуточный объект → элемент DOM
Однако, если цикл ссылок между Узел DOM и объект JavaScript вызывают утечку памяти, не означает ли это, что любой нетривиальный обработчик событий (например, onclick
) приведет к такой утечке? Я не понимаю, как обработчик событий вообще может избежать цикла ссылок, потому что я это вижу следующим образом:
Элемент DOM ссылается на обработчик событий.
Обработчик событий ссылается на DOM (прямо или косвенно). В любом случае почти невозможно избежать ссылки window
в любом интересном обработчике событий, за исключением написания цикла setInterval
, который считывает действия из глобальной очереди.
Может ли кто-нибудь дать точное объяснение проблемы циклической ссылки JavaScript ↔ DOM? Вещи, которые я хотел бы уточнить:
Какие браузеры действуют? В комментарии к источнику jQuery конкретно упоминается IE6-7, но в статье Google предполагается, что Firefox также затронут.
Отличаются ли свойства Expando и обработчики событий в отношении утечек памяти? Или оба этих фрагмента кода подвержены утечке памяти одного и того же типа?
// Создаем расширение, которое ссылается на собственный элемент.
var elem = document.getElementById('foo');
элемент.моя = элемент;
// Создаем обработчик событий, который ссылается на свой собственный элемент.
var elem = document.getElementById('foo');
элемент.onclick = функция () {
elem.style.display = 'нет';
};
Если на странице происходит утечка памяти из-за циклической ссылки, сохраняется ли утечка до тех пор, пока не будет закрыто все приложение браузера, или память освобождается при закрытии окна/вкладки?