循环let var
定义:
var、let、const
var :定义的变量没有块级作用域,是全局变量,而且在同一作用域下可以重复定义
let: 定义的变量有块级作用域,是局部变量,在同一作用域下不可重复定义,可被修改
const:经常使用const来定义常量,也是有块级作用域,是局部变量,在同一作用域下不可重复定义,也不可被修改。
let
个人理解:
先执行for循环,执行完for之后,执行其他,script结束后,执行setTimeout,
其中,for循环时每次都会把i定义一遍(let i=0/1/2/3/4)就会挂起,
let 在同一作用域下不可重复定义,可被修改,所以每次都未改变
相当于存到队列中,当执行setTimeout时,就从队列中释放出来i
先执行for内(a,b,d),再执行微任务(e),再执行宏任务(c)
代码实践:
for(let i=0; i<5; i++){
console.log(i,'aaa')//01234
console.log("bbb")
//let i = 0/1/2/3/4;挂起
//setTimeout是异步,所以先走for循环,当i=0的时候,循环一遍
setTimeout(()=>{
console.log(i,'ccc')//01234
},10);
console.log("ddd")
}
console.log('eee')
顺序:a,b,d,e,c
ccc结果:01234
var
个人理解:
1.只是setTimeout 是宏任务, 会在script代码段执行完同步代码后,
然后判断有没有微任务,没有就执行下一个宏任务,也就是setTimeout
因为这个时候循环已经完成了 所以是打印5 个 5
2.每次for循环的时候,先console ,然后遇到setTimeout时先挂起,
等for循环结束开始执行setTimeout
3.事件循环机制是从宏任务开始 script 是我们的第一个宏任务,
执行同步代码,碰到微任务就把微任务放到微任务队列,
等宏任务执行完成后,就把存放的微任务队列全部取出来执行掉,
然后再执行下一个宏任务
4.自己理解:先执行for循环,执行完for之后,执行其他,script结束后,执行setTimeout,
其中,for循环时每次遇到setTimeout就会挂起,setTimeout就有了5个,自己循环5次,
var在同一作用域下可以重复定义,所以最后var i获取最后得值
setTimeout循环时获取得是最终结果得i,所以5个5
相当于存到队列中,当执行setTimeout时,就从队列中释放出来
先执行for内(1,2,4),再执行微任务(5),再执行宏任务(3)
代码实践:
for(var i=0; i<5; i++){
console.log(i,'11')//01234
console.log("22")
//setTimeout是异步,所以先走for循环,当i=0的时候,循环一遍
setTimeout(()=>{
console.log(i,'33')//55555
},10);
console.log("44")
}
console.log('55')
顺序:1,2,4,5,3
33333结果:55555
如何解决var
解决办法:使用(function(){})()包裹setTimeout并传值
for(var i=0; i<5; i++){
// console.log('aaa')//这里不能放东西,因为它会使自执行函数报错
(function(i){
setTimeout(()=>{
console.log(i,'bbb')//01234
},10);
})(i)
console.log(i,'ccc')
}
console.log('ddd')
结果:c(01234),d,b(01234)
文章参考处:
https://blog.csdn.net/weixin_44099519/article/details/113769950
https://blog.csdn.net/qq_41476364/article/details/96492077
https://www.cnblogs.com/wxiaona/p/6016863.html