var n =123; // 为数字分配内存var s ='azerty'; // 为String分配内存var o = { a:1, b:null}; // 为对象分配内存// 为数组分配内存var a = [1,null,'abra']; functionf(a) {return a +2;} // 为函数分配内存
通过函数调用分配内存空间:
var d =newDate(); // 通过new分配date对象var e =document.createElement('div'); // 分配一个DOM对象var s ='azerty';var s2 =s.substr(0,3); // 因为js中字符串是不可变的,所以substr的操作将会创建新的字符串var a = ['ouais ouais','nan nan'];var a2 = ['generation','nan nan'];var a3 =a.concat(a2); // 同样的,concat操作也会创建新的字符串
var div;window.onload=function() { div =document.getElementById('myDivElement');div.circularReference = div;div.lotsOfData =newArray(10000).join('*');};
<html> <body> <scripttype="text/javascript">document.write("Program to illustrate memory leak via closure");window.onload=functionouterFunction(){var obj =document.getElementById("element");obj.onclick=functioninnerFunction(){alert("Hi! I will leak"); };obj.bigString=newArray(1000).join(newArray(2000).join("XXXXX"));// This is used to make the leak significant }; </script> <buttonid="element">Click Me</button> </body> </html>
上面的例子中,obj引用了 DOM 对象element,而element的onclick是outerFunction的内部函数,从而导致了对外部函数的引用,从而引用了obj。
这样最终导致循环引用,造成内存泄露。
怎么解决这个问题呢?
一个简单的办法就是在使用完obj之后,将其赋值为null,从而中断循环引用的关系:
<html> <body> <scripttype="text/javascript">document.write("Avoiding memory leak via closure by breaking the circular reference");window.onload=functionouterFunction(){var obj =document.getElementById("element");obj.onclick=functioninnerFunction() {alert("Hi! I have avoided the leak");// Some logic here };obj.bigString=newArray(1000).join(newArray(2000).join("XXXXX")); obj =null; //This breaks the circular reference };</script> <buttonid="element">"Click Here"</button></body></html>
还有一种很简洁的办法就是不要使用闭包,将其分成两个独立的函数:
<html> <head> <scripttype="text/javascript">document.write("Avoid leaks by avoiding closures!");window.onload=function() {var obj =document.getElementById("element");obj.onclick = doesNotLeak; }functiondoesNotLeak() {//Your Logic herealert("Hi! I have avoided the leak"); } </script> </head> <body> <buttonid="element">"Click Here"</button> </body> </html>