在以前寫的進階系列裏面,提到了
執行上下文
在建立階段,要建立變量對象
、肯定做用域鏈
還有肯定this的指向
,本次將重點講解一下做用域鏈
。javascript
在講解做用域鏈以前,首先了解一下,JavaScript代碼的執行過程,包括兩個步驟:java
在編譯階段主要作的是,通過編譯器的編譯,將代碼轉化爲可執行的代碼,其中就包括了做用域規則的肯定
,而在以前說的執行上下文的建立和執行階段是發生在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()
的做用域鏈圖,以下: