循环内使用setTimeout无法打印变量值?求解决方案
问题代码
function x(){ for(var i=1;i<=5;i++){ setTimeout(function (i){ console.log(i) },i*1000) } } x();
为什么打印undefined?
你在setTimeout的回调函数里声明了参数i,但触发回调时没有给它传递任何值,所以这个参数i自然就是undefined。
顺带提一句:就算你去掉回调里的i参数,结果也会是连续打印5个6——因为var声明的i是函数作用域的,循环结束后i的值已经变成6,而setTimeout是异步执行的,等它触发回调时,循环早就跑完了。
解决方法
给你几种实用的写法:
1. 用let代替var(ES6+推荐写法)
let是块级作用域,每次循环都会创建一个独立的i变量,回调能捕获到当前循环的那个i值:
function x(){ for(let i=1;i<=5;i++){ setTimeout(function (){ console.log(i) },i*1000) } } x();
2. 立即执行函数创建闭包(兼容旧环境)
给每个回调单独绑定当前循环的i值,避免后续循环修改影响:
function x(){ for(var i=1;i<=5;i++){ (function(currentI){ setTimeout(function (){ console.log(currentI) },i*1000) })(i) } } x();
3. 利用setTimeout的第三个参数传值
setTimeout从第三个参数开始,可以直接作为回调的参数传递:
function x(){ for(var i=1;i<=5;i++){ setTimeout(function (currentI){ console.log(currentI) },i*1000, i) } } x();
内容的提问来源于stack exchange,提问作者Gagan baghel
相关产品推荐
相关产品推荐

