ECMAScript 6 引入了许可声明。

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

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


当前回答

区块范围

在顶级(功能之外)

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

其他回答

在 MDN 中查看此链接

let x = 1;

if (x === 1) {
let x = 2;

console.log(x);
// expected output: 2
}

console.log(x);
// expected output: 1

如上所述:

差异是分解. var 被分解到最接近的函数区块,然后被分解到最接近的封锁区块,这可能比函数区块小。

例子1:

在我的两个例子中,我有一个功能 myfunc. myfunc 包含一个变量 myvar 等于 10. 在我的第一个例子中,我检查 myvar 等于 10 (myvar==10). 如果是的话,我 agian 宣布一个变量 myvar (现在我有两个 myvar 变量) 使用 var 关键词并将其分配到一个新的值(20)。

此分類上一篇

例2:在我的第二個例子中,而不是在我的條件區域中使用 var 關鍵字,我宣告 myvar 使用 let 關鍵字. 現在,當我呼叫 myfunc 我得到兩個不同的出口: myvar = 20 和 myvar = 10.

因此,差异很简单,即它的范围。

“var”是函数分解,而“let”是区块分解。

您可以在函数中的任何地方使用变量,然后在函数中的任何地方使用变量,然后在函数中的任何地方使用变量。

或者你可以只是使用 Var 整个时间,因为你很不可能在一个函数内部发生范围冲突,然后你不需要跟踪你定义为允许或变量的变量。

有些人建议使用让所有时间,但这不是我的偏好,因为在许多其他编程语言的本地变量是功能的破坏,如果你使用其他,那么你可能会发现它更容易思考这个模式整个时间,而不是在使用JavaScript时更换。

我刚刚遇到了一个使用案例,我不得不使用Var over让介绍新的变量。

我想创建一个新的变量,具有动态变量名称。

let variableName = 'a';
eval("let " + variableName + '= 10;');
console.log(a);   // this doesn't work
var variableName = 'a';
eval("var " + variableName + '= 10;');
console.log(a);   // this works

上面的代码不起作用,因为 eval 引入一个新的代码区块. 使用 var 的声明将声明这个代码区块之外的变量,因为 var 声明函数范围内的变量。

另一方面,让我们在区块范围内宣布一个变量,因此,一个变量仅在 eval 区块中可见。

区块范围

在顶级(功能之外)

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