1. 程式人生 > 其它 >var和let的區別

var和let的區別

作用域

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的區別主要有三點:作用域的不同、是否存在變數提升、能否重複宣告