1. 程式人生 > >javascript必知必會之this關鍵字及scope

javascript必知必會之this關鍵字及scope

先看下面幾個例子:

var global_scope = "I'm global";
var fun = function(){
var fun_scope = "I'm in fun scope";
return innerfun(){
var inner_func_scope = "I'm in the inner fun scope";
return global_scope + fun_scope + inner_func_scope; //此處的引用是重要的,請特別注意
};
};
alert(fun()());

請注意上面的程式碼,其中:

  1. global_scope 它是global scope
  2. fun_scope 它是 位於一個函式的scope
  3. inner_func_scope 是一個位於一個函式內的函式的scope

你也可以繼續內嵌函式, 那麼會生成若干個scope.

於是有個問題出現了, 為什麼innerfun方法可以引用不在它自身scope的變數?

在回答這個問題之前,需要引入一個概念 scope chain. 所謂的 scope chain 是指 在 javascript 的程式碼中形成的一個具有優先順序, 相關的作用域的鏈.

以上面的程式碼為例,

  1. 對於global的scope而言,它會為自己建立一個global的scope chain(當然此時,這個鏈只有一個scope).
  2. 對於fun函式的scope而言, 它首先建立一個與global相同的scope chain,然後再加入自己的scope(此時,這個 鏈有2個scope), 類似於這樣的結構: global==>fun
  3. 對於innerfun而言,除了fun函式所具有的鏈外,它還會加入自己的scope(當然,此時這個鏈有3個scope), 類似於這樣的結構: global==>fun==>innerfun

scope chain具有下面的特徵:

  1. 有序
  2. 每當建立一個函式時,會自動生成一個scope並加入自己的scope chain中
  3. 這個chain類似於一種棧,在查詢變數時總是先從頂端查起

參見下圖:

http://farm4.static.flickr.com/3425/3958796284_615f096470_o.png

上圖的3個部分對應上面程式碼中的三個變數的scope, 並且在對每個變數求值時,是按照 圖中的scope chain從上到下依次查詢,找到即返回值或者直到窮舉了scope chain返回undfined.

那麼現在回答上面那個問題:

其實也很好理解, 在計算某個表示式時, 它會對自己的scope chain進行從上到下的查詢,如果找到了 它會立即返回這個值,如果找完了整個chain也沒有找到,則返回undefined.

這個查詢機制也就決定了,通常位於chain的前端的scope有更高的優先順序.

例如 javascript 在計算 global_scope + fun_scope + inner_func_scope; 這個表示式時, 它會查詢上面圖示中的scope chain,從而確定出最後的結果.