閉包會造成內存泄漏問題嗎?


閉包會造成內存泄漏嗎? 不會!!!

發現網上一堆閉包的教程都說閉包會造成內存泄漏,特意去查了下書,發現這一直是一個誤解。

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),這時一定要小心,不要隨便改變父函數內部變量的值。

參考:學習Javascript閉包(Closure)- 阮一峰


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM