在不同的情况下,js的函数会有不同结果
例:
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
//6 6 6 6 6 6
这段代码的结果是6个6,而不是我们潜意识认为的0~5,这是为什么呢?
这是因为上面代码中含有setTimeout函数,这个函数的意思简单理解为就是过一会执行里面的代码,可以自己设定过多长时间来执行,单位为毫秒
原因
因为setTimeout是异步执行的,就是过一会儿再执行。所以在上面for循环中每次循环setTimeout都会执行一次,但是里面的函数没有执行。它会被放进任务队列,而for循环完后,setTimeout会执行里面的函数,从而打印出6个6
其它方法打印出0~5
1. 在for循环中使用let
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
// 0 1 2 3 4 5
这是将i绑定到for循环中,而每一次循环中的i都是新的i,每次循环JS都会记住这个值,然后复制,下次循环在这个值的基础上进行重新计算。这样for循环结束后,steTimeout打印i的值便是0~5
2. 使用闭包
for (var i=0; i<6; i++) {
(function(j) {
setTimeout(()=> {
console.log( j );
}, j*1000 );
})(i);
}
//0 1 2 3 4 5
因为实际参数与定时器i有强依赖,通过闭包,让i的变量留在内存中,输出j时,引用外部i的变量,而i值在每次循环中都确定了。所以会输出0~5
3. 使用steTimeout的第三个参数
for (let i=0; i<6; i++) {
setTimeout( function timer() {
console.log( i );
}, 0, i );
}
每次传入的参数都是for循环中i的值,所以会输出0~5
注意
方法2和方法3是网上寻找的,某些具体原理并不知晓,可能以后理解后再单独阐述