JS進階系列之做用域鏈

在以前寫的進階系列裏面,提到了執行上下文在建立階段,要建立變量對象肯定做用域鏈還有肯定this的指向,本次將重點講解一下做用域鏈javascript

JavaScript代碼的執行過程

在講解做用域鏈以前,首先了解一下,JavaScript代碼的執行過程,包括兩個步驟:java

  • 編譯階段
  • JavaScript引擎執行階段

image.png

在編譯階段主要作的是,通過編譯器的編譯,將代碼轉化爲可執行的代碼,其中就包括了做用域規則的肯定,而在以前說的執行上下文的建立和執行階段是發生在JavaScript隱引擎執行階段,因此做用域鏈是在執行上下文建立階段才產生的,這時候,可能你會疑惑,做用域和做用域鏈有什麼區別呢?函數

什麼是做用域?

做用域爲一套規則,用來管理引擎如何在當前做用域以及嵌套的子做用域中根據標識符查找變量。this

在JavaScript中,主要的做用域有兩種:3d

  • 全局做用域
  • 函數做用域

什麼是做用域鏈?

做用域鏈是由當前執行環境與上層環境的一系列變量對象組成,它保證了當前執行環境對符合訪問權限的變量和函數的有序訪問。code

而做用域與做用域鏈的區別主要在於:對象

做用域是一套規則,做用域鏈是做用域的具體實現。blog

講理論可能有些空洞,那麼我就舉個具體的例子來講明什麼是做用域鏈吧ip

demo01
var a = 20;
function test(){
        var b = a + 20;
        function innerTest(){
             var c = 10;
             return b + c;
       }
       return innerTest();
}
test();

在這個例子中,按照以前講解的作用域

  • 先建立執行上下文,按照,globalEC—>testEC—>innerTestEC的順序,壓入調用棧中,其中主要討論innerTest()的做用域鏈。
  • 按照做用鏈的定義,能夠得出innerTest()執行上下的結構,以下
innerTestEC = {
      VO:{ c:10},
      scopeChain:[VO(innerTest),VO(test),VO(global)],
      this:{...}
}

能夠看出,innerTest()的做用域鏈就是由當前的執行環境與上層的執行環境中的一系列變量對象組成,因此innerTest()就能訪問到上層執行上下文中,變量對象中的屬性和方法,這就是做用域鏈。

  • 看一下innerTest()的做用域鏈圖,以下:

image.png

相關文章
相關標籤/搜索