Closure
by Aaron • 10/11/2022, 11:26:19 AM
閉包(Closure)是函式以及該函式被宣告時所在的詞法環境(lexical environment)的組合。 在JavaScript 中,每個運行的函數,blocks {…} 以及整份程式碼,都有一個被稱為 詞法環境(Lexical Environment)的內部(隱藏)的關聯對象。
lexical environment
lexical environment由兩部分組成:
- Environment Record: 一個存儲所有局部變量作為其屬性(包括一些其他資料,例如 this 的值)的物件。
- 對外部lexical environment 的引用
- 變數宣告 當程式剛執行時 let 變數換先被宣告成 uninitialized 的狀態,直到真正宣告後才能被使用
// code -> lexical environment. -> outer lexical environment
// execution start. -> foo: <uninitialized>. -> null
let foo = 1 //-> foo: 1
foo = 2 //-> foo: 2
- 函數宣告 當程式剛執行時,函數會最先被初始化
// code -> lexical environment. -> outer lexical environment
// execution start. -> foo1: <uninitialized>. -> null
// foo2: function
let foo1 //-> foo1: undefined
foo1 = 2 //-> foo1: 2
function foo2() {
let v = 1
}
接著再細看 foo2
...
// code -> lexical environment. -> outer lexical environment
function foo2() { //-> v: <uninitialized> -> {foo1: 2, foo2: function}. -> null
let v = 1 // -> v: 1
}
...
當要訪問一個變量時首先會搜索內部詞法環境,然後搜索外部環境,然後搜索更外部的環境,以此類推,直到全局詞法環境
Closure 例子
function foo1(x) {
return foo2(y) {
return x + y;
};
}
var add5 = foo1(5);
var add10 = foo1(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12