即使在删除绑定到的DOM元素之后,内存中是否存在javascript事件处理程序?

Kap*_*ers 18 javascript jquery memory-leaks

给出以下代码

<div id="app">
  <div id="foo" />
</div>

<script>
  $('#foo').bind('click', function(){});
</script>
Run Code Online (Sandbox Code Playgroud)

我计划更换#app [eg $('#app').html('...');,or innerHTML = '...';]的内容.我知道我可以使用jQuery .remove()来调用'destroy'解除事件的处理程序.事实上,有一个destroy处理程序设置为删除事件使我相信,如果不解除事件的绑定,当删除DOM元素时,处理程序仍将存在于内存中.

因此,如果DOM元素#foo不再存在,那么处理程序是否也会消失,或者它是否会在浏览器内存中丢失?

T.J*_*der 15

jQuery跟踪事件处理程序本身,这是你需要使用unbind (现在它off)的一部分,如果你不是通过jQuery方法从DOM中删除元素(如果你使用jQuery,empty或者remove,如你所提到的那样处理它本身) inernally).这是jQuery知道它可以释放它对处理程序的引用.

如果不是那样,那么从理论上讲,你不必做任何事情,因为一旦从内存中删除了DOM元素,就不再可以访问它,因此理论上不应该将事件处理程序保留在内存中.这就是理论.现实是非常不同的,它可以很容易地结束一种情况(特别是在IE上),DOM元素事件处理程序都不能被清理,因为它们各自导致另一个 - 内存泄漏.JavaScript对循环引用没有任何问题(它理解它们并且可以释放两个指向彼此的东西,只要没有其他东西指向它们),但浏览器的DOM部分很可能用不同的语言编写一个不同的垃圾收集机制(IE使用COM,它使用引用计数而不是可达性).jQuery可以帮助你避免IE的这个陷阱(它跟踪事件处理程序的部分原因),但你必须使用unbind (现在off)(或者通过empty,删除元素remove等).

带走的消息:当你挂钩时,你也应该解开.:-)(和/或在删除元素时使用jQuery,因为它会处理这个.)

有点相关:如果你要添加和删除很多元素,你可能会看看事件委托(通过委托签名使jQuery变得非常简单on)可能有所帮助.


Kap*_*ers 5

刚碰巧阅读了关于jQuery empty()方法的文档:

为了避免内存泄漏,jQuery在删除元素本身之前从子元素中删除了其他构造,如数据和事件处理程序.