本文共 921 字,大约阅读时间需要 3 分钟。
setTimeout运行机制的问题:定时函数被加入执行队列,等主程序运行完毕时,此时再调用定时函数,i的值已经变为4,四次的定时函数都会共用i=4这个值。
for(var i=0; i<4;i++){ setTimeout(function(){ console.log(i); },100)}// 打印结果:4 4 4 4
(1)let
for循环头部的let不仅将i绑定到for循环中,它还将i重新绑定到循环体的每一次迭代中,确保上一次迭代结束的值重新被赋值。通过let声明块变量i,能作用于这个块。利用了let的块级作用域。
for(let i=0; i<4;i++){ setTimeout(function(){ console.log(i); },100)}// 打印结果:0 1 2 3
(2)拆分结构
将setTimeout进行封装,此时定时函数的变量作用域就变为f函数代码块内,每次for循环传给定时器的i值都会变为定时函数的私有变量值,这样就达到了预期目的。
for(var i=0; i<4;i++){ f(i);}var f = function(i){ setTimeout(function(){ console.log(i); },100)}// 打印结果:0 1 2 3
(3)闭包
通过闭包,将i的变量驻留在内存中,当输出j时,引用的是外部函数的变量值i,i的值是根据循环来的,执行setTimeout时已经确定了里面的的输出了。
for (var i = 0; i < 4; i++) { (function (j) { setTimeout(function () { console.log(j); }, 100) })(i); } // 打印结果:0 1 2 3
(4)setTimeout第三个参数(可能解决不了)
由于每次传入的参数是从for循环里面取到的值,所以会依次输出
转载地址:http://norti.baihongyu.com/