再次思考作用域與執行環境的關係
首先,若忘記語法作用域與執行環境可以先參考這兩篇(語法作用域、執行環境與執行堆疊)。
我們在語法作用域時有提到 callName()的範例,因此我們可以得知 CallName2()
內在調用 CallName1()
時,CallName1()
內的變數 name
會查找到全域變數的值 ASin
,所以我們了解到在撰寫原始碼時就已經定義好它的作用域,與他的執行環境變沒有關聯。
1 | var name = 'ASin'; |
範圍鍊
延伸上面的範例,其實兩個 function 已經各自產生了一個範圍鍊,當本身的 function 內找不到變數時,會再往外層尋找,這樣將查找範圍又延伸到外層一層一層出去,就是範圍鍊的形成。痾….,這範圍好像有點短,我們再來看下面的範例。
1 | var person = 'ASin'; |
- 當我們執行
sayHello()
時,由於函式內並沒有person
這個變數,所以往外層全域來查找找到了 ‘ASin’ 。 - 那麼在執行
meetSomeone()
時,裡面調用了sayHello()
,記得我們說過作用域早已經定義好了,雖然在meetSomeone()
內調用,但它會忽視var person = '漂亮的HYH'
,所以在sayHello()
原始碼往外一層就是全域,同樣找到了’ASin’。 - 接下來執行
meetHYH()
,裡面調用了sayHelloToHYH()
,所以sayHelloToHYH()
從他原始碼已定義好的作用域開始查找變數person
,嗯…函式本身沒有person
,再往外一層 →meetHYH()
內…..還是沒有找到,再往外一層 →meetSomeone()
內….發現person
!!!終於讓我找到妳啦!所以 console 印出了哈囉~ 漂亮的HYH
的結果。
從meetSomeone()
我們可以知道,當查找不到變數時會往外一層一層的找(範圍鍊),而從哪裡開始查找則是看他已定義好的作用域,而不是執行環境。