【JS】let 🆚 var

11 阅读1分钟

☺️先感受下魅力

var代码:

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

输出:

3
3
3

let代码:

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

输出:

0
1
2

🔴天呐,为什么两者输出差异如此之大?

关键点解释
let 循环变量每次循环创建新的“块级作用域变量”,不是同一个变量
var 循环变量只有一个变量,整个循环共享
结果let 保持每轮独立值;var 打印最终值3

📝每次循环时,JavaScript 会为 let 声明的变量 i 创建一个新的独立作用域和新的变量实例。

换句话说:

  • 虽然循环是同步执行的,但每一轮循环中 let i 实际上是“一个新的变量”,它的值就是当前那轮的 i
  • 这个“新的变量”会被 setTimeout 的回调通过闭包保存住。
  • 所以即使回调异步执行,它们各自闭包里保存的都是各自独立的 i

总结

特性varlet
作用域函数作用域块级作用域
变量提升有,初始化为undefined有,但不初始化,存在暂时性死区(TDZ)
重复声明允许不允许
全局对象属性是(浏览器中)
循环中的表现变量共享同一绑定每次循环新绑定