var 和 let 之間的區別
(注意:使用 let 的所有示例也適用於 const)
var 適用於所有版本的 JavaScript,而 let 和 const 是 ECMAScript 6 的一部分,僅在某些較新的瀏覽器中可用 。
var 的範圍限定為包含函式或全域性空間,具體取決於何時宣告:
var x = 4; // global scope
function DoThings() {
var x = 7; // function scope
console.log(x);
}
console.log(x); // >> 4
DoThings(); // >> 7
console.log(x); // >> 4
這意味著它轉義if 語句和所有類似的塊結構:
var x = 4;
if (true) {
var x = 7;
}
console.log(x); // >> 7
for (var i = 0; i < 4; i++) {
var j = 10;
}
console.log(i); // >> 4
console.log(j); // >> 10
相比之下,let 是塊作用域:
let x = 4;
if (true) {
let x = 7;
console.log(x); // >> 7
}
console.log(x); // >> 4
for (let i = 0; i < 4; i++) {
let j = 10;
}
console.log(i); // >> "ReferenceError: i is not defined"
console.log(j); // >> "ReferenceError: j is not defined"
請注意,i 和 j 僅在 for 迴圈中宣告,因此在其外部未宣告。
還有其他幾個重要的區別:
全域性變數宣告
在頂層作用域(在任何函式和塊之外),var 宣告將一個元素放在全域性物件中。let 沒有:
var x = 4;
let y = 7;
console.log(this.x); // >> 4
console.log(this.y); // >> undefined
重新申報
使用 var 宣告變數兩次不會產生錯誤(即使它相當於宣告一次):
var x = 4;
var x = 7;
使用 let,會產生錯誤:
let x = 4;
let x = 7;
TypeError:識別符號
x已經宣告
使用 var 宣告 y 時也是如此:
var y = 4;
let y = 7;
TypeError:識別符號
y已經宣告
但是,使用 let 宣告的變數可以在巢狀塊中重用(不重新宣告)
let i = 5;
{
let i = 6;
console.log(i); // >> 6
}
console.log(i); // >> 5
在塊內可以訪問外部 i,但是如果內部塊具有 i 的 let 宣告,則無法訪問外部 i,如果在宣告第二個宣告之前使用了 ReferenceError,則會丟擲 ReferenceError。
let i = 5;
{
i = 6; // outer i is unavailable within the Temporal Dead Zone
let i;
}
ReferenceError:我沒有定義
吊裝
用 var 和 let 宣告的變數都被懸掛 。不同之處在於,使用 var 宣告的變數可以在其自己的賦值之前引用,因為它會自動賦值(以 undefined 作為其值),但是 let 不能 - 它特別要求在呼叫之前宣告變數:
console.log(x); // >> undefined
console.log(y); // >> "ReferenceError: `y` is not defined"
//OR >> "ReferenceError: can't access lexical declaration `y` before initialization"
var x = 4;
let y = 7;
塊的開始和 let 或 const 宣告之間的區域稱為時間死區 ,並且對該區域中的變數的任何引用都將導致 ReferenceError。即使在宣告變數之前分配變數,也會發生這種情況 :
y=7; // >> "ReferenceError: `y` is not defined"
let y;
在非嚴格模式下,在沒有任何宣告的情況下為變數賦值,會自動在全域性範圍內宣告變數 。在這種情況下,let 不是在全域性範圍內自動宣告 y,而是保留變數的名稱(y),並且在宣告/初始化它之前不允許對它進行任何訪問或賦值。