什麼是閉包
閉包就是內部函式。何為內部函式呢?即是可以通過在一個函式內部或者塊級作用域裡面定義的函式。
(function autorun(){
let x = 1;
function log(){
console.log(x);
}
log();
})();
複製程式碼
此時,log() 函式就是一個閉包。
閉包特性
- 內部函式可以訪問外部函式定義的變數。即使外部函式已經執行完畢。
- 閉包只儲存外部變數的引用。
- 作用域是定義時的作用域,而不是執行時的作用域。即是詞法作用域
閉包作用
適用場景:
- 當外部函式執行完,內部函式依然存活。例如非同步操作。
- 函式當作返回值。
- 定時器、事件監聽器、Ajax請求、跨視窗通訊、Web Workers或者任何其他的非同步(或者同步)任務中,只要使用了回撥函式,實際上都是在使用閉包。
閉包缺點
- 多個子函式的[[scope]]都是同時指向父級,是完全共享的。因此當父級的變數物件被修改時,所有子函式都受到影響。
解決辦法:
- 變數可以通過 函式引數的形式 傳入,避免使用預設的[[scope]]向上查詢
- 使用setTimeout包裹,通過第三個引數傳入
- 使用 塊級作用域,讓變數成為自己上下文的屬性,避免共享
- 記憶體洩漏