淺淺淺談JavaScript作用域

叫我王珩hénghénghéng發表於2019-03-24

為了方便理解我們先看一段程式碼

a = 2;
var a; 
console.log( a );
複製程式碼

得到的結果是什麼呢,undefined、ReferenceError異常、2還是其他呢 實際上這裡會輸出2,為什麼呢,我們再看

console.log( a ); 
var a = 2;
複製程式碼

結果又是什麼呢? 答案是undefined

要了解這些,我們就需要了解作用域是什麼了。

那麼作用域是什麼呢,簡單來說就是機器再執行某段程式碼時候的程式碼存在的環境。

var color = "blue";
function changeColor() {
    var anotherColor = "red";
    function swapColors() {
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
        // 這裡可以訪問color、anotherColor和tempColor
    }
    // 這裡可以訪問color和anotherColor,不能訪問tempColor
    swapColor()
}
// 這裡只能訪問到color
changeColor()
複製程式碼

這段程式碼涉及到三個執行環境:全域性環境、changeColor()的區域性環境和swapColor()的區域性環境。也就是作用域。

我們可以看出,每一個花括號形成了一個作用域,越內部的作用域可訪問到越多,這是因為JavaScript的程式碼執行時會向上訪問,如果當前作用域找不到要訪問的物件,對向上一級作用域查詢,最終查詢到全域性作用域,都查詢不到的話丟擲錯誤。

回到開頭的程式碼,在我們看來var a = 2是一段程式碼,而JavaScript不這麼看,它看到的是 var aa =2 JavaScript會將申明移到作用域的頂端,所以第一段程式碼在console.log(a)的時候就訪問到了值,而第二段程式碼在console.log(a)的時候只做了var a 動作,a沒有實際的值,所以結果是undefined。 ——ps:es6 出現了const和let兩種申明方式,這兩種申明不會進行提升

a = 2;
let a; 
console.log( a ); // Uncaught ReferenceError: a is not defined
複製程式碼

參考資料: 《JavaScript高階程式設計》 《你不知道的JavaScript(上卷)》