Js基础-闭包解决循环问题

50 阅读1分钟

问题描述

for(var i=0; i<3; i++) {
    setTimeout(() => {
      console.log("1:", i) // 3*3次
    }, 1000*i)
}
console.log("0:", i) // 3*1次
  • 原因分析
因为 setTimeout 是异步事件
var 声明的变量有提升的特性,会污染全局
setTimeout 执行完毕之后,此时i的值是3,所以全局的i的值是3

解决方案一

for(let i=0; i<3; i++) {
    setTimeout(() => {
      console.log("2:", i) // 0, 1, 2
    }, 1000*i)
}
console.log("3:", i) // 'i' is not defined
将声明关键字由 var 改成 let,每次循环都会创建新的作用域,i 在作用域中会更新
let 声明变量创建局部作用域,所以在外面 i 获取不到

解决方案二

for(var i=0; i<3; i++) {
    ((i) => {
      setTimeout(() => {
        console.log("4:", i) // 0, 1, 2
      }, 1000*i)
    })(i)
}
利用自执行函数的作用域,将每次循环的 i 保存到作用域中,可以输出我们想要的结果