一文读懂异步在for循环下的不同表现

// var出的变量是函数级作用域,
// 作用范围是在函数开始阶段和函数执行完成之前内都是存在的;并且如果该函数内部还存在匿名函数等特殊函数,这个var出的变量在匿名函数中任然可以用; 
// let出的变量作用域是 块作用域,在离开某一代码块,该变量就会被销毁不存在. 



//这段代码的步骤简述
//0.创建一个var i到顶部,这个时候的i是个全局变量,因此只有一个全局变量i,此处可以了解百度 “js声明提前”
//1.先for循环,当遇到setTimeout时,因为for循环时同步的,setTimeouts属于异步,
//      异步简单说就是同步都执行好了,才执行异步队列

//2.于是for循环一直到9,循环期间生成了十个任务队列,也就是十个定时器,
// 此时的十个定时器里的i,指向全局变量i,也就是说,for循环i=0时,settiemout传入的i确实是0;因为就一个全局变量i
// 但是当for循环i=1时,上一个for循环i=0的settimeout的i==0,又跟着变成1,原因还是因为就一个全局变量
//
//3.for循环到9时,(var i = 9; 9 <10; 9++)此时生成了十个任务队列(0-9)
//
//4.这个时候var i = 10; 10 <10; 于是下面的代码不再执行,也就是说说for循环同步结束时,i==10
//
//5.for循环结束,开始执行异步也就是setTimeout
//PS:为什么这个时候还能获取到i==10呢;因为  
//var的变量是函数级作用域,作用范围是在函数开始阶段和函数执行完成之前内都是存在的;
//所以最后就是弹出(0-9)10个10
for (var i = 0; i <10; i++) {
  setTimeout(function() {
    alert(i)
  }, 0);
}
//10 10 10 10 10 10 10 10 10 10



//for循环有一个特别之处,就是设置循环变量那部分是一个父级作用域,而循环体内部是一个单独的子作用域

//1.先for循环,此时会创建一个块级作用域。里面的i=0;于是settiemout传入的i是0,生成一个任务队列
// let 声明不会被提升到当前执行上下文的顶部,let声明的变量只在它所在的代码块有效,
// 也就是说不会像for循环那样只有一个全局变量i,而是会生成10个i



//2.for循环一直到9,期间i的值一直都在变化,所以传入的值都不一样

//因为每次循环都会创建一个块级作用域,并且存上i的值(0-9),当前的i只在本轮循环有效,所以i++后每一次循环的i其实都是一个新的变量

// 循环期间生成了十个定时器存入任务队列,此时的十个定时器里的i,指向i++后不同的i,



//3.异步的settimeout开始运行,因为之前传入了i。所以此时就弹出0 1 2 3 4 5 6 7 8 9
for (let i = 0; i <10; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}
// //0 1 2 3 4 5 6 7 8 9
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值