彻底读懂 var let const 的区别&顺便重温一下闭包

1. 分享博文: 读懂 var let const 的区别 

2. 顺便看看:

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

/*------------------------------*/

for (let i = 0; i < 5; i++) {
  setTimeout(function () {
    console.log(i)
  }, 1000)
} // 0 1 2 3 4
console.log(i) // i is not defined

理解执行过程:

  • 1. 上一个循环,用 var 声明 i ,每次执行 for 循环(循环是同步任务),都遇到 setTimeout 这个异步任务,于是每次都将这个异步任务放到任务队列当中等待执行(共 5 个)。于是,1000毫秒内,for 已经循环完成,i = 5 , i 是全局变量,先执行同步任务的 console.log(i * 5)打印出 25 。最后打印任务队列的每个console.log(i),打印出 5 5 5 5 5 。
  • 2. 下一个循环,用 let 声明变量,和上面一样,不同的是 let 有块级作用域,类似于闭包,每次循环都将相应的变量值保存着了,因此单独运行 for 循环打印出 0 1 2 3 4 。加上console.log(i)会报错,上面说了,let 声明的变量有块级作用域,每大括号为一个块级作用域。

不妨看看下面用闭包的方式实现上面过程:

for (var i = 0; i < 5; i++) {
  ;(function (i) {
    setTimeout(function () {
      console.log(i)  // 2. 再打印 0 1 2 3 4
    }, 1000)
  })(i)
}
console.log(i * 5) // 1. 先打印 25

相同的,下面也类似,用 var 和 let 不同:

let lis = document.querySelectorAll('li')
for (var i = 0; i < lis.length; i++) {
  lis[i].addEventListener('click', function (e) {
    console.log(i)
  })
}
// 1. 使用 var 只能打印出 5 
// 2. 使用 let 可以正常打印相应的索引

 

posted @ 2022-05-10 21:18  RHCHIK  阅读(31)  评论(0编辑  收藏  举报