let為ES6新增的用來宣告變數的命令,用法類似與var,那麼let和var具體是怎麼個用法以及他們之間有什麼區別呢?
一. let宣告的變數只在let程式碼塊有效
{
let a = 1;
var b = 2;
}
console.log(a); // 報錯,a is not defined
console.log(b); // 2複製程式碼
用let宣告瞭變數a,用var宣告瞭變數b,輸出的時候a報錯,b輸出了正確的值,這說明let只在它所在的程式碼塊內有效。
例項:
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10複製程式碼
var宣告變數是全域性範圍內有效的,雖然每次迴圈i都在改變,但是迴圈內都賦值給了a的i,相當於每次迴圈出來的i都是指向同一個i,也就是最後一個i,所以為10;
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6複製程式碼
let宣告的變數i只在本輪迴圈有效,每次迴圈的i都是一個全新的變數,所以值為6;
二. 不存在變數提升
console.log(foo); // 輸出undefined
var foo = 2;複製程式碼
console.log(bar); // 報錯ReferenceError
let bar = 2;複製程式碼
var會有變數提升,所以在輸出foo之前,foo由於變數提升,就已經存在了,但是沒有值,所以為undefined;let不存在變數提升,輸出bar之前還未定義bar,所以報錯。
三. 暫時性死區
var tmp = 123;
if (true) {
tmp = 'abc';
let tmp;
console.log(tmp); // ReferenceError
}複製程式碼
var tmp = 123;
if (true) {
tmp = 'abc';
var tmp;
console.log(tmp); // abc
}複製程式碼
全域性宣告瞭變數tmp,但是在程式碼塊中又用let宣告瞭tmp,使得後者繫結了塊級作用域,此時的tmp是在宣告之前就賦值了,所以報錯。在程式碼塊內,使用let命令宣告變數之前,該變數都是不可用的。這在語法上,稱為“暫時性死區”。
四. 不允許重複宣告
{
let a = 10;
var a = 1;
console.log(a); //報錯
}
{
let a = 10;
let a = 1;
console.log(a);//報錯
}複製程式碼
{
var a = 10;
var a = 1;
console.log(a); //1
}複製程式碼
let不允許在函式內部重複宣告同一個函式,否則會報錯。