函数调用的时机不同,运行结果也不同。
为什么如下代码会打印 6 个 6,而不是 0,1,2,3,4,5?
/* 例 1 */let i = 0for(i = 0; i<6; i++){setTimeout(()=>{ // 延时函数console.log(i)},0)}
setTimeout() 函数是干嘛的?
MDN 给出的描述是:
**setTimeout()**方法设置一个定时器,该定时器在定时器到期后执行一个函数或指定的一段代码。白话理解:
- 凡是放在这个函数中的东西,都过一会再做,至于过多久,可以通过设定毫秒数来调节。
😉 如果 **setTimeout** 延时设置为 0 呢?
- 如代码例 1 中
**setTimeout**作为延时函数设置延时为 0 时,意思是尽快执行完 for 循环,然后立马执行setTimeout打印出i的值。 - 循环执行完时
i = 6,由于for循环了6次,也就是i = 6之后再去打印 6 次i,所以打印结果为 6 个 6
如何让例 1中的代码 打印出 0,1,2,3,4,5?
/* 把 let 直接写到 for 循环里 */for(let i = 0; i<6; i++){// let i = 隐藏作用域中的isetTimeout(()=>{console.log(i)},0)} // 打印结果为 0,1,2,3,4,5
在 for循环表达式中使用 let声明表达式变量
**for( let i = 0; i< 6; i++)**这句话的圆括号之间,有一个隐藏的作用域。**for( let i = 0; i< 6; i++) { 循环体 }**在每次执行循环体之前,JS 引擎会把**i**在循环体的上下文中重新声明及初始化一次。- 因为
**let**有自己的作用域块,所以在 for循环表达式中使用**let**它的每一个值都会单独存在一个独立的作用域中不会被覆盖掉。- 每次进入
for循环时都把i复制一份,就是第一次循环把i留在这个空间,后面的每一次都这样操作就有 6 个新的i,再加上本身i = 0的这个i,一共就有 7 个i。 - 这样就是
i从 0 到 6,每次都把i打出来,最后就是打出 0~5 ,因为i = 6时就跳出了循环。参考资料: 方方:我用两个月的时间理解 let
- 每次进入
除了使用 for let 配合,还有什么其他方法可以打印出 0、1、2、3、4、5?如下:
/* 1.闭包 */let ifor(i = 0; i<6; i++){!function(j){setTimeout(()=>{console.log(j)},0)}(i)} // 打印: [0,1,2,3,4,5]
/* 2.数组的push */var arr1 = [];var n = 0;for(var i = 0; i<6; i++){n += 1;arr1.push(n-1)}console.log(arr1) // 打印: [0,1,2,3,4,5]
/* 3.利用 setTimeout 的第三个参数,将i传进去 */let ifor(i = 0; i<6; i++){setTimeout((value)=>{console.log(value)},0,i)} // 打印: [0,1,2,3,4,5]
/* 4.利用 const 关键字 */let ifor(i=0; i<6; i++){const x = isetTimeout(() => {console.log(x)})}
