1. 程式人生 > >JavaScript 作用域(Scope)詳解

JavaScript 作用域(Scope)詳解

先對需要用到的名詞解釋一下,再通過例子深入理解

一、什麼是作用域(Scope)

  [[scope]]:每個javascript函式都是一個物件,物件中有些屬性我們可以訪問,但有些不可以,這些屬性僅供javascript引擎存取,[[scope]]就是其中一個。[[scope]]指的就是我們所說的作用域,其中儲存了執行期上下文的集合。即作用域決定了程式碼區塊中變數和其他資源的可見性。

 

二、變數的作用域型別

  1.全域性作用域:全域性作用域貫穿整個javascript文件,在所有函式宣告或者大括號之外定義的變數,都在全域性作用域裡。一旦你聲明瞭一個全域性變數,那麼你在任何地方都可以使用它,包括函式內部。

  2.區域性作用域:區域性作用域一般只在固定的程式碼片段內可訪問到,而其外部是無法訪問的,它分為函式作用域和塊級作用域

    a:函式作用域: 當你在函式裡定義一個變數時,它在函式內任何地方都可以使用。在函式之外,你就無法訪問它了。

    b:塊級作用域:你在使用大括號時,聲明瞭一個const或者let的變數時,你就只能在大括號內部使用這一變數。

 

三、作用域鏈

  作用域鏈:[[scope]]中所儲存的執行期上下文物件的集合,這個集合呈鏈式連結,我們把這種鏈式連結叫做作用域鏈。

 

四、執行期上下文

  當函式執行時,會建立一個稱為執行期上下文的內部物件。一個執行期上下文定義了一個函式執行時的環境,函式每次執行時對應的執行上下文都是獨一無二的,所以多次呼叫一個函式會導致建立多個執行上下文,當函式執行完畢,執行上下文被銷燬。(即AO、GO,不瞭解的可參考預預編譯文章)

 

五、查詢變數

  在函式中查詢變數,從其作用域鏈的頂端依次向下查詢,從Scope chain 的0位依次查到最後一位。


通過一個例子具體瞭解上面的定義:

<script>
    function a() {
            function b() {
                var bb = 234
            }
        var aa = 123;
        b();
    }
    var glob = 100;
    a();
</script>

 1.a()定義時,其Scope裡存放GO

2.a()執行時,形成作用域鏈,Scope chain[0] 存放AO, Scope chain[1] 存放GO

   

3: b()定義,因為它是a()內部的函式,因此其執行期上下文與a()執行時是一樣的;

  

4:b()執行時,產生自己的AO,在作用域鏈中將a()的AO與GO儲存位置下移,第0位存自己的AO

  

 注意:b()  Scope chain 儲存的a() 的AO與a()中的AO一樣,只是將其引用掛到裡面,即通過b()中可以改變a()中變數的值

   例:

<script>
    function a() {
            function b() {
                var bb = 234
                aa = 0;
            }
        var aa = 123;
        b();
     console.log(a); } var glob = 100; a(); </script>

 輸出a的值為 0