這篇文章的主題是閉包(closure),我們先不講它是什麼東西,先來看一段程式碼。
var outerValue = "foo";
function outerFunction() {
var innerValue = "bar";
console.log(outerValue);
console.log(innerValue);
}
console.log(outerValue);
console.log(innerValue);
outerFunction();
執行的結果你應該看得出來,在函式外的outerValue = “foo”
,innerValue = reference error
;在函式內的outerValue = “foo”
, innerValue = “bar”
。
你知道這是變數範圍(scope)的緣故,函式內部可以存取函式外部定義的變數和函式,而全域環境或者外部函式卻不能存取宣告在內部函式的變數或函式。
像outerFunction
這樣就是一個 closure,當函式被定義時,同時在它周圍建立起一個「安全氣泡」,讓外界無法入侵。全域環境也是一個 closure,而且在網頁生命週期結束前永遠不會消失。
再看另外一個例子。
var outerValue = "foo";
var later;
function outerFunction() {
var innerValue = "bar";
function innerFunction() {
console.log(outerValue);
console.log(innerValue);
}
later = innerFunction;
}
outerFunction();
later();
這段程式碼的結果會是什麼呢?outerValue
一定可以取得foo
的值,因為它是全域變數。innerFunction
是在函式內被指派在全域變數later
,但呼叫later
時已經是在函式之外了,或許我們會得到innerValue is undefined
?
執行的結果卻是innerValue = “bar”
,這個原因就是 closure。當函式建立的時候,closure 同時建立一個時間膠囊,把能確保函式執行的外部變數及函式全都保留下來。