☺️先感受下魅力
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
。
总结
特性 | var | let |
---|---|---|
作用域 | 函数作用域 | 块级作用域 |
变量提升 | 有,初始化为undefined | 有,但不初始化,存在暂时性死区(TDZ) |
重复声明 | 允许 | 不允许 |
全局对象属性 | 是(浏览器中) | 否 |
循环中的表现 | 变量共享同一绑定 | 每次循环新绑定 |