1
for (var i = 0; i < 5; i++) {
    setTimeout(() => {
        console.log(i)
    }, 1000);
}

这道题挺经典的,输出结果是什么呢?结果是1000毫秒之后,输出5个5(隔一秒输出在1000上乘个i就行)
原因是,for循环在主线程内,setTimeout是异步方法,在任务队列里面,只有主线程执行完后,任务队列才执行,此时i的值已经是5,所以得到结果是5个5

那么怎么解决呢?其实思路很容易,只要每次循环把当前的i值传入setTimeout内即可

方法1:使用let

for (let i = 0; i < 5; i++) {
    setTimeout(() => {
        console.log(i)
    }, 1000);
}

使用let 相当于每次循环的时候都新建了1个i并为其赋值

方法2:定义函数并传值

for (var i = 0; i < 5; i++) {
    function a(i) {
        setTimeout(() => {
            console.log(i)
        }, 1000);        
    }
    a(i)
}

方法3:IIFE(立即执行函数)

for (var i = 1; i <= 5; i++) {
    ~function(i) {
        setTimeout(() => {
            console.log(i)
        }, 1000);
    }(i)
}

方法4:使用闭包

for (var i = 1; i <= 5; i++) {
    setTimeout(
        (i =>
            () => console.log(i)
        )(i), 1000);
}

方法5:setTimeout第三个参数传入i(是的,你没看错,setTimeout还有第三个参数)

for (var i = 1; i <= 5; i++) {
    setTimeout((i) => console.log(i),1000,i);
}

柳云落
2 声望0 粉丝

程序员