我們都知道,在JavaScript 要執行一段函式只需要在函式的最後加上()就可以了,我們把執行函式的執行這個動作稱做invoke。
下面有一段簡單的code,我們用這段code來解釋原理:
function b() {
}
function a() {
b()
}
a()
當我們執行上述code 時,我們會先創建一個global execution context,這時候會一併建立this、global object (如果是在瀏覽器則是建立window object)
當我執行到a()時,除了會建立a() execution context並且會被放置在execution stack中。
如果我在執行這個 execution context 時, invoke 另一個 function時,它就會在那個地方停住並且創建另一個 execution context。
execution stack 最上面的會是正在執行的。任何時候在JavaScript中 invoke a function ,都會創建一個execution context 並放入execution stack。每一個execution context都擁有自己的空間 for variables and functions。
每一次我們調用function時,該function都會創建一個新的execution context (第一階段創建變數並且先讓每個變數值放入undefined,第二階段才會把我們要給這個變數的值放到裡面。’this’這個特殊變數也會一起創建),並把這個新的execution context放到 stack的最上面(stack為後進先出,最上面的會先執行,synchronously)然後完成後他就會popped off。
基礎的原理理解完後,來看一個稍微進階一點的:
function b() {
var myVar
console.log(myVar)
}
function a() {
var myVar = 2
console.log(myVar)
b()
}
var myVar = 1
console.log(myVar)
a()
結果是:
1
2
undefined
疑?為什麼在三個會是undefined,原因就在於剛剛我們有提到:每一個execution context都擁有自己的空間 for variables and functions,因為這個原因,不同 execution context 中的變數是不會互相影響的。
所以這個案例來說,我在function b 裡面有在宣告一個名為myVar 的變數,因此只要在這個function裡面所有使用到myVar都是會以這次宣告為主。
但如果這時候我是使用myVar而不是宣告呢?
function b() {
console.log(myVar)
}
function a() {
var myVar = 2
console.log(myVar)
b()
}
var myVar = 1
console.log(myVar)
a()
結果會是:
1
2
1
為什麼第三個不是not defined ?
這是因為在未宣告新的變數的情況下,在該execution context中JavaScript engine找不到這個變數,它就會往它的外層(Outer Environment)去尋找。
雖然程式執行的過程中會先執行global execution context(myVar = 1),接著執行function a(myVar = 2),最後才執行function b。但是對於function b來說,它的outer environment就是最外層的global environment,這就是他的結果是1不是2的原因
解釋一下兩個名詞:
scope chain(作用域鏈)
Scope Chain就是在找變數的過程中,從內層找到外層,直到最外面的global environment的這條鍊,就叫做Scope Chain。
outer environment(外部環境)
每個 execution context 都會對 outer environment 做引用,什麼時候會做這項動作:呼叫一個變數但在execution context中沒有時,它會往它的outer environment去找。
但並不是直接看code的順序,而是要看lexical environment
這次真的是結束了,在排前面這幾篇順序時我很猶豫,scope 跟 hoistting 是否真的要擺在這麼前面,原本的打算是要放在 data types 後面,但在整理自己之前的文章還有筆記時發現了這篇,覺得很重要想要放進來,但這樣兩篇function中間會隔著兩篇,我很不喜歡XD因此就變成現在的順序。
希望大家喜歡這樣的排序!