javascript - js中循环语句的执行结果
伊谢尔伦
伊谢尔伦 2017-04-11 11:06:08
[JavaScript讨论组]
for (var i = 0; i < 3; i++) {
    setTimeout(function() {
        console.log(i);
   
    }, 0);
    console.log(i);
}

请教下这段代码的执行结果是多少,求一份指导过程。

伊谢尔伦
伊谢尔伦

小伙看你根骨奇佳,潜力无限,来学PHP伐。

全部回复(6)
PHP中文网

settimeout是要等当前事件执行完之后马上执行,所以在循环中只是将它加入到事件队列中,等循环执行完之后才会调用。三次循环分别输出1,2,3而此时i=3.所以输出3

ringa_lee

直接用Google的Console执行你就知道了。如

ringa_lee
var i;
for (i = 0; i < 3; i++) {
    // 定时器会放在 event loop 里面,定时器到的时候触发事件,执行定时器里面的函数
    // 执行定时器的函数时,js 主线程已经执行完毕,这时 i 已经设置为 3.
    setTimeout(function() {
        console.log(i);
    }, 0);
    
    // 上面的代码不会影响 js 主线程的执行,所以会先打印出 i。
    console.log(i);
}
阿神

先看结果,这段代码执行的时候是这个样子:

var i;
for (i=0; i < 3; i++){
    console.log(i) //结果是0,1,2
}

console.log(i)  // 3
console.log(i)  // 3
console.log(i)  // 3

原因是多个js的特性组成的:

1、 var i; 是因为js里面变量提前声明,这个很多面试题都会考到。

2、 setTimeout 机制,不会在主线程中执行, 而是放到event loop, 表示要等主线程的程序执行完了,才能开始执行 loop 里面的代码,也就是 3个 console放到了最后的原因

3、 变量的作用域,这个里面i的作用域包含了全部,所以最后的console时候,i的值已经变成了3

天蓬老师
  1. setTimeout()计划在未来的某个时间点运行,之所以说“计划”是因为js是运行在单线程环境中的,虽然setTimeout()是在语句之后立即开始计时,但是最差也必须等待主线程运行完毕才会去运行延时函数里面的代码。

  2. 在这里,变量i的作用域是整个函数,当setTimeout()内代码运行的时候,循环已经结束,此时i=3,输出当然是3。

  3. 如果你想要延时输出0、1、2,你需要用闭包来保存当前的i的值。

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

//如果是es6,有了块级作用域,就不需要用立即执行函数来隔绝作用域了,也可以直接这么写。
for(let i = 0; i < 3; i++) {
    setTimeout(function(){
        console.log(i);
    }, 0);
    console.log(i);
}
ringa_lee

0,1,2,3,3,3

当然是3啦,,JS的异步执行机制,setTimeout会将加入其中的事件放入到一个事件队列中去,等到所有代码执行完,再去事件队列中询问:“还有没有需要执行的事件呀?~”,然后事件队列就会依次出队列执行,此时的i是全局变量,已经变成3了,所以,打印出来也是3咯

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

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