封闭内部循环

Jae*_*Lee 3 javascript closures

我知道使用此代码将0到9记录的方法之一:

编辑: 来源

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
      console.log(i);
    }), 10)
}
Run Code Online (Sandbox Code Playgroud)

的jsfiddle

setTimeout自我调用并i作为参数传递,如下所示:

for(var i = 0; i < 10; i++) {
    setTimeout((function(i) {
      console.log(i);
    })(i), 10)
}
Run Code Online (Sandbox Code Playgroud)

但我已经测试过setTImeout自我调用而不通过i,它仍然有效:

for(var i = 0; i < 10; i++) {
    setTimeout((function() {
      console.log(i);
    })(), 10)
}
Run Code Online (Sandbox Code Playgroud)

的jsfiddle

我的问题:

  1. 为什么即使不i作为参数传递也能工作?
  2. 有必要通过i吗?

Sci*_*tas 8

问题

这不是关闭.

for(var i = 0; i < 10; i++) {
  setTimeout((function(i) {
    console.log(i);
  })(i), 10)
}
Run Code Online (Sandbox Code Playgroud)

setTimeout实际上需要一个函数作为参数,但是你让它立即调用.所以它立即记录了值i,而不是等待.setTimeout现在返回你的匿名函数作为第一个参数undefined.

和这里一样:

for(var i = 0; i < 10; i++) {
   setTimeout((function() {
     console.log(i);
   })(), 10)
}
Run Code Online (Sandbox Code Playgroud)

它立即执行,不等待10ms.您没有i作为参数传递的唯一区别,但它将在父作用域中查找名为的变量i- 并且只有一个.

如果将时间设置为例如一秒(1000),您将看到立即调用您的匿名函数.

真正的闭包看起来像这样:

没有参数:你会看到10次10​​,因为在执行内部函数时循环已经完成,这意味着当时我等于10:

for(var i = 0; i < 10; i++) {
   (function() {
        setTimeout(function() {
         console.log(i);
      },10);
   })();
}
Run Code Online (Sandbox Code Playgroud)

使用参数 - 您将获得预期的结果:

for(var i = 0; i < 10; i++) {
   (function(i) {
        setTimeout(function() {
         console.log(i);
      },10);
   })(i);
}
Run Code Online (Sandbox Code Playgroud)