閉包之記憶體洩漏
阿新 • • 發佈:2018-12-27
對於全域性變數來說如果沒有主動銷燬則將永遠存在.即如果沒有主動的將其置為 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