猿问

有人可以帮助解释 for 循环中的 setTimeout 是如何工作的吗?这和闭包有关系吗

var result = 0;


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

  setTimeout(function() {

    result += i;

  }, 1000);

}

为什么结果会等于 9 而不是 3?


回首忆惘然
浏览 186回答 2
2回答

噜噜哒

您得到 9 是因为您要添加result到循环计数器i中,并且每次循环迭代时这两个数字都会增加。如果您只希望最终答案为 3,那么您根本不需要result并且可以在循环的最终迭代时报告循环计数器的值。目前尚不清楚您的目标是什么,但是当人们想要重复完成某件事时,通常会认为计时器属于循环。计时器可以做到这一点,而无需任何循环通过setInterval()计时器或递归setTimeout()计时器来帮助它。两种方法如下所示:递归 setTimeout() 定时器:var result = 0;function timerCallback(){&nbsp; if(result < 3){&nbsp; &nbsp; console.log(++result);&nbsp; &nbsp; // A second timer is embedded in the&nbsp; &nbsp; // first timer's callback function.&nbsp; &nbsp; // This second timer calls the current&nbsp; &nbsp; // function, setting up a looping flow.&nbsp; &nbsp; setTimeout(timerCallback, 1000);&nbsp; }}// Start a one time timersetTimeout(timerCallback, 1000);setInterval() 定时器:var timer = null; // Will hold reference to timer's idvar result = 0;function timerCallback(){&nbsp; if(result < 3){&nbsp; &nbsp; console.log(++result);&nbsp; } else {&nbsp; &nbsp; // Cancel timer&nbsp; &nbsp; clearInterval(timer);&nbsp; }}// Start a timer that continues// until it is stopped.timer = setInterval(timerCallback, 1000);

摇曳的蔷薇

当你写var result = 0;for (var i=0; i < 3; i++) {&nbsp; setTimeout(function() {&nbsp; &nbsp; result += i;&nbsp; }, 1000);}因为 javascript 变量提升它变成了var result = 0;var i;for (i=0; i < 3; i++) {&nbsp; setTimeout(function() {&nbsp; &nbsp; result += i;&nbsp; }, 1000);}var i移动到顶部。setTimeout并且由于javascript是非阻塞的,因此在调用堆栈中没有更多阻塞操作(即循环结束后)之后,您的情况下的所有异步代码都将执行。当循环结束i is 3时result += 3,执行 3 次,结果变为 9但是,如果您希望它是我可以从下面的问题中看到的result += 0;result += 1;result += 2;结果 3那么你可以通过closurevar result = 0;for (var i=0; i < 3; i++) {&nbsp; const j = i;&nbsp; setTimeout(function() {&nbsp; &nbsp; result += j;&nbsp; &nbsp; console.log(result);&nbsp; }, 1000);}在这种情况下,最终结果将是 3这里发生的是,j声明将在每次循环迭代中对 i 的值进行闭包,并且每次迭代的 setTimeout 将记住它们在迭代时附加的 j 的值。希望这可以帮助
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答