一个例子理解ES6新增的变量声明let

JavaScript中最常接触的一种变量声明的方式就是var, 我们都知道在JS中存在着预解析, 那么何为预解析呢, 就是当你在一个作用域中不管在什么位置声明一个变量的时候, 会把他放在该做用于最开始的位置, 也就是我们所说的变量声明提升. 当然, 函数也有变量声明提升并且优先级要高于变量, 但是我们主要介绍变量. 预解析是一把双刃剑, 有时会方便我们编程人员, 但是又会为我们带来一些麻烦, 而下面这个例子就是很好地说明变量声明提升的一个弊端:

for(var i=0;i<5;i++) {
  setTimeout(function() {
    console.log(i)
  },0)
} 

在这里插入图片描述
这是一个for循环, 里面是个定时器, 我们的本意是循环5次, 打印出来的结果应该是1,2,3,4,5,但是在node中打印后我们会发现打印了5个5.name为什么会产生这样的结果呢, 其实原因出在两方面, 第一变量的作用域, 第二,定时器是异步函数
首先, 在ES6以前的JS中, 只有全局作用域和函数作用域, 而没有块级作用域, 所谓块级作用域, 说通俗一点就是一对大括号就是一个块级作用域, 每次for循环一次,都会产生一个块级作用域,但是因为i是var声明的,所以var没有块级作用域的概念, 所有块级作用域都会共享这个变量,i是全局变量,在所有的块级作用域中,都能访问的到,又因为js的预解析,所以,每次在块级作用域中,var 的i 都是变量声明提升到全局的最顶端,且,定时器是异步函数以及JS的单线程,所以他会被放在队列中等待执行,当上述所有代码执行完成后,从上往下执行每个定时器,当除定时器以外的代码执行完毕后,i的值已经变成了5,然后执行5次定时器,所以打印5次5
for循环可以分解成一下这样的形式:

{
  var i=0;
  if(i<5) {
    setTimeout(function() {
      console.log(i,1);
    })
  }
}

{
  var i=i+1;
  if(i<5) {
    setTimeout(function() {
      console.log(i,2);
    })
  }
}

{
  var i=i+1;
  if(i<5) {
    setTimeout(function() {
      console.log(i,3);
    })
  }
}

{
  var i=i+1;
  if(i<5) {
    setTimeout(function() {
      console.log(i,4);
    })
  }
}

{
  var i=i+1;
  if(i<5) {
    setTimeout(function() {
      console.log(i,5);
    })
  }
}

{
  var i=i+1;
  //条件不满足,不执行if语句
  if(i<5) {
    setTimeout(function() {
      console.log(i,6);
    })
  }
}

而此时, ES6中新增的一个变量声明的关键字就可以完美的替代var声明变量的方式, 那就是let
let支持块级作用域, 也就是说, 只有在同一块级作用域中, let声明的变量才可以被访问到, 并且, let没有变量声明提升的问题, 这正是在我们开发过程中所倡导的避免全局变量污染的概念, 那么上述相同的代码, 当我们在for循环中用let声明i会发生什么呢:

for(let i=0;i<5;i++) {
  setTimeout(function() {
    console.log(i)
  },0)
} 

在这里插入图片描述
此时, for还是那个for, 定时器还是那个最后才会执行的异步函数, 但是, 每个for循环产生的块级作用域中已经正确的记录下来了每次循环产生的i的值, 因为let声明的变量在不同作用域不能相互访问, 因此, 每个定时器也都正确的拿到了对应的i值

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IsQtion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值