ECMAScript 6 引入了许可声明。

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

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


当前回答

// 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

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

其他回答

正如我目前正在试图深入了解JavaScript,我将分享我的简短研究,其中包含一些已经讨论的伟大作品,以及一些其他细节,从不同的角度。

理解VAR和LAT之间的差异可以更容易,如果我们理解函数和区块范围之间的差异。

让我们来看看以下案例:

(function timer() {
    for(var i = 0; i <= 5; i++) {
        setTimeout(function notime() { console.log(i); }, i * 1000);
    }
})();


   Stack            VariableEnvironment //one VariablEnvironment for timer();
                                       // when the timer is out - the value will be the same for each iteration
5. [setTimeout, i]  [i=5] 
4. [setTimeout, i]  
3. [setTimeout, i]
2. [setTimeout, i]
1. [setTimeout, i]
0. [setTimeout, i]

####################    

(function timer() {
    for (let i = 0; i <= 5; i++) {
        setTimeout(function notime() { console.log(i); }, i * 1000);
    }
})();

   Stack           LexicalEnvironment - each iteration has a new lexical environment
5. [setTimeout, i]  [i=5]       
                      LexicalEnvironment 
4. [setTimeout, i]    [i=4]     
                        LexicalEnvironment 
3. [setTimeout, i]      [i=3]       
                         LexicalEnvironment 
2. [setTimeout, i]       [i=2]
                           LexicalEnvironment 
1. [setTimeout, i]         [i=1]
                             LexicalEnvironment 
0. [setTimeout, i]           [i=0]

当按时()被称为执行内容时,将创建一个内容,该内容将包含每个字符串的变量环境和所有相应的语法环境。

更简单的例子

功能范围

function test() {
    for(var z = 0; z < 69; z++) {
        //todo
    }
    //z is visible outside the loop
}

区块范围

function test() {
    for(let z = 0; z < 69; z++) {
        //todo
    }
    //z is not defined :(
}

简而言之,Let和Var之间的区别在于Var是功能分解,Let是区块分解。

使用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,变量被分解并共享副本。

一些黑客与Let:

1。

    let statistics = [16, 170, 10];
    let [age, height, grade] = statistics;

    console.log(height)

二。

    let x = 120,
    y = 12;
    [x, y] = [y, x];
    console.log(`x: ${x} y: ${y}`);

3、

    let node = {
                   type: "Identifier",
                   name: "foo"
               };

    let { type, name, value } = node;

    console.log(type);      // "Identifier"
    console.log(name);      // "foo"
    console.log(value);     // undefined

    let node = {
        type: "Identifier"
    };

    let { type: localType, name: localName = "bar" } = node;

    console.log(localType);     // "Identifier"
    console.log(localName);     // "bar"

Getter 和 Setter 與 Let:

let jar = {
    numberOfCookies: 10,
    get cookies() {
        return this.numberOfCookies;
    },
    set cookies(value) {
        this.numberOfCookies = value;
    }
};

console.log(jar.cookies)
jar.cookies = 7;

console.log(jar.cookies)

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

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

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

如上所述:

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

例子1:

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

此分類上一篇

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

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