1. 程式人生 > 程式設計 >JavaScript基礎之作用域

JavaScript基礎之作用域

目錄
  • 作用域
    • 全域性作用域
    • 函式作用域
      • if,switch,for ,while
    • 塊作用域
    • 作用域鏈
      • 總結

        再聊AO和BO之前還需要了解作用域的概念,這樣方便後面瞭解很多東西,比如this指向等。

        作用域

        作用域(Scope)簡單的說就是變數,函式和物件定義後其可用的範圍。

        console.log(a)
        {
            var a=1;
        }
        function test(){
             var b=2;
        }
        

        在這裡插入圖片描述

        可以看出在外面無法使用變數b。可以看出作用域可以保護資料不會被外部隨意訪問,以及修改。簡單可以看出作用域可以相互隔離彼此的變數,也就是說在不同的作用域下的同名變數不會衝突。

        而作用域最重要常用的是全域性作用域和函式作用域。不過ES6之後因為let 和const關鍵字的出現又引如了一個塊級作用域。

        全域性作用域

        全域性作用域簡單說就是所有域都可以訪問器域下變數以及方法物件。

        var a="全域性1";
         function test(){
            b="沒有帶var,隱式轉變為全域性變數";
            window.c="直接將變數c作為window下也會變全域性";
            var d="非全域性作用域";
         }
         #第一步 執行test()
        test()  #這樣才會將方法內的變數進行定義以及賦值
        #第二步
        console.log(a)
        console.log(b)
        console.log(c)
        console.log(d)
        

        在這裡插入圖片描述

        一般來說window的屬性都是全域性變數,而window.c 其實式將c作為一個window的屬性來對待。注意一點在宣告變數的時候不要帶var ,最好是帶著var,這樣不會將其提升成全域性變數,導致資料會被相互汙染。

        補充說一句,test這個方法也是全域性域下的方法。

        function test(){
            var a= function(){
                console.log("字面量的方法")
            }
            b=function(){
                console.log("不帶var字面量的方法")
            } 
           function test1(){
               console.log("普通宣告方法")
           }
             
        }
         

        在這裡插入圖片描述

        這個可以看出字面量宣告的方法,類似一個可以看成一個將函式賦值給一個變數,將其作為一個變數來對待。前面預編譯的時候也演示過了。

        函式作用域

        函式作用域與全域性作用域相反,其不是為所有的地方用,而是在一定的範圍用,一般宣告的變數,只在函式內部使用。

        function test(){
             var a="非全域性作用域";
             console.log(a)
        }
        

        現在又有了一個問題,全域性方法裡面可以用函式作用域內部的變數。那麼函式是內部是否可以有其下面的函式生成的函式作用域呢?以及其變數是否可以相互用?

        function test(){
             var a="test方法作用域";
            function test1(){
                 var b="test1方法作用域";
                console.log("a的值=",a);
            }
            # 呼叫函式內部函式
            test1();
             console.log("b的值=",b);
         }
        

        在這裡插入圖片描述

        這個地方可以看出作用域是分層的,內層作用域可以訪問外層作用域的變數,外部訪問不了內部的變數。

        if,switch,for ,while

        條件語句和邏輯迴圈,**它們不是函式同樣也不像函式,也不會建立一個新的作用域。**其www.cppcns.com塊定義的變數將保留在它們存在的作用域中。

        function test(a){
            if(a>1){
                var b=13;
            }else{
               var b=1;  
            }
            console.log(b);
        }
        

        在這裡插入圖片描述

        所以在使用條件語句和邏輯迴圈的時候,儘可能不要再全域性作用域下使用。因為其方法體中的變數會影響其他的資料。

        塊作用域

        塊作用域的出現,一般需要依賴兩個關鍵字let或const之一,不然就不會存在這個塊作用域。

        在這裡插入圖片描述

        function test(a){
            const b="23";
            if (a>2){
                const c=3
                console.log("第一個人if---c-----",c)
            }
            if (a>1){
                console.log("第二個人if----b----",b)
                console.log("第二個人if----c----",c)
            }
             
        }
        

        在這裡插入圖片描述

        可以看出如果有關鍵字let和const後,其變數的範圍就是在其宣告的那一對花括號內。所以第一個if中的c變數再第二個if的裡面無法取得。當然還是遵守:內層作用域可以訪問外層作用域的變數。

        瞭解let和const看前一篇:地址

        作用域鏈

        這個看似很神奇的概念,簡單的說就是作用域內有就直接用,沒有找上一層,如果都沒有,找到全域性就結束。

        var a=1
        var b=3
        function test(){
            var a=2
            console.logoxLyMy("a的值",a);
            console.log("b的值",b);
        }
         

        在這裡插入圖片描述

        多嘴說一下,作用域鏈其實和原型鏈的尋找邏輯一樣,後面繼續聊。

        總結

        本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注我們的更多內容!