JS之執行環境,作用域詳解

在《Javascript高級程序設計》這本書中學到的知識,覺得對於JS學習還是有很大幫助的,所以就寫上來跟大家分享一下。

首先我們來看一下執行環境。用例子來說明:

var backgroundColor='red';
function changeColor(){
    if(backgroundColor=='red'){
        backgroundColor='blue';
            }

}
changeColor();
alert(backgroundColor);

上面的結果是blue。然而,我們分析一下它的執行過程。每一個函數都有執行環境,當這個函數執行的時候,這個執行環境就會進入環境棧中,函數結束後就會被棧彈出。在這個環境中會產生一個AO(Active 0bject)對象,最開始這個AO對象只有一個變量:argument,但隨着作用域鏈,backgroundColor這個對象也存在了AO對象的一個變量中,所以,changeColor的執行過程是這樣的:

①產生一個AO對象,一開始只有argument變量: ActiveObject{argument}
②沿着作用域鏈,ActiveObject{argument,backgroundColor:'blue'}
③接着就彈出對話框,其中的信息是ActiveObject.backgroundColor,也就是blue。

上面不斷提到作用域鏈的問題,到底什麼是作用域鏈呢?我們首先來看一下作用域,換一個例子:

var color='blue';
function a(){
    var backColor='red';
    function b(){
        var fontColor='black';
    //這裏能夠訪問color,backColor,fontColor
    }
    //這裏能夠訪問color backColor 但不能訪問fontColor
    b();
}
//這裏只能夠訪問 color
a();

從上面的例子註釋,我們可以很容易理解作用域的概念,就是變量在哪個地方能夠被訪問。要注意,js是沒有塊級作用域的。然後,我們來說說開始的例子作用域鏈的問題,產生AO對象的時候,它會在函數changeColor中找變量,發現裏面並沒有聲明任何變量(即沒有var一個變量),所以,沿着作用域鏈,查找比changeColor範圍還要廣的作用域,即是全局作用域,就發現了backgroundColor。這就是作用域鏈:保證對執行環境有權訪問的所有變量和函數的有序訪問。

最後,我們來看一看一個經典的面試題

var str='global';
function a(){
    alert(str);
    var str='local';
    alert(str);
}
a();

大家想到結果沒有? 第一個是undefined ,第二個是local。 有沒有大驚小怪?
不過相信大家看了上面的知識,理解這道題就沒什麼難度了。

大家不要被全局變量str="global"誤導了,其實這個並沒什麼作用
有作用的是a函數裏面的var str='local',在變量定義的時候,其實編譯器會先把變量聲明瞭 再給它賦值的,也就是其實上面的代碼是這樣的:
function a(){
    var str;
    alert(str);
    str='local';
    alert(str);
}
接着,就產生一個AO對象,裏面首先是alert(AO.str)一開始的時候,str=undefined的所以會輸出undefined,接着str賦值爲local,就會輸出AO.str='local'.

好了,這部分大概就這麼多了,大家可以把這個面試裏a函數裏面的var去掉,看看結果什麼,如果和你預想一樣,這部分我相信你也能夠理解了。

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