首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用"let“和"var”有什么区别?

使用"let“和"var”有什么区别?
EN

Stack Overflow用户
提问于 2009-04-18 04:09:27
回答 15查看 1.8M关注 0票数 5.5K

ECMAScript 6引入了the let statement

我听说它被描述为一个local变量,但我仍然不太确定它的行为与var关键字有什么不同。

有什么不同?何时应该使用let而不是var

EN

回答 15

Stack Overflow用户

发布于 2015-06-03 04:59:18

被接受的答案遗漏了一点:

{
  let a = 123;
};

console.log(a); // ReferenceError: a is not defined
票数 130
EN

Stack Overflow用户

发布于 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

在函数内部

在函数内部(但在块之外),letvar具有相同的作用域。

(() => {
  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

constlet非常相似--它是块作用域,并且有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
票数 114
EN

Stack Overflow用户

发布于 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);

票数 62
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/762011

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档