Web前端处理内存泄漏:
1.意外的全局变量
JS 在处理未声明的变量时,对未声明的变量的引用会在全局对象内创建一个新变量。这些全局变量是无法进行垃圾回收的(除非将它们赋值为 null 或重新进行分配),所以对于存储大量数据的全局变量,确保在使用完之后,对其赋值为 null 或者重新分配:
function leak(){
leak="xxx";//leak成为一个全局变量,不会被回收
}
2.被遗忘的定时器(Timers)或者回调函数(callback)
var someResouce=getData();
setInterval(function(){
var node=document.getElementById('Node');
if(node){
node.innerHTML=JSON.stringify(someResouce)
}
},1000)
// 如果 id 为 Node 的元素从 DOM 中移除, 该定时器仍会存在,
3,闭包函数
function bindEvent(){
var obj=document.createElement("XXX");
obj.onclick=function(){
//Even if it's a empty function
}
}
闭包可以维持函数内局部变量,使其得不到释放。 上例定义事件回调时,由于是函数内定义函数,并且内部函数–事件回调的引用外暴了,形成了闭包。解决之道,将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中,删除对dom的引用
//将事件处理函数定义在外部
function onclickHandler(){
//do something
}
function bindEvent(){
var obj=document.createElement("XXX");
obj.onclick=onclickHandler;
}
function bindEvent(){
var obj=document.createElement("XXX");
obj.onclick=function(){
//Even if it's a empty function
}
obj=null;
}
4.没有清理的DOM元素的引用:
var elements={ button: document.getElementById("button"),
image: document.getElementById("image"),
text: document.getElementById("text")
};
function doStuff(){
image.src="http://some.url/image";
button.click():
console.log(text.innerHTML)
}
function removeButton(){
document.body.removeChild(document.getElementById('button'))
}