var和let的區別
阿新 • • 發佈:2021-10-01
作用域
var是函式作用域,而let是塊作用域。
在ES6之前,我們都是用var來宣告變數,而且JS只有函式作用域和全域性作用域,沒有塊級作用域,所以{}
限定不了var宣告變數的訪問範圍。
{
var i = 9;
}
console.log(i); // 9
var j=0;
{
console.log(j);//0
}
ES6新增的let
,可以宣告塊級作用域的變數。
{
let i = 9;
console.log(i) // 9
}
console.log(i); // Uncaught ReferenceError: i is not defined
變數提升
let必須先宣告,在使用;而var先使用後宣告也行。只不過直接使用但沒有定義的時候,其值是undefined。var有一個變數提升的過程,當整個函式作用域被建立的時候,實際上var定義的變數都會被建立,並且如果此時沒有初始化的話,則預設為初始化一個undefined
// var 的情況
console.log(a); // 輸出undefined
var a = 100;
// let 的情況
console.log(b); // 報錯ReferenceError
let b = 200;
上面程式碼變數a用var宣告,會發生變數提升,因沒有值,所以會輸出undefined。變數b用let宣告的則不會發生變數提升。
重複宣告
var可以允許重複宣告相同的變數,後者會覆蓋前者;
let不允許在相同作用域內,重複宣告同一個變數。
// 報錯 function func() { let a = 10; var a = 1; } // 報錯 // Uncaught SyntaxError: Identifier 'a' has already been declared function func() { let a = 10; let a = 1; }
因此,不能在函式內部重新宣告引數。
function func(a) {
let a; // 報錯
}
function func(a) {
{
let a; // 不報錯
}
}
常見習題
for (var i = 0; i <10; i++) {
setTimeout(function() { // 同步註冊回撥函式到 非同步的 巨集任務佇列。
console.log(i); // 執行此程式碼時,同步程式碼for迴圈已經執行完成
}, 0);
}
// 輸出結果
//10 共10個
如果把 var改成 let宣告:
// i雖然在全域性作用域宣告,但是在for迴圈體區域性作用域中使用的時候,變數會被固定,不受外界干擾。 for (let i = 0; i < 10; i++) { setTimeout(function() { console.log(i); // i 是迴圈體內區域性作用域,不受外界影響。 }, 0); } // 輸出結果: 0 1 2 3 4 5 6 7 8 9
總結
總的來說,let和var的區別主要有三點:作用域的不同、是否存在變數提升、能否重複宣告