ECMAScript 6 引入了许可声明。

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

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


当前回答

使用Let

允许的关键词将变量声明连接到它所包含的任何区块的范围(通常是 {.. } 对),换句话说,允许随意窃取任何区块的范围为其变量声明。

让变量无法在窗口对象中访问,因为它们无法在全球范围内访问。

function a(){
    { // this is the Max Scope for let variable
        let x = 12;
    }
    console.log(x);
}
a(); // Uncaught ReferenceError: x is not defined

当使用VAR

在 ES5 中, var 和 variables 具有函数中的曲线,这意味着在函数内有效,而不是函数本身之外。

function a(){ // this is the Max Scope for var variable
    { 
        var x = 12;
    }
    console.log(x);
}
a(); // 12

如果你想知道更多,继续阅读下面

最著名的面试问题之一的范围也可能足以准确使用下列;

使用Let

for (let i = 0; i < 10 ; i++) {
    setTimeout(
        function a() {
            console.log(i); //print 0 to 9, that is literally AWW!!!
        }, 
        100 * i);
}

当使用VAR

for (var i = 0; i < 10 ; i++) {
    setTimeout(
        function a() {
            console.log(i); //print 10 times 10
        }, 
        100 * i);
}

这是因为在使用VAR时,对于每个曲线 iteration,变量被分解并共享副本。

其他回答

ECMAScript 6 添加了另一个关键字来宣布变量,而不是“放下”。

“Let”和“Let”在“var”上引入的主要目标是,而不是传统的词汇,区块点点点点点点点点点点点点点点点点点点点点点点点点。

答案缺少一点:

{
  let a = 123;
};

console.log(a); // ReferenceError: a is not defined

我想将这些关键词链接到执行背景,因为执行背景在这一切中都很重要。执行背景有两个阶段:创作阶段和执行阶段。

在创建阶段的执行背景, var, let 和 const 将仍然存储其变量在记忆中与未确定的值在该执行背景的变量环境中. 差异在执行阶段. 如果您使用参考一个变量定义为 var 之前它被分配一个值,它将只是不确定的。

function a(){
    b;
    let b;
}
a();
> Uncaught ReferenceError: b is not defined

// An array of adder functions.
var adderFunctions = [];

for (var i = 0; i < 1000; i++) {
  // We want the function at index i to add the index to its argument.
  adderFunctions[i] = function(x) {
    // What is i bound to here?
    return x + i;
  };
}

var add12 = adderFunctions[12];

// Uh oh. The function is bound to i in the outer scope, which is currently 1000.
console.log(add12(8) === 20); // => false
console.log(add12(8) === 1008); // => true
console.log(i); // => 1000

// It gets worse.
i = -8;
console.log(add12(8) === 0); // => true

上面的过程不会产生所需的函数序列,因为我的范围超越了每个函数创建的区块的 iteration。 相反,在环节结束时,每个函数的 i 关闭指在环节结束时的 i 值(1000)为每个在 adder 中的匿名函数。

// Let's try this again.
// NOTE: We're using another ES6 keyword, const, for values that won't
// be reassigned. const and let have similar scoping behavior.
const adderFunctions = [];

for (let i = 0; i < 1000; i++) {
  // NOTE: We're using the newer arrow function syntax this time, but 
  // using the "function(x) { ..." syntax from the previous example 
  // here would not change the behavior shown.
  adderFunctions[i] = x => x + i;
}

const add12 = adderFunctions[12];

// Yay! The behavior is as expected. 
console.log(add12(8) === 20); // => true

// i's scope doesn't extend outside the for loop.
console.log(i); // => ReferenceError: i is not defined

每个函数现在保留在函数创建时的 i 的值,并且 adderFunctions 按照预期行事。

现在,图像将两种行为混合在一起,你可能会看到为什么不建议在同一脚本中混合更新的Let和 const。

const doubleAdderFunctions = [];

for (var i = 0; i < 1000; i++) {
    const j = i;
    doubleAdderFunctions[i] = x => x + i + j;
}

const add18 = doubleAdderFunctions[9];
const add24 = doubleAdderFunctions[12];

// It's not fun debugging situations like this, especially when the
// code is more complex than in this example.
console.log(add18(24) === 42); // => false
console.log(add24(18) === 42); // => false
console.log(add18(24) === add24(18)); // => false
console.log(add18(24) === 2018); // => false
console.log(add24(18) === 2018); // => false
console.log(add18(24) === 1033); // => true
console.log(add24(18) === 1030); // => true

不要让这件事发生在你身上,使用灯具。

我刚刚遇到了一个使用案例,我不得不使用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 区块中可见。