javascript - Scope
透過下面的例子瞭解javascript是怎麼運作的
|
|
我原本的認知是第一行的code就是一次的宣告指令
但其實可以透過另一種方式來看這段程式碼
就是把自己當成naive top down compiler
並把compile拆成宣告跟執行兩個步驟
- 第一行,嘿 Scope global ,我找到了一個叫做 foo 的 var 宣告
- 第三行,嘿 Scope global ,我找到了一個叫做 bar 的 function 宣告
- 第四行,嘿 Scope bar ,我找到了一個叫做 foo 的 var 宣告
- 第七行,嘿 Scope blobal ,我找到了一個叫做 baz 的 function 宣告
- 第七行的 foo , 嘿 Scope baz ,我找到了一個叫做 foo 的 var 宣告
- 第一行的 var 在執行階段已經不在,因為在 compile 階段已經宣告了 foo 成為一個 var,所以第一行在做的事情就是,向當前的 scope 去詢問,嘿 global scope,你有LHS reference 叫做foo的嗎?scope 會回應說有找到,並且直接將RHS assign 進LHS。
- 在 = 左邊為LHS 也就是target, 右邊為RHS 也就是source
- 若 reference 不是 LHS,那就會是RHS
- 假設我們執行了 function bar,這時就會問,嘿 bar scope,你有LHS reference 叫作foo的嗎?scope 會回應說有找到,並且直接將RHS assign 進LHS。
- 第七行,嘿, baz scope 你有LHS reference 叫作foo的嗎?scope 會回應說有找到,並且直接將RHS assign 進LHS。
- 第九行,嘿, baz scope 你有LHS reference 叫作bam的嗎?這時scope 會回應說沒有,這時候就會往外一層scope去找,再問,嘿,global scope,你有LHS reference 叫作bam的嗎? 若在 unstrict 模式下 global scope 會回應說,「有啊,我幫你創造了一個」,這時 bam就變成了一個global variable了。
這邊稍微講一下 undeclared跟undefined的差別
undeclared:沒在任何的scope底下被宣告
undefined:已宣告的變數但沒有任何實際的值
例子
|
|
在 LHS reference 沒被宣告的情況下,scope會自動幫你宣告
但 RHS reference 沒被宣告則會觸發 ReferenceError
function declaration
|
|
function expressions
|
|
block scope
|
|
IIFE (Immediately-invoked function expression)
可以避免global變數被我們寫的code所影響
|
|
let (ES6)
let 是在ES6 syntax中新的語法,讓變數只存在在block中,let不會hoisting,所以必須將let宣告放在最前面
|
|
|
|
Ref: