所有的函式都是閉包:談 JS 中的作用域與 Closure
作用域 Scope
- 作用域(Scope):一個變數的生存範圍,一旦出了這個作用域,就無法存取到這個變數。
- 自由變數(Free Variable):內層函式可以存取到外層函式的變數,外層函式的變數可以稱為 Free Variable
- 作用域鏈(Scope Chain):內層函式在自己的作用域找不到變數,會往上層找,再找不到就繼續往上層找,直到找到或到最上層了還是找不到。inner function scope -> outer function scope -> global scope
- 靜態作用域(Static Scope、Lexical scope):作用域跟 function 在哪裡被呼叫沒有關係,看程式碼的結構就可以知道作用域在哪裡。JacaScript 採用靜態作用域。
- 動態作用域(Dynamic Scope):function 被呼叫時作用域才動態產生。JavaScript 的
this
很像動態作用域,一樣是動態決定。
從 ECMAScript 的作用域來看閉包 Closure
- 每個 EC 都有自己的 Scope Chain,當進入 EC 時,Scope Chain 會被建立
- 進入 EC 時,Scope Chain 會被初始化成 Activation Object(AO) + funciton 的
[[scope]]
屬性:scopeChain = activationObject + [[scope]]
- 進入「函式」時會產生 AO,這個 AO 之後會被當作 VO 使用
- AO 跟 VO 差別在於,AO 有
arguments
,因為是給 function 用的 [[scope]]
就是當前 EC 的 Scope Chain- Scope Chain:存在 EC 裡,為自身 AO、上層 AO 以及 VO 的集合,也就是 AO 跟 VO 的組合
其實跟 原型鏈(Prototype Chain) 很像,都是把相關資訊先存起來,再放進自己的屬性裡面。
參考資料
所有的函式都是閉包:談 JS 中的作用域與 Closure
你不可不知的 JavaScript 二三事#Day5:湯姆克魯斯與唐家霸王槍——變數的作用域(Scope) (1)