我有一个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);
}
}
答案 0 :(得分:2)
如果您确保避免在click
函数中绑定多个RecreateLinks()
处理程序,那么您应该没问题。这可以通过显式解除现有的绑定,删除DOM节点或确保不添加多个click
处理程序来完成。
浏览器在内存分配策略上越来越好,但你不应该假设太多。如果内存使用是一个很大的问题,请尽量避免创建太多的闭包,而你不确定它们是否会收集垃圾。一种方法是使用.data()
来存储您的值对象,然后使用通用的单击处理程序而不是闭包。
分析JavaScript并不那么简单; Chrome确实有一个可以监控CPU和数据性能的配置文件工具。这可以很好地衡量预期的内存消耗量,但Chrome并不是所有浏览器,请记住这一点。
答案 1 :(得分:1)
根据浏览器的智能程度,将“myLinks [i] .value”作为<li>
上的属性而不是通过闭包传递可能会更好。当事件处理程序从其范围之外引用变量时,某些愚蠢的浏览器会收集垃圾。 JavaScript和DOM运行两个不同的GC,并且JS没有意识到DOM元素/ eventhandler已经消失,并且该变量不再使用。通过javascript正确删除事件处理程序而不是仅仅处理它所附加的元素,可以解决此问题。
类似于:
li.attr('lvalue',myLinks[i].value);
...
var value = $(this).attr('lvalue');
此设置还允许您使用
$('#links > ul > li').live('click',function(){...});
每次都不需要添加单个事件。