不久前的面試中,面試官開門見山問我閉包是什麼,我啞然。就像this一樣,可能給我幾道關於this的題目我會做,但是要我說說什麼是this,我還真不知道從何說起,為了face以後同樣的問題,查閱了一些資料在此簡單做下記錄。誠然,樓主對於閉包的理解還處在初級階段…
簡單來說閉包擁有三個特性:
1.函式巢狀函式
2.函式內部可以取用外部的引數和變數
3.引數和變數不會被垃圾回收機制回收
閉包是指有權訪問另一個函式作用域中的變數的函式,建立閉包的最常見的方式就是在一個函式內建立另一個函式,透過另一個函式訪問這個函式的區域性變數。使用閉包有一個優點,也是它的缺點,就是可以把區域性變數駐留在記憶體中,可以避免使用全域性變數。全域性變數在每個模組都可呼叫,這勢必將是災難性的。(所以推薦使用私有的,封裝的區域性變數。)一般函式執行完畢後,區域性活動物件就被銷毀,記憶體中僅僅儲存全域性作用域。但閉包的情況不同!
我覺得這段說明也很精彩:js裡的函式在執行結束之後,所有的過程中產生的變數都會被銷毀(銷毀原則是無取用)
但在js的函式A裡定義一個函式B併在外部取用時,這條取用鏈上的變數都不會銷毀(即使A已經執行結束),這個函式B就叫做一個閉包。
function fn() { var a = 0; function f() { console.log(a++); } return f; } var b = fn(); b(); // 0 b(); // 1 b(); // 2
接著來看上面的例子,這是一段經典的閉包程式碼,我們看看程式碼都幹了些什麼。
首先要明確f函式即是所謂的閉包,我們看到它巢狀在fn函式內,而且訪問了外部的變數a,同時console的結果也證明瞭變數a貯存在了記憶體中!為什麼會這樣呢?原因在於f被賦予給了一個全域性變數b,導致始終存在在記憶體中,而f的存在必須依賴於fn,這導致fn也始終存在在記憶體中,於是變數a不會在執行後被垃圾回收機制回收。以上例子很好地避免了全域性變數的使用,避免了全域性變數的汙染。
閉包還有什麼用?繼續一個經典的例子:
- 0
- 1
- 2
- 3
- 4