由 let 块作用域,反思自己的无知…
Demo
我们先来一个例子
1 2 3 4 5 6 7 8
| for (var i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 100 * i); }
|
1 2 3 4 5 6 7 8 9 10 11 12
| for (let i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 100 * i); }
|
是不是发现二者的不同之处了,是的, 声明变量不同,let
与var
。
当 let 声明出现在循环体里时拥有完全不同的行为。 不仅是在循环里引入了一个新的变量环境,而是针对 每次迭代都会创建这样一个新作用域。 这就是我们在使用立即执行的函数表达式时做的事,所以在 setTimeout 例子里我们仅使用 let 声明就可以了。
块级作用域
可以通过一个简单的案例查看到明显区别:
1 2 3 4 5 6 7
| function demo() { let n = 5; if (true) { let n = 10; } console.log(n); }
|
1 2 3 4 5 6 7
| function demo() { var n = 5; if (true) { var n = 10; } console.log(n); }
|
let 允许你声明一个作用域被限制在块级中的变量、语句或者表达式。与 var 关键字不同的是,var 声明的变量只能是全局或者整个函数块的。
let与var的不同当然不止这一点,比如重定义等,更多可查看 let-MDN
More
题外话,如果案例不使用 let 呢? 之前 js 循环延时踩坑 中也提到过。当然,原理还是划分作用域。
如果把 Demo 中的 let 案例转化为 es5 就会发现其中的大不同:
1 2 3 4 5 6
| for (let i = 0; i < 5; i++) { setTimeout(() => { console.log(i); }, 100 * i); }
|
1 2 3 4 5 6 7 8 9 10
| var _loop = function _loop(i) { setTimeout(function() { console.log(i); }, 100 * i); };
for (var i = 0; i < 5; i++) { _loop(i); }
|