var
的缺點var
如果被重複性宣告同一個變數,之後的宣告會覆蓋之前的宣告。
var num = 1;
//程式碼⋯⋯
var num = 3;
console.log(num); //3
因此當如果程式碼長度太長,有可能會因為失誤,而不小心重複宣告了某個變數,導致出現錯誤。
而var
另一個缺點,在於會污染作用域。
for (var i=0; i<10; i++){
console.log(i);
}
console.log(i);
在上面的情況中,迴圈中的i
變數是可以在迴圈被顯示的(因為這裡的i
是全域變數),這種情況就稱為污染作用域,因為i
變數原本應該只需要作用在迴圈中。
而在判斷式中,也有同樣的問題:
var ans = true;
if(ans == true) {
var join = "Yes";
console.log(join);
}
console.log(join);
在上面的情況中,迴圈中的join
變數一樣應該只需要作用在判斷式中,但結束了判斷式,join
變數一樣可以被讀取,所以和迴圈一樣,也出現了污染作用域的問題。
let
和const
let
和const
都是宣告變數時使用,用來解決var
出現的問題。
兩者之間的最大差異,在於用const
宣告變數後,該變數不可被重新賦值。
let
可以被重新賦值,但該變數不可被重複宣告。
違反了let
和const
的規定,就會出現錯誤。
let a = 1;
a = 3;
console.log(a); //3
這種情況使用let
宣告變數是可以執行的,但換成const
就會出現錯誤。
var b = true;
var b = false;
console.log(b);
在上面這種情況下,let
和const
都不可以使用,因為重複宣告變數,使用let
和const
都會出現錯誤。
let
的作用域var
的作用域區間在於函式,只有在函式內,var
才有區域變數。
let
的作用域在於區塊(block),只要在區塊的半形大括弧({}
)中,let
宣告的變數就是區域變數。
let num = 3;
{
let num = 5;
console.log(num); //5
}
console.log(num); //3
在上面的狀況中,因為第二個num
變數的作用域只在半形大括弧({}
)的區塊中,所以雖然出現兩個num
變數,但不算重複宣告,並且兩次console.log(num);
的結果也不一樣。
let
的hoistinglet
也有hoisting,和var
執行hoisting時的步驟完全相同。但不像var
的hoisting可以讀取,會出現undefined,let
的hoisting會出現一個被稱為暫時性死區(又稱TDZ)的區域,在暫時性死區的資料不可被讀取,會出現錯誤。