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
),并且在声明/初始化它之前不允许对它进行任何访问或赋值。