带你走进JavaScript世界系列——内存泄漏

在之前的内容中我们介绍垃圾收集的过程,由于 IE9 之前版本对JScript 和 COM 对象使用不同的垃圾回收机制,因此闭包在 IE 的这些版本中会导致一些特殊的问题。具体来说,如果闭包的作用域链中保存着一个 HTML 元素,那么这个元素将无法被销毁。例:

带你走进JavaScript世界系列——内存泄漏

闭包的内存泄漏问题

上面的代码创建了一个作为 element 元素事件处理程序闭包,而这个闭包又创建了一个循环引用。由于匿名函数保存了一个对 assignHandler() 的活动对象的引用,因此就会导致无法减少 element 的引用数。只要匿名函数存在,element 的引用数至少是 1 ,因此它所占用的内存就永远不会被回收。不过,可以通过下面的方式来解决这个问题:

带你走进JavaScript世界系列——内存泄漏

解决上面闭包内存泄漏问题

上面的代码通过 把 element.id 保存到在一个变量中,并且在闭包中引用这个变量消除了循环引用。但仅仅这样是不行的,闭包会引用包含函数的整个活动对象,而其中包含这 element 对象。即使闭包不直接引用 element ,包含函数的活动对象中也仍然会保存一个引用,因此必须把 element 变量设置为 null ,这样才能够解除对 DOM 对象的引用,确保正常回收其占用的内存。