2014年12月9日 星期二

Javascript:範圍鏈(Scope Chain)


Javascript學習過程中,範圍鏈(Scope Chain)是非常重要的,常常聽到javascript中一個重要概念閉包(Closure),這個概念屬於較抽象難懂的,因此在了解閉包(Closure)機制之前,必須先對範圍鏈(Scope Chain)詳加了解,才有助於學習閉包(Closure)的核心,及避免濫用而造成內存洩漏(Memory leak)等問題。

    一、說明javascript中的範圍鏈概念就以變數為例較清楚,其中我們都知道使用var關鍵字所宣告出來的變數作用範圍是在當時的環境,如下面程式碼函數f與變數a都存在於全域環境中,而f也存取的到a變數:
var a = 5;
function f(){
    alert(a);//5
}
 可以看成物件形式較為清楚:window{a: 5,f: function (){alert(a)}},其中在function f 內有一個alert(a),在function f的範圍內並沒有宣告a,那為什麼顯示出來的值是5?,這是因為javascript會循著範圍鏈    (Scope Chain)一層一層往外找,並使用找到的那一層變數。

     二、由上面結果可以知道在查找變數時,會先從目前的範圍鏈(Scope Chain)往上找,直到全域物件為止,那麼再看看下面的例子。
1.全域中有一function outer,裡面包含一個y的變數與function inner,而在inner內也包含一個變數z。
function outer(){
       var y = 20;
       function inner(){
          var z = 30;
       }
       return inner;
}
2.那麼我們可以知道outer的parent == this,再看看以下代碼,宣告一個變數f = outer(),此時f的parent應該是何者?
  var f = outer();
答案是outer,因為注意到上面function有一個return inner,而我們宣告f並指定為outer()執行後的結果,返回來的是inner,故我們的變數f指向了inner,因此他的parent是為outer。
3.在看以下例子,第一個console.log(m)結果是undefined,那是因為我們還沒宣告m,當m宣告並設定其值時,在執行一次console.log(m);便順利印出5
function func(){
      console.log(m);//undefined {m: undefined}
      var m = 5;  {m: 5}
      console.log(m);//5  {m: 5}
}
4.最後我們了解到javascript中的範圍鏈(Scope Chain)都會由目前範圍網上查找,並使用找到的那一層變數,直到全域中也找不到就是為undefined。

沒有留言:

張貼留言