js javascript let 变量 深入 理解

本文探讨了JavaScript中var与let声明变量的区别,重点在于块级作用域和变量提升的概念。通过代码示例解释了为何在for循环中使用var会导致事件回调函数打印出的i始终为5,而使用let则能正确保留每个循环的i值。解决方案包括使用let声明和利用闭包。文章还介绍了立即执行函数和闭包在解决此类问题中的应用。
摘要由CSDN通过智能技术生成

let理解:

  1. let 声明的变量支持块级作用域
  2. let 不存在变量提升
  3. let 存在暂时死区(不能在初始化之前,使用变量)

根据下面代码块深入理解:
(涉及块级作用域、变量提升相关知识)

// 代码段1
var liLists = document.querySelectorAll('li') // 共5个li
for( var i=0; i<liLists.length; i++){
  liLists[i].onclick = function(){
    console.log(i)
  }
}

众所周知最后 i 的打印结果都是5,而不是想象中的0、1、2、3、4

原因(仅个人理解,哪里有错误望各位大神指正):

  1. onclick事件触发的函数,并非立即执行,当执行时,for循环一定已经遍历完了。
  2. 那么很多人就有疑问: 遍历完后,i应该是4, 可结果为什么是5,因为var存在变量提升,你应该把上面的代码这样理解:
// 代码段2
var liLists;
var i;
liLists = document.querySelectorAll('li') // 共5个li
for( i=0; i<liLists.length; i++){
  liLists[i].onclick = function(){
    console.log(i)
  }
}
  1. 当遍历到最后(也就是很多人理解的i4时), i依旧执行了最后一次i++, 只是没有满足for循环的遍历条件, 且没有进入到for循环。 但是经过变量提升后的的i 已经变成了5
  2. 最后当onclick时间发生的时候,所调用的函数中引用了i变量,这个时候就涉及到了作用域,当自身作用域中找不到该变量时,就会去上一层找,上一层也找不到就会去全局中。全局的i5, 所以结果都为5

解决的办法:

1. var改为let后, 依次触发事件, 所得到的结果为0,1,2,3,4
// 代码段3
var liLists = document.querySelectorAll('li') // 共5个li
for( let i=0; i<liLists.length; i++){
 liLists[i].onclick = function(){
   console.log(i)
 }
}
  1. let声明的变量不存在变量提升
  2. for( let i = 0; i< 5; i++) 这句话的圆括号之间,有一个隐藏的作用域
  3. for( let i = 0; i< 5; i++) { 循环体 } 在每次执行循环体之前,JS 引擎会把 i 在循环体的上下文中重新声明及初始化一次。
也就是说上面的代码段3可以近似近似近似地理解为
// 代码段4
var liLists = document.querySelectorAll('li') // 共5个li
for( let i=0; i<liLists.length; i++){
  let i = 隐藏作用域中的i // 看这里看这里看这里
  liLists[i].onclick = function(){
    console.log(i)
  }
}

那样的话,5 次循环,就会有 5 个不同的 i,console.log 出来的 i 当然也是不同的值。

2. 使用 立即执行函数+闭包
    function demo(){
      let arr =[]
      for(var i = 1; i<=3 ; i++){
        arr.push(
          (function(n) {
            return function(){
              return n
            }
          })(i)
        )
      }
      return arr
    }
    console.log(demo()[1]());
  1. 这样当遍历时,i就会被及时的留存,这里面就应用到了 闭包+立即执行函数

以上内容均借鉴于以下文章, 小编只是融合了一小部分自己的理解。
出处:

https://www.jianshu.com/p/0f49c88cf169
https://www.liaoxuefeng.com/wiki/1022910821149312/1023021250770016

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

DefuseAll

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

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

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

打赏作者

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

抵扣说明:

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

余额充值