1 解释为什么如下代码会打印 6 个 6
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
这是因为循环先执行完,此时i=6,for循环停止并退出,只有1个i,再去打印出6次。 setTimeout就是尽快,但不是现在,而是忙完手头事情立即做的事
setTimeout函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号;
setTimeout(func|code, delay)
setTimeout函数接受两个参数,第一个参数func|code是将要推迟执行的函数名或者一段代码,第二个参数delay是推迟执行的毫秒数,根据HTML5标准,delay最少是4毫秒。如果小于这个值,会被自动增加到4ms。
setTimeout(f,0)或写为setTimeout(()=>{},0),将第二个参数设为0,作用是让f在现有的任务(脚本的同步任务和“任务队列”中已有的事件)一结束就立刻执行。也就是说,setTimeout(f,0)的作用是,尽可能早地执行指定的任务。
setTimeout(function (){
console.log("你好!");
}, 0);
上面代码的含义是,尽可能早地显示“你好!”。 setTimeout(f,0)指定的任务,最早也要到下一次Event Loop才会执行。
2 写出让上面代码打印 0、1、2、3、4、5 的方法:
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
这是因为JS在for和let在一起用的时候,每次循环会多创建一个i,也就是把i复制了6遍。 变量i是let声明的,当前的i只是本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。JS引擎内部会记住上一轮循环的值,初始化本轮的 变量i时,就在上一轮循环的基础上进行计算,所以就算是for和setTimeout()执行的顺序不变,但是打印输出的还是本次循环i的值
3 除了使用 for let 配合,还有什么其他方法可以打印出 0、1、2、3、4、5
一种是利用setTimeout的第三个参数:
for (var i=0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0,i)
}
另外一种是利用闭包:
for (var i=0; i<6; i++){
!(function(j){
setTimeout(()=>{
console.log(j)
},0)
})(i)
}