function attachEvents() {
var element = document.getElementById("myID");
element.onclick = function() {
alert("Element clicked");
}
};
attachEvents();
function attachEvents() {
var element = document.getElementById("myID");
element.onclick = function() {
alert("Element clicked");
}
};
attachEvents();
好久没有研究内存泄漏的课题了。姑且猜猜吧。
attachEvents 原本是一次性执行结束的,但其中包含了一个匿名的函数——那个监听器,结果它就被这个监听器“绑架”了(不能安心地驾鹤西去)。
而监听器又被绑定给了element对应的DOM对象。DOM对象只要还在网页中,那么就一直有效。
但我不太清楚:
内存泄漏是closure的原因造成的。闭包是由函数和构建函数的环境所组成的。 按理说,函数运行完成后,内部变量会被销毁。但是看这段代码,attachEvent函数内部返回了click函数,构造了一个闭包,这就导致了element变量会被onclick函数所引用。因此javascript垃圾回收器并不会回收element变量。 除了element=null的方法外,还可以把函数写在外面来避免。
function attachEvent()
{
var obj = document.getElementById("XXX");
obj.onclick=onclickHandler;
}
function onclickHandler(){
//do something
}
8 回答4.7k 阅读✓ 已解决
6 回答3.4k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
5 回答6.3k 阅读✓ 已解决
4 回答2.2k 阅读✓ 已解决
4 回答2.8k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
该代码创建了一个引用循环。
变量元素包含函数的引用(归于
onclick
属性)。 同时,函数保持一个 DOM 元素的引用(提示:函数内部可以访问元素,因为闭包)。所以 JavaScript 垃圾收集器不能清除元素或是函数,因为他们被相互引用。 大部分的 JavaScript 引擎对于清除循环应用都不够聪明。
解决办法:避免那些闭包,或者不去做函数内的循环引用。
谢谢 @沙之守护 的提醒,原文有误:delete 不能够删除变量,参见我在 sf 发表的博文 javascript 中的 delete,应该写
element = null
。TODO:明天继续更新……
参考:http://justjavac.com/named-function-expressions-demystified.html#jscript-memory-management