在下面的代码片段中,6被打印了5次。请解释一下这种输出行为。
对于每个i,我都会调用settimeout函数,因此console.log应该具有i的值。代码:
for(var i = 1;i <= 5;i++) {
setTimeout(function() {
console.log("i:" + i);
},i*1000);
}
文书主任6 6 6
O/P预期为%1%2%3%4%5
发布于 2017-01-25 19:37:02
即使超时0也会产生相同的结果,要理解这一点,你必须理解事件循环中的回调概念。理想情况下,回调只在堆栈为空的时候执行,js代码的执行是基于堆栈的,我指的是执行上下文,所以当你在这里说一个for循环时,它意味着第一个i被推入堆栈,所以现在堆栈处理这个变量,当它涉及到回调(setTimeout)时,它存储的增量值是一个事件循环。
在event-loop中运行块的唯一方法是当你的堆栈为空时,即当你的循环结束时,因为它是一个闭包函数,所以它保留了最后一个值,其中所有的日志都被打印出来了。
参见示例,您将看到1到6个外部回调,因为它在堆栈中执行,但只有在堆栈为空时才会进行回调。
如果您想更好地理解执行上下文,请转到loupe并复制、粘贴您的js代码以查看操作。
for(var i = 1;i <= 5;i++)
{
console.log(i)
setTimeout(function(){
console.log("i:" + i);
},0
);
}
发布于 2017-01-25 19:35:17
这是因为该函数在for循环的相同作用域中使用变量
在执行setTimeout函数时,作用域中的变量i已经更改了值,因此所有计时器都将打印循环的最后一个值
尝试将i值作为setTimeout的参数传递,以便立即对其求值,并且函数可以使用其自身作用域中的值,而不会有任何副作用
for(var i = 1;i <= 5;i++)
{
setTimeout(function(a){
console.log("i:" + a);
},i*1000,i
);
}
发布于 2017-01-25 19:34:05
在js中,变量具有块/函数作用域,并且setTimeout异步工作。
https://stackoverflow.com/questions/41850424
复制相似问题