詳解 JavaScript 作用域

JavaScript 的作用域一直是前端開發(fā)和前端面試中難以理解的知識點,一不留神就入坑了,小編寫這篇文章,就是來填坑的,好了,直接開始。

1. JavaScript 無塊級作用域

什么是塊級作用域?其實就是占地盤,畫個圈圈說這塊地盤是我的,只有我能在這個區(qū)域里作,例如,這個 “{ }” 大括號。
那無塊級作用域又是什么意思呢?就是即便你畫了個圈,但憑啥你說這是你地盤就是你地盤,我在圈外面就想插一腳玩玩。
例子1:
JavaScript 無塊級作用域

function Fun()  { 
     if(true) {
          var name = 'yes';
    }
    console.log(name);
};
Fun();
// yes

這里 if(true) 后面的 {...} 是一個塊級作用域,根據(jù)輸出結果,可以知道 console.log(name) 是可以訪問 var name = 'yes' 的,等同于別人在你家門外就能拿你家里的東西。
不過在 ES6 中,引入了 let 關鍵字,用于指定變量屬于塊級作用域。也就是說JavaScript 也有塊級作用域了。
例子2:
JavaScript 有塊級作用域

function Fun()  { 
     if(true) {
          let name = 'yes';
    }
    console.log(name);
};
Fun();
// undefined

引用 let 替換 var 后,生成了塊級作用域,console.log(name) 訪問不到大括號里面的內(nèi)容了。

2. JavaScript 函數(shù)作用域

JavaScript 中每個函數(shù)作為一個作用域,外部是無法訪問作用域內(nèi)部的變量的。
例子3:

function Fun() {
    var x = 1;
    var y = 2;
    console.log(x); 
}
Fun();
console.log(y);
// 1   ReferenceError: y is not defined......

“函數(shù)作用域”還是比較厲害的,自己家的東西管的很嚴格,別人看都不讓看。

3. JavaScript 作用域鏈

JavaScript中的每個函數(shù)作為一個作用域,如果出現(xiàn)函數(shù)之間互相嵌套,就會出現(xiàn)作用域鏈。
例子4:

x = 1;
function Fun() {
      var x = 2;
      function main() {
            var x = 3;
            console.log(x);
      }
      main();
}
Fun();
// 3

兩個函數(shù)互相嵌套,形成三個作用域組成的作用域鏈(不要忘記全局作用域),這種情況下,尋找變量就要按照順序。

執(zhí)行console.log(x)時,按照作用域有內(nèi)而外的優(yōu)先級尋找,很明顯,應該先在

   function main() {
      var x = 3;
      console.log(x);
   }

找到了 var x = 3,最后結果就是3。修改例子3,如下:

 x = 1;
 function Fun() {
     var x = 2;
     function main() {
           console.log(x);
     }
     main();
 }
 Fun();
 // 2

依次類推,如果最后找不到則報錯。

這里,順便講一下JavaScript 變量提升。

4. JavaScript 變量提升

有時候也稱之為聲明提前,變量聲明提升等等,其實都是一個意思。
什么是變量提升,即變量可以在聲明之前使用,說的簡單點,就是聲明的這個變量它比較喜歡往前湊熱鬧。

  1. JavaScript 中不創(chuàng)建變量,直接使用,結果是報錯的

     console.log(x);
     // ReferenceError: x is not defined...
    
  2. 創(chuàng)建變量但是不賦值,結果是 undefined

     var x;
     console.log(x);
     // undefined
    
  3. 創(chuàng)建變量并賦值,結果輸出正常

     var x = 3;
     console.log(x);
     // 3
    

注意:這里 var x = 3 在實際執(zhí)行過程中是這樣的,明白這點很重要。
var x;
x = 3;
我們看下面這個例子
例子5:

    function Fun() {
        console.log(x);
        var x = '5';
    }
    Fun();
    // undefined

為什么輸出的是 undefined,而不是直接報錯或者輸出“5”呢?請看原因:這個時候,變量提升和剛才的“明白這點很重要”該出馬了。在 JavaScript 被執(zhí)行之前,有一個“預編譯”的過程,這期間代碼變成這樣了
function Fun() {
var x; // 看到了沒,我跑前面來了哦
console.log(x);
x = '5'; // 賦值語句位置不變,聲明語句提前
}
Fun();

喜歡的童鞋,可以關注一下我('?' )?

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容