閉包(Closure)的細節(三):閉包與記憶體洩漏
- 詳細內容
- 分類:Javascript
- 發佈:2013-07-08, 週一 05:15
- 點擊數:2223
閉包(Closure)的細節(三),閉包與記憶體洩漏:
所謂的記憶體洩漏指的是一些無法被釋放掉的記憶體。而這裡要討論的是早期IE的記憶體洩漏問題。雖然稱之為早期,但不得不承認早期IE的餘毒威力猶存,很多人依然在使用早期的IE,因此還是有了解的必要。
早期的IE很容易造成記憶體洩漏的情形,原因是因為IE對於DOM物件有自己的處理模式。當Javascript物件與DOM物件循環參考時,就會造成記憶體洩漏的問題。因為IE無法回收這樣的記憶體。下面是來自MDN的例子:
function leakMemory() { var el = document.getElementById('el'); var o = { 'el': el }; el.o = o; }
物件o的el屬性參考了el物件,而el物件的o屬性參考了o物件。很明顯el物件是個DOM物件,而Javascript物件與DOM物件的循環參考造成了IE瀏覽器無法回收這些記憶體,因此形成了記憶體洩漏的問題。這程式碼其實很明顯很容易看出循環參考的問題,但是如果循環參考隱藏在閉包之中則很不容易發現:
function addHandler() { var el = document.getElementById('el'); el.onclick = function() { this.style.backgroundColor = 'red'; } //el=null; }
看起來完全沒有循環參考的問題,但實際上呢?el物件的屬性參考到了一個函式,很不幸的是這函式其實擁有存取el物件的能力。因此循環參考就此形成。要破壞這種記憶體洩漏其實不難,上例程式碼中的el=null就足以達成這目的,當然也可以在一開始就不使用el變數:
function addHandler(){ document.getElementById('el').onclick = function(){ this.style.backgroundColor = 'red'; } }
另外的方法就是使用額外的閉包:
function addHandler() { var clickHandler = function() { this.style.backgroundColor = 'red'; }; (function() { var el = document.getElementById('el'); el.onclick = clickHandler; })(); }
記憶體洩漏的問題通常不大,除非你大量的洩漏記憶體。不過不管如何,當瀏覽器被關閉時,這類的記憶體洩漏都會被釋放掉。
按個讚!~支持本站!~
FB推薦載入中