JavaScript 解决循环打印问题
题目分析
以下代码运行后会打印出什么?
1 |
|
答案:66666
虽然每个for
循环中定时器设置的时间都是0,但由于 JavaScript 是单线程 eventLoop 机制,setTimeout
是异步任务,遇到setTimeout
函数时,JavaScript 会将其放入任务队列中,待同步任务执行完毕后,才执行任务队列中的异步任务。
又因为setTimeout
函数也是一种闭包,往上找它的父级作用域链是window
,而变量i
是用var
声明的,是window
上的全局变量,所以此时变量i
的值已经变成i = 6
了,最后执行setTimeout
时,当然会输出5个6了!
解决办法
如果就是要输入1 2 3 4 5,该怎么办呢?
立即执行函数
立即执行函数可以锁定参数值,传入每次循环的当前索引,从而锁定索引值。
1 |
|
使用 let 声明(块级作用域)
利用 JavaScript 的块级作用域,就不用这么麻烦了。如果 for 循环使用块级作用域变量关键字,循环就会为每个循环创建独立的变量,从而每次打印都会有正确的索引值。
1 |
|
定时器传入第三个参数
一般我们使用setTimeout
都会使用2个参数,回调函数和延迟时间,但setTimeout
是有第三个参数的。
一旦定时器到期,会将第三个参数作为参数传递给回调函数。这样打印时,也能得到正确的索引值。
1 |
|
使用 Promise
在任务队列tasks
中,依次存放Promise
,其中传入相应的i
,异步操作完成之后,输出最后的i
。
1 |
|
版权声明
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 协议 ,转载请注明出处!
JavaScript 解决循环打印问题
https://www.xukaiyyds.cn/posts/eeb964bd/