[JavaScript] 忍之道解謎(一) - function Scope
Q: 請問alert訊息是?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var site = "jsdc"; | |
function foo(){ | |
site = "IThome"; | |
} | |
function boo(){ | |
alert(site); | |
} | |
foo(); | |
boo(); |
JavaScript 的 function scope
Scope 是程式語言用來管理變數的生命週期與可視範圍(Visibility),有了這項機制可以避免命名的衝突以及記憶體自動管理。JS 提供了function scope 機制,這意昧著function 裡面所宣告的變數僅限函式內使用,超出此範圍即失去其效用,function執行階段在取用這些變數成員時,是透過Scope chain 去搜尋並取用。
當函式被呼叫執行時,會依下列步驟產生 Scope chain:
(1) 建立 Execution context
(2) 初始化 scope chain 物件集合
(3) 將 Global object 加入 scope chain:
將外部所宣告的 Global variables 與 document, window and navigator 等變數加入global object,再將scope chain 第一個位置變數指向它。
(4) 建立 Activation object:
Activation 裡面將包含了所有在函式所宣告的 Local variables, parameters 等,當然別忘了還有 this, arguments。
(5) 將 Activation object 移到物件集合的第一筆位置:
當function 執行期間碰到要取用變數時,會從第一筆開始尋找目標,直到找到對應的變數(或找不到),這也是為什麼濫用Global variable會造成JS速度低落的原因,因為Global object 總是scope chain 的最後一個物件
了解 JS 的 function scope 原理後 (如上所示),應該就很清楚 alert 訊息是什麼了,當 foo 被執行時,site 這個global variable 被加入了 foo 的 scope chain 並且在 function body 更新其值,當 boo 建立 scope chain 時,其 Activation object 所reference 的 site 變數其值已經被 foo 更新為 " IThome " 了,所以答案是「IThome」。
留言
張貼留言