for (var i=1;i<=5;i++) {
setTimeout(function(){
console.log(i)
},i*1000)
}
for循环语句是如何运行的呢?为什么会输出5个6呢?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
闭包,闭包,闭包的问题!
通过上面的代码,可以看出只定义了一个变量
i,只有在循环里面赋值为1~5,循环结束后是 6。而
setTimeout中的代码是在循环之后执行的,所以输出的i是 6。而不是你所想的。因为 i 只有一个,不可能同时等于
1,2,3,4,5.可以改成(建议先理解上面一段代码,先不要纠结ES6的):
因为
setTimeout是异步的啊,当你执行完for的时候,设定了 5个setTimeout,分别延迟1至5秒,执行完
for后,i的值为 6,然后你会看到,每隔一秒输出1个6,一共5个这是闭包问题,
function test(i){
}
循环里面套函数都会产生这种闭包问题
这个题的重点在于, setTimeout是需要等到你的主程序执行流执行完了后才执行.
一开始, 程序从for开始执行, 遇到setTimeout的时候先不管, 继续往后执行, 一直执行到循环结束.
好了, setTimeout可以执行啦. 连续六个setTimeout打印出i, 而此时的i已经是6啦.
这是由于js没有块级作用域造成的,而不是for循环的问题.
先看这个例子:
输出的结果是:2.就是说
{}中定义的变量i会取代{}外面的变量i,即没有块级作用域.每执行一次就相当于执行了一次上面的代码,最后循环中的i是5,又执行了一次i++,所以变成了6;
判断当前i的值是否小于等于5,是的话就加1,因为你用了setTimeout,所以一秒后i的值已经变成6了,再输出的话,就一直是6了