閉包會造成內存泄漏嗎? 不會!!!
發現網上一堆閉包的教程都說閉包會造成內存泄漏,特意去查了下書,發現這一直是一個誤解。
js高程原文這樣說的:由於IE9 之前的版本對JScript 對象和COM 對象使用不同的垃圾收集。因此閉包在IE 的這些版本中會導致一些特殊的問題。具體來說,如果閉包的作用域鏈中保存着一個HTML 元素,那么就意味着該元素將無法被銷毀。
意思就是閉包造成的內存泄漏是舊版本IE的bug,真正情況下的閉包不會造成內存泄漏。
下面是修復舊版本IE內存泄漏的方法:
function assignHandler(){ var element = document.getElementById("someElement"); element.onclick = function(){ alert(element.id); }; }
以上代碼創建了一個作為element 元素事件處理程序的閉包,而這個閉包則又創建了一個循環引用。由於匿名函數保存了一個對assignHandler()的活動對象的引用,因此就會導致無法減少element 的引用數。只要匿名函數存在,element 的引用數至少也是1,因此它所占用的內存就永遠不會被回收,這是IE的問題,所以閉包和內存泄漏沒半毛錢關系。
解決辦法前言已經提到過,把element.id 的一個副本保存在一個變量中,從而消除閉包中該變量的循環引用同時將element變量設為null。
function assignHandler(){ var element = document.getElementById("someElement"); var id = element.id; element.onclick = function(){ alert(id); }; element = null; }
總結:閉包並不會引起內存泄漏,只是由於IE9 之前的版本對JScript對象和COM對象使用不同的垃圾收集,從而導致內存無法進行回收。
使用閉包的注意點
1)由於閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。
2)閉包會在父函數外部,改變父函數內部變量的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變量的值。