還有這個(gè)例子在IE 6中同樣原因會(huì)引起泄露
function leakmaybe() { var elm = document.createElement("DIV"); elm.onclick = function(){ return 2 + 2 ; } } for( var i = 0 ;i < 10000;i ++){ leakmaybe(); }
關(guān)于Closure的知識(shí),大家可以看看 這篇文章 ,習(xí)慣中文也可以看看zkjbeyond的blog,他對(duì)Closure 這篇文章進(jìn)行了 簡(jiǎn)要的翻譯 。之所以會(huì)有這一系列的問題,關(guān)鍵就在于javascript是種函數(shù)式腳本解析語言,因此javascript中“函數(shù)中的變量的作用域是定義作用域,而不是動(dòng)態(tài)作用域”,這點(diǎn)在犀牛書《JavaScript: The Definitive Guide》中的“Funtion”一章中有所討論。
http://support.microsoft.com/default.aspx?scid=KB;EN-US;830555中也對(duì)這個(gè)問題舉了很詳細(xì)的例子。
一些簡(jiǎn)單的解決方案
目前大多數(shù)ajax前端的javascript framework都利用對(duì)事件的管理,解決了該問題。
如果你需要自己解決這個(gè)問題,可以參考以下的一些方法:
http://outofhanwell.com/ieleak/index.php?title=Main_Page:有個(gè)不錯(cuò)的檢測(cè)工具
http://youngpup.net/2005/0221010713 中提到:可以利用遞歸Dom樹,解除event綁定,從而解除循環(huán)引用:
if (window.attachEvent){ var clearElementProps = ['data','onmouseover','onmouseout','onmousedown','onmouseup', 'ondblclick','onclick','onselectstart','oncontextmenu']; window.attachEvent("onunload", function(){ var el; for(var d = document.all.length;d--;){ el = document.all[d]; for(var c = clearElementProps.length;c--;){ el[clearElementProps[c]] = null; } } } ); }
而http://novemberborn.net/javascript/event-cache一文中則通過增加EventCache,從而給出一個(gè)相對(duì)結(jié)構(gòu)化的解決方案
/* EventCache Version 1.0 Copyright 2005 Mark Wubben Provides a way for automagically removing events from nodes and thus preventing memory leakage. See <http://novemberborn.net/javascript/event-cache> for more information. This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/> */ /* Implement array.push for browsers which don't support it natively. Please remove this if it's already in other code */ if (Array.prototype.push == null ){ Array.prototype.push = function (){ for (var i = 0;i<arguments.length;i ++){ this[this.length] = arguments[i]; }; return this.length; }; }; /* Event Cache uses an anonymous function to create a hidden scope chain. This is to prevent scoping issues. */ var EventCache = function (){ var listEvents=[]; return{ listEvents : listEvents, add: function(node, sEventName, fHandler, bCapture){ listEvents.push(arguments); }, flush: function (){ var i,item; for (i = listEvents.length-1;i>=0;i=i-1 ){ item=listEvents[i]; if(item[0].removeEventListener){ item[0].removeEventListener(item[1],item[2],item[3]); }; /* From this point on we need the event names to be prefixed with 'on" */ if(item[1].substring(0, 2)!="on" ){ item[1]="on"+item[1]; }; if(item[0].detachEvent){ item[0].detachEvent(item[1], item[2]); }; item[0][item[1]]=null; }; } }; }();
使用方法也很簡(jiǎn)單:
<script type="text/javascript"> function addEvent(oEventTarget,sEventType,fDest){ if(oEventTarget.attachEvent){ oEventTarget.attachEvent("on" + sEventType, fDest); } elseif(oEventTarget.addEventListener){ oEventTarget.addEventListener(sEventType, fDest, true); } elseif(typeof oEventTarget[sEventType]=="function"){ var fOld = oEventTarget[sEventType]; oEventTarget[sEventType] = function(e){ fOld(e); fDest(e); }; } else { oEventTarget[sEventType] = fDest; }; /* Implementing EventCache for all event systems */ EventCache.add(oEventTarget, sEventType, fDest, true);}; function createLeak(){ var body = document.body; function someHandler(){ return body; }; addEvent(body, "click", someHandler); }; window.onload = function(){ var i = 500; while(i > 0){ createLeak(); i = i - 1; } }; window.onunload = EventCache.flush; </script>
出處:藍(lán)色理想
責(zé)任編輯:bluehearts
上一頁 關(guān)于Javascript的內(nèi)存泄漏問題 [1] 下一頁 關(guān)于Javascript的內(nèi)存泄漏問題 [3]
◎進(jìn)入論壇網(wǎng)頁制作、WEB標(biāo)準(zhǔn)化版塊參加討論,我還想發(fā)表評(píng)論。
|