Подтвердить что ты не робот

Я создаю утечку памяти?

У меня есть закрытие JavaScript, которое я продолжаю воссоздавать на протяжении всего жизненного цикла своего веб-приложения (одна полная страница ajax).

Я хотел бы знать, создает ли это утечку памяти.

Вот пример JSFIDDLE

Код, о котором идет речь:

function CreateLinks() {

    var ul = $("<ul></ul>").appendTo('div#links');

    for (var i in myLinks) {

        var li = $('<li>' + myLinks[i].name + '</li>').appendTo(ul);

        //closure starts here
        (function (value) {
            li.click(function (e) {
                $('div#info').append('<label>' + value + '</label><br />');
                RecreateLinks();
            });
        })(myLinks[i].value);

    }
}
4b9b3361

Ответ 1

Вы должны быть в порядке, если вы убедитесь, что избегаете связывания нескольких обработчиков click в функции RecreateLinks(); это может быть сделано путем явного развязывания существующих, удаления узлов DOM или обеспечения того, что вы не будете добавлять несколько обработчиков click.

Браузеры улучшают стратегии распределения памяти, но вы не должны слишком много думать. Если использование памяти вызывает большую озабоченность, постарайтесь не создавать слишком много закрытий, из которых вы не уверены, что они получат сбор мусора. Одним из таких подходов является использование .data() для хранения объекта значения, а затем использование общего обработчика кликов вместо закрытия.

Профайлинг JavaScript не так прост; У Chrome есть инструмент Profile, который может контролировать производительность процессора и данных. Это может дать вам неплохую оценку ожидаемого объема памяти, но Chrome не все браузеры, помните об этом.

Ответ 2

В зависимости от того, насколько интеллектуальным является браузер, может быть лучше иметь "myLinks [i].value" атрибут на вашем <li>, а не передавать через закрытие. У некоторых немых браузеров есть проблемы с сбором мусора, когда обработчик событий ссылается на переменную из-за пределов ее области. JavaScript и DOM запускают два разных GC, а JS не понимает, что элемент DOM/обработчик событий исчез, и эта переменная больше не используется. Эта проблема может быть устранена путем правильного удаления обработчика событий с помощью javascript, а не просто удаления элемента, к которому он присоединен.

Что-то похожее на:

li.attr('lvalue',myLinks[i].value);
...
var value = $(this).attr('lvalue');

Эта настройка также позволит вам использовать

$('#links > ul > li').live('click',function(){...});

Это избавит вас от необходимости добавлять отдельные события каждый раз.