ECMAScript 6 引入了许可声明。

我听说它被描述为一个当地变量,但我仍然不确定它是如何行为不同于 var 关键词。

什么是差异?什么时候应该被允许使用而不是 var?


当前回答

差异在于与每一个声明的变量范围。

让变量仅在其最接近的封锁区({... })中可见。让变量仅在变量被宣布后发生的代码线上可用。让变量不被随后的变量或变量重新宣布。让变量不被全球变量添加到全球窗口对象中。让变量易于使用与封锁(它们不会导致赛车条件)。

{
    let x = 1;
}
console.log(`x is ${x}`);  // ReferenceError during parsing: "x is not defined".

{
    x = x + 1;  // ReferenceError during parsing: "x is not defined".
    let x;
    console.log(`x is ${x}`);  // Never runs.
}

没有重新宣言:下列代码表明,被允许宣言的变量不能随后重新宣言:

let x = 1;
let x = 2;  // SyntaxError: Identifier 'x' has already been declared

var button = "I cause accidents because my name is too common.";
let link = "Though my name is common, I am harder to access from other JS files.";
console.log(link);  // OK
console.log(window.link);  // undefined (GOOD!)
console.log(window.button);  // OK

5. 易于使用与关闭: 与 var 表示的变量与关闭内部的关闭工作不太好. 这里是一个简单的旋转,结果的值序列,变量 i 有在不同的时间点:

for (let i = 0; i < 5; i++) {
    console.log(`i is ${i}`), 125/*ms*/);
}

具体而言,这些输出:

i is 0
i is 1
i is 2
i is 3
i is 4

在JavaScript中,我们经常使用变量比它们创建时更晚的时间。当我们通过延迟输出以关闭转移到设置Timeout时:

for (let i = 0; i < 5; i++) {
    setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}

for (var i = 0; i < 5; i++) {
    setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}

i is 5
i is 5
i is 5
i is 5
i is 5

其他回答

主要差异是范围差异,而让它只能在所宣布的范围内可用,如在圆圈中,可在圆圈之外可访问,例如从MDN的文档(MDN的例子):

function varTest() {
  var x = 1;
  if (true) {
    var x = 2;  // same variable!
    console.log(x);  // 2
  }
  console.log(x);  // 2
}

function letTest() {
  let x = 1;
  if (true) {
    let x = 2;  // different variable
    console.log(x);  // 2
  }
  console.log(x);  // 1
}`

var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined

当在区块内使用时,请将变量的范围限制在该区块上。

var a = 1;
var b = 2;

if (a === 1) {
  var a = 11; // the scope is global
  let b = 22; // the scope is inside the if-block

  console.log(a);  // 11
  console.log(b);  // 22
} 

console.log(a); // 11
console.log(b); // 2

函数运行() { var foo = “Foo”; let bar = “Bar”; console.log(foo, bar); // Foo Bar { var Moo = “Mooo” let baz = “Bazz”; console.log(moo, baz); // Mooo Bazz } console.log(moo); // Mooo console.log(baz); // ReferenceError } run();

為什麼讓關鍵字被引入到語言是功能範圍是混亂的原因,是JavaScript的主要錯誤來源之一。

创建全球对象财产

在最高层次上,让我们不同于VAR,不会在全球对象上创造任何财产:

var foo = “Foo”; // 全球推翻的Let bar = “Bar”; // 不允许全球推翻的console.log(window.foo); // Foo console.log(window.bar); // undefined

有一些微妙的差异 - 让滑动行为更像变量滑动在更多或更少的任何其他语言。

例如,它转向封锁区块,它们在被宣布之前不存在,等等。

然而,值得注意的是,让它只是新的JavaScript实施的一部分,并且有不同的浏览器支持程度。

var 是全球范围(可容量)的变量。

Let and const 是区块范围。

测试JS

{ let l = 'let'; const c = 'const'; var v = 'var'; v2 = 'var 2'; } console.log(v, this.v); console.log(v2, this.v2); console.log(l); // ReferenceError: l 未定义 console.log(c); // ReferenceError: c 未定义

区块范围

在顶级(功能之外)

var globalVariable = 42;
let blockScopedVariable = 43;

console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43

console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined

在一个功能之内

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

在一个区块内

{
  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 in Loops宣言的变量只能在该圈内提到。

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.

// 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);
}

临时死区

由于临时死亡区,使用声明的变量在被声明之前无法访问,试图这样做会导致错误。

console.log(noTDZ); // undefined
var noTDZ = 43;
console.log(hasTDZ); // ReferenceError: hasTDZ is not defined
let hasTDZ = 42;

没有重新宣布

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 a = 42;
a = 43; // TypeError: Assignment to constant variable.

请注意,这并不意味着值是不可改变的;它的属性仍然可以改变。

const obj = {};
obj.a = 42;
console.log(obj.a); // 42

如果您想要一个不可变的对象,您应该使用 Object.freeze()。

const obj = Object.freeze({a: 40});
obj.a = 42;
console.log(obj.a); // 40
console.log(obj.b); // undefined

初步者需要

在使用 const 表示变量时,您必须始终指定值。

const a; // SyntaxError: Missing initializer in const declaration