我应该在什么时候或在什么条件下取消jQuery中的对象



我正在开发一个大量使用Javascript的项目,其中包括大量DOM操作。随着代码的增长,我注意到在InternetExplorer(9)下,页面加载时有时会延迟Javasript执行(约1-2秒)。这种延迟从未在Firefox上发生过。

例如:

// the actual code contains much more stuff
$("body").append("<p>paragraph</p>");

尽管p是动态生成的,但它应该在现代浏览器上的页面加载之后立即显示。但在IE上,有时我可以清楚地看到,在所有静态内容加载之后,p被添加了,这让整个页面变得跳跃。

如果我重新启动IE,延迟就消失了。然而,如果已经进行了大量的DOM操作,则在下一次页面刷新时会再次出现这种情况。

所以我想如果这是由memory leak引起的,因为我很少取消对象引用。

var foo = $("#foo");
foo.on("click", function() {
    var bar = '<div id="bar">bar</div>';
    $("body").append(bar);
    // nullify bar
    bar = null;
});
// nullify foo
foo = null;

问题:

  1. 每个对象引用都像上面的例子一样被使用时,我应该取消它们吗?

  2. 如果Q1的答案是否定的,我应该在什么时候或在什么条件下取消对象引用?

  3. 除了无效之外,我还能做些什么来防止内存泄漏?

附言:几年前我读过一些类似的问题,它们大多是针对IE 6/7的。

当每个对象引用都像上面的例子一样被使用时,我应该取消它们吗?

不,那太夸张了。

如果Q1的答案是否定的,我应该在什么时候或在什么条件下取消对象引用?

当你不再需要它,但它在静物功能的范围内时。在您的示例中,foo可以从单击处理程序中引用,因此只要处理程序附加到DOM,它就不会被垃圾收集。然而,没有理由取消bar

除了无效之外,我还能做些什么来防止内存泄漏?

  • 根本不要使用变量。在您的示例中,您可以简单地使用链接:$("#foo").on(…);
  • 如果处理程序函数与使用它们的执行上下文无关,请在不同的作用域中声明它们:
$(document).ready(function() {
    var foo = $("#foo");
    foo.on("click", showBar);
    // do anything else with `foo`
});
function showBar() {
    var bar = '<div id="bar">bar</div>';
    $("body").append(bar);
});

几年前我读过一些类似的问题,它们大多是针对IE 6/7的。

这是因为IE6/7的垃圾收集器中有一些错误(javascript、循环引用和内存泄漏、MSDN文章)。然而,上面提到的技术与此无关,它们假设GC正确工作。通过优化GC,它们甚至可能不需要,例如V8确实收集了实际在范围内但不会再次使用的变量(调试揭示模块模式:函数在调用之前不在范围内?)。

最新更新