在循环中根据标准在 IIFE 中调用 setTimeout()

Invoke setTimeout() in IIFE against standard in a loop

IIFE函数背后的逻辑和setTimeout()循环背后的逻辑是什么。 有两个for:

for (var i = 0; i < 10; i++) {
  // Standard
  setTimeout(function() {
    console.log("Standard" + i);
  }, 1000 * i);
}

for (var j = 0; j < 10; j++) {
  // IIFE
  (function(j) {
    setTimeout(function() {
      console.log("IIFE " + j);
    }, 1000 * j);
  })(j);
}

现在当我 运行 和 node.js 时,我在 10 秒后得到这个结果(每个 console.log() 每秒执行一次):

谁能给我解释一下第一个函数和第二个函数调用之间的运行时间逻辑差异?

特别是如果你能回答这些问题:

提前致谢。

[编辑] 我不明白为什么在 for 中每秒都会触发 console.log() 但超时秒数 1000 * i|j 可能是可见的超时。

在第一个版本中,setTimeout 在触发时从父作用域引用变量 i,但到那时它已经改变了。

在第二个步骤中,您使用 j 参数创建了一堆新作用域,该参数不是对父作用域 j 变量的引用。因此当 setTimeout 触发时它没有改变。

为什么log在both for中都是每秒执行一次? (1000 * i|j 被忽略)

这是因为setTimeout()是一个异步函数。所以执行不会在这一步被阻塞,而是用给定的持续时间参数启动一个时钟,然后继续执行。一旦持续时间过去,事件就会被触发,回调被添加到事件循环队列中,以便一个一个地执行。

为什么我的值总是10?

这是因为closure的概念。当第一个 "Standard" 超时时,此时 i 的值已经是 10(此时所有 setTimeout 都已注册)。而在 IIFE 的情况下,j 是函数中的形式参数,它在每次迭代后接收循环计数器变量值。而这个函数中包含的setTimeout就是用这个j.