它打印了10次,我不明白为什么

It prints 10 ten times i cannot understand why?

本文关键字:明白 为什么 打印 10次      更新时间:2023-09-26
var i;
var print = function(){
  console.log(i);
};
for(i = 0 ; i<10;i++){
 setTimeout(print,1000);
};

它打印了10次,我不明白为什么?

setTimeout是一个异步调用。这意味着,它只有在整个循环被执行之后才被执行。在你的JS解释器中,它会是这样的:

 1: for loop.                               // i = 0
 2: send setTimeout #1.     increment i.    // i = 1
 3: send setTimeout #2.     increment i.    // i = 2
 4: send setTimeout #3.     increment i.    // i = 3
 5: send setTimeout #4.     increment i.    // i = 4
 6: send setTimeout #5.     increment i.    // i = 5
 7: send setTimeout #6.     increment i.    // i = 6
 8: send setTimeout #7.     increment i.    // i = 7
 9: send setTimeout #8.     increment i.    // i = 8
10: send setTimeout #9.     increment i.    // i = 9
11: send setTimeout #10.    increment i.    // i = 10
12: finish for loop.                        // i = 10
13: exec setTimeout #1.                     // i = 10
14: exec setTimeout #2.                     // i = 10
15: exec setTimeout #3.                     // i = 10
16: exec setTimeout #4.                     // i = 10
17: exec setTimeout #5.                     // i = 10
18: exec setTimeout #6.                     // i = 10
19: exec setTimeout #7.                     // i = 10
20: exec setTimeout #8.                     // i = 10
21: exec setTimeout #9.                     // i = 10
22: exec setTimeout #10.                    // i = 10

当执行阶段发生时,i将已经有10。

正确的方法是使用闭包。它们通过封装变量的值来保持环境值。

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

这是因为JavaScript事件循环。所有的setTimeouts都堆叠在事件循环队列的末尾。一旦for循环完成(当我已经增加到10时(,所有setTimeouts都开始执行。因此,你可以看到10一直在打印。

n值是从闭包中选取的。在创建函数时,它包含值=1,2,3。

var i ;
var print = function(n){
  console.log(n);
};
for(i = 0 ; i<10;i++){
 setTimeout((function(n){
   return function () {
     print(n);  
   }
 })(i),1000);
};