【问题标题】:immediately-invoked function calling setTimeout calling for loop立即调用的函数调用 setTimeout 调用循环
【发布时间】:2020-01-02 06:16:57
【问题描述】:

在以下场景中,事件setTimeout 进入队列,只有在堆栈清空后,i = 3 才会打印 3 次

//ver1
for (var i = 0; i < 3; i ++ ) setTimeout(()=> console.log(i), 3)

以下将按顺序打印1 2 3,因为i 是在func x 中捕获的??

//ver2
for (var i = 0; i < 3; i++) {
    (function x(i) {
        setTimeout(() => {console.log(i)}, 30)
    })(i);
}

为什么下面只打印一次2

//ver3
for (var i = 0; i < 3; i++) {
    function x(i) {
        setTimeout(() => {console.log(i)}, 30)
    }(i);
}

我对@9​​87654332@ 和ver3 很困惑


编辑: ver2 解释可以找到here。关于为什么ver3 只打印2 的任何见解?

【问题讨论】:

标签: javascript scope closures


【解决方案1】:

您的版本 3 完全没有您认为的那样。 Parenthesis are not optional on an IIFE。但是因为你命名了这个函数,它确实被解析为一个函数声明:

for (var i = 0; i < 3; i++) {
    function x(i) {
        setTimeout(() => {console.log(i)}, 30)
    }
    (i);
}

你从来没有在这里打电话给x(…)(i) 只是一个评估 i 变量的不必要的parenthesised 表达式。您的代码执行与

相同
for (var i = 0; i < 3; i++) {
    i;
}

那么为什么这会在控制台中记录2?因为当您在控制台上运行它时,它会打印最后一次评估的语句的结果值:i,它在循环的最后一次迭代中具有值2

【讨论】:

  • 这很有意义..谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-22
  • 1970-01-01
  • 1970-01-01
  • 2016-08-11
  • 2015-02-22
相关资源
最近更新 更多