如何在使用var时修复for循环中setTimeout的索引输出异常
解决var在for循环异步回调中索引异常的问题
因为var声明的变量属于函数作用域,整个init函数内只有一个index变量。setTimeout的回调是异步执行的,当所有回调触发时,for循环已经执行完毕,index的值已经变为5,所以所有回调都会打印5。
以下是几种不使用let的解决方案:
使用立即执行函数表达式(IIFE)创建独立作用域
function init() { for (var index = 0; index < 5; ++index) { (function(currentIndex) { setTimeout(() => { console.log(currentIndex); }, index); })(index); } }每次循环时,通过IIFE将当前
index的值传入,形成独立作用域,currentIndex会保留当前循环的索引值,回调访问的是该作用域内的变量。给setTimeout传递额外参数
function init() { for (var index = 0; index < 5; ++index) { setTimeout((currentIndex) => { console.log(currentIndex); }, index, index); } }setTimeout的第三个及后续参数会作为回调函数的参数传递,这样每个回调都会拿到当前循环的index值。利用bind绑定参数
function init() { for (var index = 0; index < 5; ++index) { setTimeout(console.log.bind(console, index), index); } }通过
bind方法给console.log绑定当前的index作为第一个参数,每个setTimeout的回调都是绑定了不同参数的函数,执行时会打印对应索引。使用Function构造函数(不推荐)
function init() { for (var index = 0; index < 5; ++index) { setTimeout(new Function('console.log(' + index + ');'), index); } }每次循环生成一个新函数,函数内部的索引是字符串拼接后的字面量值,会保留当前循环的索引。但这种方式可读性差,存在安全风险,不建议使用。
内容的提问来源于stack exchange,提问作者galhayne
相关产品推荐
相关产品推荐

