爲了方便理解咱們先看一段代碼javascript
a = 2;
var a;
console.log( a );
複製代碼
獲得的結果是什麼呢,undefined、ReferenceError異常、2仍是其餘呢 實際上這裏會輸出2,爲何呢,咱們再看java
console.log( a );
var a = 2;
複製代碼
結果又是什麼呢? 答案是undefinedes6
要了解這些,咱們就須要瞭解做用域是什麼了。ui
那麼做用域是什麼呢,簡單來講就是機器再運行某段代碼時候的代碼存在的環境。spa
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的代碼執行時會向上訪問,若是當前做用域找不到要訪問的對象,對向上一級做用域查詢,最終查找到全局做用域,都查詢不到的話拋出錯誤。code
回到開頭的代碼,在咱們看來var a = 2
是一段代碼,而JavaScript不這麼看,它看到的是 var a
和a =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(上卷)》ip