提出问题

首先这里有一个例子

  1. let i = 0
  2. for(i = 0; i<6; i++){
  3. setTimeout(()=>{
  4. console.log(i)
  5. },0)
  6. }

执行这段代码, 我们会发现结果是打印了6次6.
原因是循环中 i = 0 声明了 i, 这里默认是 var 定义, 而 setTimeout() 的效果是稍后执行, 而 Javascript引擎是单线程的, 一次只能进行一个操作, setTimeout()所以会在目前正在执行中的代码块执行完后才生效. 这里有6个 console.log(i)待执行, 但是在循环结束后 i 的值为6, 这时候执行 console.log(i) 当然会打印出6个6.

用 let 代替 var

把上面的代码改成

  1. for(let i = 0; i<6; i++){
  2. setTimeout(()=>{
  3. console.log(i)
  4. },0)
  5. }

就可以打印出 0, 1, 2, 3, 4, 5 的结果了.

使用立即执行函数

  1. for (var i = 0; i < 6; i++) {
  2. ! function () {
  3. var j = i;
  4. setTimeout(() => {
  5. console.log(j)
  6. }, 0)
  7. }(i)
  8. }

使 setTimeout()函数与循环结构中间多一层取反操作, 使它在中间这层取反操作结束后在下个循环开始前执行, 得出相同的结果: 0, 1, 2, 3, 4, 5.