1. 程式人生 > >閉包之記憶體洩漏

閉包之記憶體洩漏

對於全域性變數來說如果沒有主動銷燬則將永遠存在.即如果沒有主動的將其置為 null ,其始終會佔據一部分記憶體.

而對於函式內使用 var 宣告的區域性變數來說,當函式執行完畢後區域性變數會自行銷燬.

function f(){
 var a = 1;   //函式執行結束後區域性變數a會被自行銷燬
 alert(a)
}
f()

而閉包的結構則可以改變變數的生存週期,使區域性變數不被銷燬

var cost = (function(num){
  var money = 0;
  return function(num){
    if(arguments.length == 0){
        return money;  
    }else{
      money += num
    }
  }
})()
cost(100);
cost(100);
console.log(cost());    // 200
console.log(cost());    // 200

上述程式碼中區域性變數 money 在cost() 函式執行結束後,由於在返回的匿名函式中仍別引用,因此沒有被銷燬.由兩次列印cost()即可看出,改變數被儲存了下來,再次列印時仍可輸出.由此便造成了記憶體洩露,倘若不主動銷燬會一直佔用記憶體資源.

而上述例項也恰恰利用閉包的該特點完成了一個特殊的功能,cost()函式代表單次花費了多少,引數即為每次的花費值,而當我們想要獲取總共的花費值時只需列印 cost() 不傳入引數即可

要如何解決呢?

var cost = (function(num){
  var money = 0;
  return function(num){
    if(arguments.length == 0){
      try{
        return money;
      }finally{
        money = null;
      }
      
    }else{
      money += num
    }
  }
})()
cost(100);
cost(100);
console.log(cost());    // 200
console.log(cost());    // null

再看上述程式碼利用finally的特性在cost()首次執行後主動將 money 銷燬,則再次列印結果為 null