JavaScript - Closure與Hoisting

JavaScript - Closure與Hoisting

分散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: Closure 與 Hoisting

留言