search

Home  >  Q&A  >  body text

javascript - js pitfall question: What is the reason why the result of the setTimeout() function is five 6s after execution?

The reason why the result of the setTimeout() function is five 6s after execution?

 for (var i = 1; i <= 5; i++) {
        setTimeout(function timer() {
            console.log(i);
        }, i * 1000);
    }
// 其实我们想得到的结果是1,2,3,4,5,结果却是五个6

Although I solved the problem using js closure and got the desired 1, 2, 3, 4, 5, I still don’t understand why five 6s appear in the above code?

 for (var i = 1; i <= 5; i++) {
        (function(j) {
            setTimeout(function timer() {
                console.log(j);
            }, j * 1000);
        })(i);
        
//通过一个立即执行函数,为每次循环创建一个单独的作用域
黄舟黄舟2791 days ago808

reply all(3)I'll reply

  • PHPz

    PHPz2017-05-19 10:49:29

    The first thing you need to understand is that the task mechanism of JS is the queue mechanism.

    So instead of running a for loop, we just put the setTimeout task at the back of the queue. That is, the code executed in setTimeout will only be executed after the for loop is executed, so the value of i at that time is the value that does not satisfy the for loop. , will execute the setTimeout code.

    Personal opinion, please point out if there is anything wrong

    reply
    0
  • 天蓬老师

    天蓬老师2017-05-19 10:49:29

    var can be changed to let

    var is a global definition, i does not form a closure, and log(i) prints the final value of i 6

    let is a block-level domain

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

    reply
    0
  • 为情所困

    为情所困2017-05-19 10:49:29

    setTimeout has two characteristics, its this is separated from the context's this, and its call is asynchronous.

    This is caused by [asynchronous], the for loop will be completed first, and then setTimeout will be executed, because the for loop will be 6 at the end every time it is executed - so naturally when setTimeout calls i, it will be five 6

    Solution 1:

    var 换 let

    Solution 2:

    楼主自己用的闭包

    Solution 3:

    //类似于方法二,使用setTimeout的第三个参数直接传参
      for (var i = 1; i <= 5; i++) {
        setTimeout(function(i) {
          console.log(i);
        }, i * 1000,i);
      }

    reply
    0
  • Cancelreply