1.什麼是閉包?
當函數可以記住并通路所在的詞法作用域,即使函數是在目前詞法作用域之外執行,這就産生了閉包。–《你不知道的JavaScript上卷》
個人了解:閉包就是函數中的函數,裡面的函數可以通路外面函數的變量,外面的變量的是這個内部函數的一部分。
例:其中func_2稱為閉包
function func_1(){
const n = 10;
function func_2(){
console.log(n)
}
return func_2
}
2.閉包形成的條件
- 函數嵌套
- 内部函數引用外部函數的局部變量
3.閉包的記憶體洩露
- 全局作用域:當網頁關閉時才會銷毀的作用域
- 私有作用域:隻有函數執行時才會産生的作用域
一般情況下,函數執行會形成一個新的私有作用域,一般函數執行完成後,我們目前作用域都會主動的進行釋放和銷毀。但當遇到函數執行傳回一個引用資料類型的值,并且在函數的外面被某個變量接收了,這種情況下形成的私有作用域都不會銷毀。
💡記憶體洩漏:指任何對象在不被需要之後,它仍然存在。
例:
function fn(){
var num = 100;
return function(){}
}
var f = fn() // 此時fn形成的作用域被f接收,不會被銷毀
是以閉包不能濫用,否則會導緻記憶體洩漏,影響網頁性能。閉包使用完了之後,要立即釋放資源,将引用變量指向null。
經典面試題:
function outer(){
var num = 0; // 内部變量
return function add(){
num++;
console.log(num);
}
}
var func1 = outer();
func1(); // 等同于調用add -> num=1
func1(); // 再次調用 num=2
var func2 = outer();
func2(); // num = 1 重新引用時,生成的作用域也是全新的
func2(); // num = 2
4.閉包的作用
- 可以讀取函數内部的變量
- 可以使變量的值長期儲存在記憶體中,生命周期比較長。但需要及時釋放,否則會影響網頁性能
- 可以用來實作Js子產品
5.閉包的運用
- 防抖節流
總結
閉包就是在函數中定義并傳回另一個函數, 裡層的函數調用外層函數的變量, 進而形成閉包. 而因為外層函數的變量被裡層函數調用, 就會導緻變量不會被垃圾回收機制回收,進而存在記憶體洩漏的風險