11

我有一个 JavaScript 闭包,我会在我的 Web 应用程序的整个生命周期中不断重新创建它(单个完整的 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);

    }
}
4

2 回答 2

2

如果您确保避免clickRecreateLinks()函数中绑定多个处理程序,您应该没问题;这可以通过显式解除绑定现有节点、删除 DOM 节点或确保您不会添加多个click处理程序来完成。

浏览器在内存分配策略方面做得越来越好,但你不应该假设太多。如果内存使用是一个大问题,请尽量避免创建太多您不确定它们是否会被垃圾收集的闭包。一种这样的方法是用于.data()存储您的值对象,然后使用通用的单击处理程序而不是闭包。

分析 JavaScript 并不是那么简单;Chrome 确实有一个 Profile 工具,可以监控 CPU 和数据性能。这可以让您很好地衡量预期的内存消耗,但 Chrome 并不是所有的浏览器,请记住这一点。

于 2012-10-01T19:06:07.587 回答
1

根据浏览器的智能程度,最好在您的属性上添加“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(){...});

这将消除每次添加单个事件的需要。

于 2012-10-01T19:17:08.680 回答