預解析 var 變量提升 函數提升

1 明確預解析的過程:瀏覽器在執行代碼的時候,會對整體進行預解析,作用是爲了排除錯誤以及提升變量和函數。
2 變量提升僅僅提升用 var 聲明的變量,先提升變量在提升函數;
3 當函數被調用的時候,函數體內的代碼又會進行相同的解析過程;
4 解析完畢之後,瀏覽器一行一行的執行代碼;
5 案例解釋:

var a = 18 ;
f1();
function f1(){
    var b = 9 ;
    console.log(a);
    console.log(b);
    var a = "abc";
}

解析過程:
提升變量和函數

var a ;
function f1(){
    var b = 9 ;
    console.log(a);
    console.log(b);
    var a = "abc";
}
//一行一行執行代碼
a = 18 ;
f1();
//執行到上面這一行代碼的時候,函數被調用,開闢一塊獨立的內存區 ,在函數體內又會進行同樣的解析過程
function f1(){
    var b ;
    var a ;
    b = 9 ;
    console.log(a);
    console.log(b);
    a = "abc";
}
//解析完畢

以上代碼輸出結果爲:undefined 9.

注意兩個問題:
1 函數體被提升的時候,並不會被執行;
2 變量的使用會遵循“就近原則”,即,如果在函數內部有定義的變量,那麼就會在當前作用域下找當前作用域下聲明的變量, 如果在當前作用域沒有聲明該變量,則會在上一級作用域找變量那麼外部的變量不會被調用
這就解釋了 a 輸出的結果是 undefined;

變身1 :

    var a = 18 ;
    f1();
    function f1(){
        var b = 9 ;
        console.log(a);
        console.log(b);
        a = "abc";
    }

以上代碼輸出結果爲 18 9 ;
此時, a 調用的是全局變量 a = 18 ;可能有的人 會問爲什麼不是 a = “abc” ;還是回到瀏覽器的解析過程:提升變量和函數的 聲明,然後 一行一行執行代碼
去掉函數體內 a 的 var 聲明,此時 a 是隱式全局變量,函數體 f1()整體被執行完畢之後,外部的全局變量 a 會被重新賦值爲 “abc ”。
變身2 :

var a = 18 ;
    f1();
    function f1(){
        var b = 9 ;
        console.log(a);
        console.log(b);
        a = "abc";
        console.log(a);
    }
console.log(a);

輸出的結果爲 18 9 abc abc .(代碼是一行一行執行的,只有當執行到 a = “abc”,那一行。隱式全局變量 a 纔可以改變 全局變量 a 的值。

變身3 :

var a = 18 ;
f1();
function f1(){
    var b = 9 ;
    console.log(a);
    console.log(b);
     a = "abc";
     console.log(a);
     var a ;
}
console.log(a);

輸出結果是 :undefined 9 abc 18
注意函數體內的用 var聲明的變量都是局部變量,在該函數體內的局部作用域有效,就只能在該函數中訪問該變量。當退出該函數後,這個變量會被撤銷。這種變量稱爲本地變量。可以在不同的函數中使用名稱相同的本地變量,這是因爲只有聲明過變量的函數能夠識別其中的每個變量。
在調用 f1() 的時候,函數體內的預解析如下:此時函數體內的 a 是局部變量

    function f1(){
         var a ;
         var b ;
         b = 9 ;
         console.log(a);
         console.log(b);
         a = "abc";
         console.log(a);    
    }

變身4 :

    var a = 18 ;
    function f1(){
        var b = 9 ;
        console.log(a);
        console.log(b);
        a = "abc";
        console.log(a);

    }
console.log(a);

輸出結果爲 18 ,有的同學可能會疑問,爲什麼隱式全局變量 a = “abc “,沒有覆蓋掉 a = 18 的值呢? 根本一句話:當沒有調用函數的時候,即是函數體內有隱式全局變量,也不會被執行。(函數裏面的代碼塊只有在被調用的時候纔會被聲明執行)。

發佈了35 篇原創文章 · 獲贊 48 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章