JS之做用域淺談

這幾天看了一下JS高級程序設計裏的介紹做用域的章節,也參考了網上的資料,如今結合着本身的理解,給你們分享一下我本身對JS做用域的理解。前端

做用域及執行環境

這裏有三個重要的概念:執行環境、做用域、變量對象函數

(JS高級程序設計解釋)
執行環境 :定義變量或函數可訪問的其餘數據,來決定它們的行爲。
變量對象 :保存執行環境中定義的變量和函數。
做用域鏈 :保證對環境中定義的變量和函數的有序訪問。設計

通俗來講,執行環境和做用域就是變量或函數有效執行所在的一個環境。
總結一下這三者的關係:每一個執行環境執行時都會產生一個做用域,做用域前端都有一個變量對象來保存環境中的變量和函數。code

知道這3個重要概念後,要想搞清做用域,就要先清楚JS程序的預解析過程
JS程序開始執行時會先解析語法(檢查錯誤等等)、解析內存,而後把function、var解析到變量對象裏。
這裏注意解析var變量時只是會把變量名稱解析,而等到程序運行到變量賦值時纔會向變量賦值。對象

var a="A";
function test(){
    console.log(a);//undefined
    var a="B";
}
test();

這段代碼的第一個console.log之因此會是undefined,緣由是函數內部的a變量在預解析時已經被解析到變量對象裏,但沒被賦值。因此函數執行時找到函數裏未被賦值的a變量,輸出undefined。內存

搞清楚預解析後,在判斷做用域範圍
由於做用域的查找順序是由局部做用域一步步地往上找,直到找到聲明的變量和函數或已經到了全局做用域。因此局部的做用域能夠訪問到外部做用域的變量,而外部做用域訪問不到內部做用域的變量。作用域

相關場景

var a="A";
function test(){
    console.log(a);//「A」
    a="B";
}
test();
console.log(a);//"B"
function test(){  
      b();//函數b會被預解析,所以能夠調用,執行了輸出1;
      var a=1;
      function b(){
          console.log(1);
          console.log(a);//undefined
          var a=2;
      }
}
test();

以上例子參考網上資料。io

總結

要想搞清做用域,首先要搞清預解析,而後判斷做用域範圍,先判斷本層環境有無聲明及賦值,若是有聲明,則判斷調用前是否賦值。若是找不到聲明,則一層層往外部的做用域找,直到全局環境也找不到時,一般就會報錯。console

若是有解釋的不對或不清晰的,歡迎留言討論。function

相關文章
相關標籤/搜索