扫码关注官方订阅号
for(var i = 1; i<=5; i++){
setTimeout(function () { console.log(i); }, i*1000);
}这段代码中为何1000秒*i中的i的值为1
ringa_lee
首先问题问错了,你应该这么问:这段代码中为何1000秒*i中的i的值分别为1,2,3,4,5(或者为啥1秒输出一次),而最后打印的i是6
for(var i = 1; i<=5; i++){ setTimeout(function () { console.log(i); }, i*1000); }
从头来i=1,执行了
setTimeout(function () {console.log(i);}, i*1000);
注意是setTimeout()(函数的调用)的形式。所以i*1000是实参,需要找i的具体值,i=1,也就是执行了setTimeout(function () {console.log(i);}, 1*1000);而前面的function () {console.log(i);}只是声明了一个匿名函数作为setTimeout的第一个参数,作为回调函数等会执行。同样i=2,执行了setTimeout(function () {console.log(i);}, 2*1000);同样i=3,执行了setTimeout(function () {console.log(i);}, 3*1000);同样i=4,执行了setTimeout(function () {console.log(i);}, 4*1000);同样i=5,执行了setTimeout(function () {console.log(i);}, 5*1000);最后i++,i=6,不满足限制条件i<=5,停止循环,此时i=6然后等待事件队列中的回调函数执行。按照时间1s到了执行function () {console.log(i),去外部作用域查找i,i=6,输出6,2s,3s,4s,5s同理,所以输出5个6
setTimeout()
i*1000
i=1
setTimeout(function () {console.log(i);}, 1*1000);
function () {console.log(i);}
setTimeout(function () {console.log(i);}, 2*1000);
setTimeout(function () {console.log(i);}, 3*1000);
setTimeout(function () {console.log(i);}, 4*1000);
setTimeout(function () {console.log(i);}, 5*1000);
function () {console.log(i)
先去看下作用域的概念,再看下函数执行顺序,最后可以查查event loop。
解决方法:
for(var i = 1; i<=5; i++){ (function(i){ setTimeout(function () { console.log(i); }, i*1000); })(i); }
不加立即执行函数, 传入参数的话, 即原写法在setTimeout执行时for循环已经执行完毕, 最后一个一次执行时i=5 又++则为6楼上说的都对.
楼上已经说明了原因, 因为for循环执行完了,所以最后输出5个6可以使用闭包解决
for (var i = 1; i <= 5; i++) { (function(i){ setTimeout(function() { console.log(i); }, i * 1000); })(i) }
这样就可以利用闭包把每一次的 i 缓存起来
谈一下我的理解:
for(var i = 1; i<=5; i++){ setTimeout(function () { console.log(i); }, i*1000); // }
第一次运行时:
= 1。这个时候setTimeout要在 i * 1000毫秒后运行 function(){...}里的程序(下面简称闭包内程序)。好这个时候第一次运行结束。这个时候function(){...}还没有运行。
function(){...}
第二次运行时:这个时候,i = 2,没有看错,这个时候i是2,同里,setTimeout要在2秒后运行function(){...}
第3-5次(略)
由于你的机器很牛叉,这个循环只需要0.0000000000x秒就可以运行完毕。从启动开始,现在基本上程序运行了0.0000000000x。我们知道,第一次运行时设定的闭包内程序要在1秒后运行,对吗?到1秒的时候,i=6了,所以打印了一个6,第二次闭包内程序运行从程序开始运行后2秒开始,1秒和2秒之间差了1秒,同理3秒比2秒也多1秒……
画个图你就明白了:
如果按你的理解,5个6应该是在同1时间弹出,明白了?
不知道你那里出错了。最后输出的应该是6吧?
由于在console.log(i)执行的时候,for循环已经结束,而i等于6
i不是1,你循环的i是多少就是多少,是1~6。
你的问题不对。
1000 * i 中的i,分别为1、2、3、4、5。
1000 * i
i
console.log(i) 中的i只会输入6。
所以你这段代码会每隔1秒输出一个6,一共五次。
应该是每隔一秒打印出一个6吧,总共打印5个6;1000*i中的i的值为依次是1,2,3,4,5,并不一直是1,因为第一个6隔了1秒,第二个6隔了2秒...如果是1,就会变成
for(var i = 1; i<=5; i++){ setTimeout(function () { console.log(i); }, 1000); }
这样是一秒后同时打印5个6,效果是不一样的。
同楼上1000*i中的i 分别是1,2,3,4,5,在setTimeout函数中 表示1秒后、2秒后......5秒后执行console.log(i);最后console.log(i);输出的时候for循环已经结束 所以这里输出的i只能为6这段代码的执行结果为:
1000*i
setTimeout
console.log(i);
我不知道你说的i*1000;i=1是什么意思?你的这窜代码,一跑起来,其实是在循环完后,设置了5个计时器,分别为setTimeout(function () {
console.log(i);//这里外层的i已经循环完了,输出为6
}, 1*1000);setTimeout(function () {
}, 2*1000);...每个计时器调用一次就输出一次6,所以控制台是知道到连续输出5个6我比较好奇楼主你是怎么拿到那个i的?在计时器内部输出永远为6,在外部输出为1~5啊,你倒是让我模糊了
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
首先问题问错了,你应该这么问:
这段代码中为何1000秒*i中的i的值分别为1,2,3,4,5(或者为啥1秒输出一次),而最后打印的i是6
从头来i=1,执行了
注意是
setTimeout()(函数的调用)的形式。所以i*1000是实参,需要找i的具体值,i=1,也就是执行了setTimeout(function () {console.log(i);}, 1*1000);而前面的
function () {console.log(i);}只是声明了一个匿名函数作为setTimeout的第一个参数,作为回调函数等会执行。同样i=2,执行了
setTimeout(function () {console.log(i);}, 2*1000);同样i=3,执行了
setTimeout(function () {console.log(i);}, 3*1000);同样i=4,执行了
setTimeout(function () {console.log(i);}, 4*1000);同样i=5,执行了
setTimeout(function () {console.log(i);}, 5*1000);最后i++,i=6,不满足限制条件i<=5,停止循环,此时i=6
然后等待事件队列中的回调函数执行。
按照时间1s到了执行
function () {console.log(i),去外部作用域查找i,i=6,输出6,2s,3s,4s,5s同理,所以输出5个6
先去看下作用域的概念,再看下函数执行顺序,最后可以查查event loop。
解决方法:
不加立即执行函数, 传入参数的话, 即原写法
在setTimeout执行时for循环已经执行完毕, 最后一个一次执行时i=5 又++则为6
楼上说的都对.
楼上已经说明了原因, 因为for循环执行完了,所以最后输出5个6
可以使用闭包解决
这样就可以利用闭包把每一次的 i 缓存起来
谈一下我的理解:
第一次运行时:
= 1。这个时候setTimeout要在 i * 1000毫秒后运行
function(){...}里的程序(下面简称闭包内程序)。好这个时候第一次运行结束。这个时候function(){...}还没有运行。第二次运行时:
这个时候,i = 2,没有看错,这个时候i是2,同里,setTimeout要在2秒后运行
function(){...}第3-5次(略)
由于你的机器很牛叉,这个循环只需要0.0000000000x秒就可以运行完毕。从启动开始,现在基本上程序运行了0.0000000000x。我们知道,第一次运行时设定的闭包内程序要在1秒后运行,对吗?到1秒的时候,i=6了,所以打印了一个6,第二次闭包内程序运行从程序开始运行后2秒开始,1秒和2秒之间差了1秒,同理3秒比2秒也多1秒……
画个图你就明白了:
如果按你的理解,5个6应该是在同1时间弹出,明白了?
不知道你那里出错了。最后输出的应该是6吧?
由于在console.log(i)执行的时候,for循环已经结束,而i等于6
i不是1,你循环的i是多少就是多少,是1~6。
你的问题不对。
1000 * i中的i,分别为1、2、3、4、5。console.log(i) 中的
i只会输入6。所以你这段代码会每隔1秒输出一个6,一共五次。
应该是每隔一秒打印出一个6吧,总共打印5个6;
1000*i中的i的值为依次是1,2,3,4,5,并不一直是1,因为第一个6隔了1秒,第二个6隔了2秒...
如果是1,就会变成
这样是一秒后同时打印5个6,效果是不一样的。
同楼上
1000*i中的i 分别是1,2,3,4,5,在setTimeout函数中 表示1秒后、2秒后......5秒后执行console.log(i);最后
console.log(i);输出的时候for循环已经结束 所以这里输出的i只能为6这段代码的执行结果为:
我不知道你说的i*1000;i=1是什么意思?你的这窜代码,一跑起来,其实是在循环完后,设置了5个计时器,分别为
setTimeout(function () {
}, 1*1000);
setTimeout(function () {
}, 2*1000);
...
每个计时器调用一次就输出一次6,所以控制台是知道到连续输出5个6
我比较好奇楼主你是怎么拿到那个i的?在计时器内部输出永远为6,在外部输出为1~5啊,你倒是让我模糊了