发布于 2015-06-03 04:59:18
被接受的答案遗漏了一点:
{
let a = 123;
};
console.log(a); // ReferenceError: a is not defined
发布于 2016-11-24 06:52:38
let
块作用域
使用let
关键字声明的变量是块范围的,这意味着它们只在声明时所在的block中可用。
在顶层(函数外部)
在顶层,使用let
声明的变量不会在全局对象上创建属性。
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined
在函数内部
在函数内部(但在块之外),let
与var
具有相同的作用域。
(() => {
var functionScopedVariable = 42;
let blockScopedVariable = 43;
console.log(functionScopedVariable); // 42
console.log(blockScopedVariable); // 43
})();
console.log(functionScopedVariable); // ReferenceError: functionScopedVariable is not defined
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
在一个块内
在块内使用let
声明的变量不能在该块之外访问。
{
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
}
console.log(globalVariable); // 42
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
在循环中
在循环中使用let
声明的变量只能在该循环中引用。
for (var i = 0; i < 3; i++) {
var j = i * 2;
}
console.log(i); // 3
console.log(j); // 4
for (let k = 0; k < 3; k++) {
let l = k * 2;
}
console.log(typeof k); // undefined
console.log(typeof l); // undefined
// Trying to do console.log(k) or console.log(l) here would throw a ReferenceError.
带有闭包的循环
如果在循环中使用let
而不是var
,那么每次迭代都会得到一个新变量。这意味着您可以在循环中安全地使用闭包。
// Logs 3 thrice, not what we meant.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// Logs 0, 1 and 2, as expected.
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 0);
}
临时死区
由于使用了the temporal dead zone,使用let
声明的变量在声明之前不能被访问。尝试这样做会抛出错误。
console.log(noTDZ); // undefined
var noTDZ = 43;
console.log(hasTDZ); // ReferenceError: hasTDZ is not defined
let hasTDZ = 42;
不能重复声明
您不能使用let
多次声明同一个变量。您也不能使用与使用var
声明的另一个变量具有相同标识符的let
来声明变量。
var a;
var a; // Works fine.
let b;
let b; // SyntaxError: Identifier 'b' has already been declared
var c;
let c; // SyntaxError: Identifier 'c' has already been declared
const
const
与let
非常相似--它是块作用域,并且有TDZ。然而,有两件事是不同的。
禁止重新分配
不能重新赋值使用const
声明的变量。
const a = 42;
a = 43; // TypeError: Assignment to constant variable.
注意,这并不意味着该值是不可变的。它的属性仍然可以更改。
const obj = {};
obj.a = 42;
console.log(obj.a); // 42
如果你想拥有一个不可变的对象,你应该使用Object.freeze()
。
需要初始值设定项
在使用const
声明变量时,必须始终指定一个值。
const a; // SyntaxError: Missing initializer in const declaration
发布于 2015-03-06 18:41:11
下面是两者的区别示例(对chrome的支持刚刚开始):
正如您所看到的,var j
变量的值仍然在for循环作用域(Block作用域)之外,但是let i
变量在for循环作用域之外是未定义的。
"use strict";
console.log("var:");
for (var j = 0; j < 2; j++) {
console.log(j);
}
console.log(j);
console.log("let:");
for (let i = 0; i < 2; i++) {
console.log(i);
}
console.log(i);
https://stackoverflow.com/questions/762011
复制相似问题