這是一門在Udemy 課程,是同學介紹的。主要是因為想要運用到過年前這段時間好好的增進自己的JavaScript的基礎能力,讓自己能往前端工程師更近一步。主要還是會以筆記的形式做呈現!
我們都知道,在JavaScript 要執行一段函式只需要在函式的最後加上()就可以了,我們把執行函式的執行這個動作稱做invoke。
下面有一段剪的的code,我們用這段code來解釋原理:
1 | function b() { |
當我們執行上述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。
基礎的原理理解完後,來看一個稍微進階一點的:
1 | function b() { |
結果是:
1 | 1 |
疑?為什麼在三個會是undefined,原因就在於剛剛我們有提到:每一個execution context都擁有自己的空間 for variables and functions,因為這個原因,不同 execution context 中的變數是不會互相影響的。
所以這個案例來說,我在function b 裡面有在宣告一個名為myVar 的變數,因此只要在這個function裡面所有使用到myVar都是會以這次宣告為主。
但如果這時候我是使用myVar而不是宣告呢?
1 | function b() { |
結果會是:
1 | 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
lexical environment(詞彙環境)
在JavaScript中,他所代表的的是:今天這段code在memory的位子
所以不需要去考慮他們在code的順序,因為執行的順序是跟他們被 invoked 有關