js的for循环中有关var和let的疑难知识点

在楼主最近学习js中碰到一些小问题,楼主用自己学到的知识对此进行了解答,可能知识掌握运用的不是很牢固,可能楼主的解答在一些大佬眼里会存在纰漏,如果有大佬替楼主指正,楼主先在此谢过。

首先我们来了解一下js中 var 和 let 的不同,var 会变量提升,let 由于暂时性死区 不会存在变量提升这种东西。
那我们先来聊聊变量提升这个东西
举个例子:
console.log(a);
var a = 1; //输出的结果是undefined
如果是
console.log(b);
let b = 1;//浏览器控制台内就会报错
之所以产生这种差异,就是因为var有变量提升的效果,而let没有。
由于变量提升
console.log(a);
var a = 1;
相当于
var a ; //先声明
console.log(a);
a = 1;
而let没有这种功能,所以直接console.log(b),浏览器发现找不到b了,就会报错。

直接进入正题:

<script>
for(var a = 0 ; a < 5 ; a++){
	setTimeout(()=>{console.log(a)},0) // => 输出5个5
}
console.log(a) // => 5

//其实这相当于
var a 
// => for循环中的每一个a都是相同的,每次都是给同一个a进行赋值
for(a; a < 5; a++) {
	setTimeout(()=>{console.log(a),0})
}
// 因为var的作用域是函数作用域和全局作用域,且var会变量提升
</script>
<script>
// => for循环中的每一个b都是不相同的,每次for循环都会重新定义一个新的b
for(let b = 0 ; b < 5 ; b++){
	setTimeout(()=>{console.log(b)},0) // => 输出 0,1,2,3,4
}
console.log(b) // => !error
</script>

为什么在 for循环中用var 和 let能产生这么大的差别呢?
我认为主要的原因有两点 1.变量提升 2.异步编程(任务队列)

上文已经介绍过变量提升了,那么在这里我再来介绍一下异步编程。
我们都知道js是单线程的语言,即js在解释语句时是从上到下、从头到尾进行解释。但是js的创造者发现这样的解释效率并不高,所以就出现了异步编程(事件循环)这样的东西。

事件循环

异步操作进入的任务队列分成宏任务队列(settimeout script 等会进入),微任务队列(promise等 会进入).
事件循环执行的顺序是 将宏任务队列中最前面一个任务出队并完成,执行此时微任务队列中的所有微任务

用一句话来说就是,执行一个宏任务后把那个时候有的所有微任务都执行了。  

然后一直按照这个规律执行下去.

这个时候我们在来看看这道题目(我的理解)

  1. 一开始执行的时候碰到 script标签,script 是属于宏任务的, script进入宏任务队列
  2. script 出宏任务队列,执行script中的命令(顺序执行里面的所有同步操作,碰到异步操作将它放入到宏任务队列或者微任务队列), 然后开始解析js代码。先碰到for循环,for循环是同步的,但是里面的settimeout不是同步的,执行for循环的时候将5个settimeout放入到宏任务队列,然后接着往下执行,执行完毕后该script宏任务结束
  3. 将微任务队列中的任务全部执行,但是此时微任务队列为空,不执行任何微任务
  4. 进入新一轮循环。将宏任务队列中的最先入队列的settimeout取出并执行,因为var 有变量提升,且var是函数、全局作用域的(可以在for循环外面访问到a),所以for循环中的var其实用的是同一个.此时a经过了同步的for循环的++操作,此时a的值是5.而let的话没有变量提升,且它的作用域是块级的,导致for循环中的let声明的变量都是不同的(不可以在for循环外面访问到let声明的a),.执行完之后看微任务队列中有没有任务需要执行,发现没有,结束一轮循环
  5. 重复4的过程,之后输出相应的数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值