在JavaScript for for循环中阻止作用域?

时间:2018-01-14 23:29:41

标签: javascript

为什么这段代码用VAR打印6但是" i"和LET增加的for循环值

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

2 个答案:

答案 0 :(得分:0)

定义为var的变量会自动移到顶部。

即使你这样定义:

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

它被用作好像你已经写过

var i;

for (i = 1; i <= 5; i++) {
    setTimeout(function () {
        console.log("i " + i);
    }, i * 1000)
}

由于i现在就像一个全局变量,for循环执行并保留值为6的变量。将来,当setTimeout调用该函数时,所有调用的值都是6。

您可以详细了解letvar

答案 1 :(得分:0)

varlet之间的差异是范围:

var scope

  

声明的变量在声明它们的执行上下文中受到约束。未声明的变量总是全局的。

let scope

  

let声明的变量的范围是定义它们的块,以及任何包含的子块。

当您使用var运行示例时,循环将快速执行并在setTimeout()函数开始执行之前结束,并且当它们执行时,它们将获得i的当前值变量是6。

当您使用let运行示例时,循环也将快速执行并在setTimeout()函数开始执行之前结束。但是这一次,因为i变量的作用域是循环,它会将每个值保留在每个setTimeout()函数调用的上下文内存中。

为了与'var'实现相同的效果,您可以使用闭包创建不同的上下文来保留值,就像let所做的那样:

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