js--閉包

weixin_33807284發表於2017-03-22
  • 當在函式內部定義了其他函式時,就建立了閉包。

  • 在後臺執行環境中,閉包的作用域鏈包含著它自己的作用域、外部函式的作用域和全域性作用域。

  • 通常,函式的作用域及其所有變數都會在函式執行結束後被銷燬。

  • 所以,建立並立即呼叫一個函式,既可以執行其中的程式碼,又不會在記憶體中留下對該函式的引用。

  • 但是,當函式返回一個閉包時,這個函式的作用域將會一直在記憶體中儲存到閉包不存在為止。

  • 每個函式在被呼叫時都會自動取得兩個特殊變數:this和arguments,內部函式在搜尋這兩個變數時,只會搜尋到自己的活動物件為止,因此永遠不可能直接訪問外部函式的這兩個變數,所以在閉包函式裡的this,指向的是window物件。

  • 例如:
    var name = "The Window";

     var object = {
         name : "My Object",
     
         getNameFunc : function(){
             return function(){
                 return this.name;
             };
         }
     };
     
     alert(object.getNameFunc()());  //"The Window"
    
  • 清理記憶體:

  •      function assign(){
             var element = document.getElementById("xxx");
             var id = element.id;
             element.onclick = function(){
                 alert(id);
                 // alert(element.id);
             }
             element = null;
             }
    
  • 解析:DOM物件往往佔據較大的記憶體,當在閉包函式內直接訪問element.id時,element具有兩個引用數,引用數大於0就無法被垃圾回收。

  • 改進:用id = element.id來取得需要的值,而避免在閉包內對element的整個引用,但此時element依然在外部函式的作用域中被引用,引用數為1依舊大於0,所以為了使element所指物件的引用數0,在使用完後要將element的引用指向null,這樣之前被element引用的物件就可以被垃圾回收了。

相關文章