Closure 閉包
這是 JavaScript 中一個很有趣的特徵,它作用在函式的閒置變數與當時環境綁定。
所以建立函式不等於 Closure。是將外部變數使之繼續存活或關入自己的範疇中才稱之為 Closure。
如下:
var wrapper = function () {
var x = 100;
function inner(val) {
return x + val;
}
return inner;
}();
console.log(wrapper(2));
變數 x 沒有定義在 inner 內中,實際上 x 是從外部函式來的,函式 inner 建立了 Closure,
把 x 關入了自己的範圍中讓它繼續存活延續了 x 的生命週期。
要注意的是 Closure 關閉的是變數,而不是值
var wrapper = function () {
var x = 100;
function inner(val) {
x = x + val;
return x;
}
return inner;
}();
console.log(wrapper(2)); // 102
console.log(wrapper(60)); // 162
可以利用 Closure 的特性做出區域變數的區隔
function wrapper() {
var x = 100;
function inner(val) {
x = x + val;
return x;
}
return inner;
};
var layout_1 = wrapper();
var layout_2 = wrapper();
console.log(layout_1(2)); // 102
console.log(layout_2(60)); // 160
歸納
特性
- 在特定函式存取另一個函式的變數
- 外層函式宣告的變數可以在內層函式取得
- 作用域鏈結 (Scope Chain)
閉包程式碼外觀
- 運用在巢狀函式的定義
以下輸出結果又是如何呢 ?
var _array = [100, 200, 300, 400, 500];
function List() {
var result = [];
var i = 0;
var length = _array.length;
for (i=0; i<length; i++) {
result[i] = function() {
console.log(_array[i]);
};
}
return result;
}
var price = List();
price[0](); // ?
price[1](); // ?
price[2](); // ?
price[3](); // ?
price[4](); // ?
這是一個區塊範疇的陷阱,也會在實務應用中遇到。對不懂 closure 特性的開發人員會是一個很大的災難。