javascript - 一道JS题目
巴扎黑
巴扎黑 2017-04-11 13:19:45
[JavaScript讨论组]
for (var i=1;i<=5;i++) {
                setTimeout(function(){
                    console.log(i)
                },i*1000)
            }
for循环语句是如何运行的呢?为什么会输出5个6呢?
巴扎黑
巴扎黑

全部回复(6)
PHP中文网

闭包,闭包,闭包的问题!

通过上面的代码,可以看出只定义了一个变量 i ,只有在循环里面赋值为1~5,循环结束后是 6
setTimeout中的代码是在循环之后执行的,所以输出的i是 6。而不是你所想的。
因为 i 只有一个,不可能同时等于 1,2,3,4,5.

可以改成(建议先理解上面一段代码,先不要纠结ES6的):

for (var i=1;i<=5;i++) {
    (function(){
        var j = i;
        setTimeout(function(){console.log(j)},
                    j*1000);
    })();    
} 
\\ 或 ES6
for (let i=1;i<=5;i++) {
    setTimeout(()=>console.log(i),i*1000);
}
大家讲道理

因为 setTimeout 是异步的啊,当你执行完 for 的时候,设定了 5个setTimeout,分别延迟 1至5秒,
执行完 for后,i的值为 6,然后你会看到,每隔一秒输出1个6,一共5个

巴扎黑

这是闭包问题,

  for (var i=1;i<=5;i++) {
            setTimeout(test(i),i*1000)
        }

function test(i){

console.log(i)

}

或者
for (var i=1;i<=5;i++) {
            setTimeout((function(x){
                return function(){
                    console.log(x)
                }
            })(i),i*1000)
        }

循环里面套函数都会产生这种闭包问题

阿神

这个题的重点在于, setTimeout是需要等到你的主程序执行流执行完了后才执行.

一开始, 程序从for开始执行, 遇到setTimeout的时候先不管, 继续往后执行, 一直执行到循环结束.
好了, setTimeout可以执行啦. 连续六个setTimeout打印出i, 而此时的i已经是6啦.

高洛峰

这是由于js没有块级作用域造成的,而不是for循环的问题.

先看这个例子:

var i = 1;
{
  var i = 2;
}
console.log(i);

输出的结果是:2.就是说{}中定义的变量i会取代{}外面的变量i,即没有块级作用域.

每执行一次就相当于执行了一次上面的代码,最后循环中的i是5,又执行了一次i++,所以变成了6;

怪我咯

判断当前i的值是否小于等于5,是的话就加1,因为你用了setTimeout,所以一秒后i的值已经变成6了,再输出的话,就一直是6了

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号