js中如何解决for循环输出问题的几种方法

  • Post author:
  • Post category:其他



观察以下代码:

for(var i = 1; i <= 5; i ++){
    setTimeout(function timer(){
        console.log(i)  //i = 6
    }, 0)
}


问题描述:


为什么会全部输出6?如何改进,让它输出1,2,3,4,5?


原因:

因为

setTimeout

为宏任务,由于JS中单线程

eventLoop

机制,在主线程同步任务执行完后才去执行宏任务,因此循环结束后

setTimeout

中的回调才依次执行,但输出 i 的时候当前作用域没有,往上一级再找, 发现了 i ,此时循环已经结束,i 变成了6。因此会全部输出6。


解决方法:

1、利用

IIFE

(立即执行函数表达式)当每次

for

循环时,把此时的i变量传递到定时器中

for(var i = 1;i <= 5;i++){
    (function(j){
        setTimeout(function timer(){
        console.log(j)
        }, 0)
    })(i)
}

2、给定时器传入第三个参数, 作为

timer

函数的第一个函数参数

for(var i=1;i<=5;i++){
    setTimeout(function timer(j){
        console.log(j)
    }, 0, i)
}

3、使用

ES6

中的

let

for(let i = 1; i <= 5; i++){
    setTimeout(function timer(){
        console.log(i)
    },0)
}

let使JS发生革命性的变化,让JS有函数作用域变为了块级作用域,用let后作用域链不复存在。代码的作用域以块级为单位,以上面代码为例:

// i = 1
{
    setTimeout(function timer(){
        console.log(1)
    },0)
}
// i = 2
{
    setTimeout(function timer(){
        console.log(2)
    },0)
}
// i = 3
...

因此能输出正确的结果1,2,3,4,5。完美解决!



版权声明:本文为weixin_48005981原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。