JavaScript: Closure 與 Hoisting
01 May 2015分散 var 來宣告變數並沒有太大的意義,因為就 JavaScript 程式語言的特性來說,函數(Function)中未宣告而先用到的變數會被提升至區塊的第一行做宣告。先來看基本觀念 Closure,再來看 Hoisting。
Closure
Closure 是指變數的生命週期只存在於該 Function 中,一旦離開了 Function,該變數就會被回收而不可再利用,且必須在 Function 內事先宣告。
function closure() {
var a = 1;
console.log(a); //1
}
closure();
console.log(a); //Uncaught ReferenceError: a is not defined
對於 Closure 進一步的探討可參考這篇文章 Closures。
Hoisting
Hoisting 是一種把宣告提升到其所在區域內頂端的行為,意即程式會將 Function 中全部需要宣告的 Local Variable,提升到 Function 的第一行來執行,但不包含初始值設定。
var a = 1;
function hoisting() {
if (!a) {
var a = 999;
}
console.log(a); //999
}
hoisting();
咦!?怎麼會是 999 呢?a 在第一行已初始化為 1,必不為 0、undefined、空字串或 null,怎麼會造成判斷!a === true
呢?原來對於 JavaScript 來說,所有未宣告的 Local Variable 都會被提到第一行做宣告(但不設定初始值,即初始值為 undefined),意即:
var a = 1;
function hoisting() {
var a = undefined;
if (!a) {
a = 999;
}
console.log(a); //999
}
hoisting();
會有 Hoising 這樣的狀況當然和 JavaScript 語言本身的特性有關,即在執行程式前會有「Variables Instantiation」的動作 - 將使用 var 的變數宣告先辨識起來(除了 Function 外,初始值設為 undefined),到了執行階段才給予初始值。相關可參考這篇文章 Initialization of functions and variables。
推薦閱讀
- JavaScript Scoping and Hoisting:清楚說明 Scope、Hoisting、Function 的相關觀念。
- Functions: declarations and expressions:承上,Function 相關可參考這篇文章。
- JavaScript Patterns:Hoisting - 分散 var 造成的問題。
- Closures:Access to outer variables, nested functions and closures.
- Initialization of functions and variables - 對 JavaScript 這個語言特性有興趣的可以參考這篇文章,將 Lexical Environment 和 Pre-processing Stage 的流程和所做的事情解釋得很清楚。
- [筆記] JavaScript 變數宣告與作用域
這篇文章的原始位置在這裡-JavaScript - Closure 與 Hoisting
由於部落格搬遷至此,因此在這裡放了一份,以便閱讀;部份文章片段也做了些許修改,以期提供更好的內容。