let 和 var 区别
- let : 变量只能声明一次,var : 变量可以多次声明
var v = 5;
var v = 3;
let l = 2;
let l = 4;
// 报错信息: Identifier 'l' has already been declared
- 我们可以巧妙的利用这个特性,实现如下代码:
// 使用var,输出五遍var5
for(var i=0;i<5;i++){
setTimeout(function(){
console.log("var:" + i);
})
}
// 使用let,输出let12345
for(let i=0;i<5;i++){
setTimeout(function(){
console.log("let" + i);
})
}
//使用var和闭包才能实现输出12345
for(var i=0;i<5;i++){
(function(i){
setTimeout(function(){
console.log("var" + i);
})
})(i);
- 通过这个我们可以理解下面这个题目
// 点击每一个div输出5,如果把var i换成let i,输出则是0-4
(function (){
var foo;
for (var i = 0;i < 5;i++) {
foo = document.createElement("div");
foo.innerHTML = i;
foo.onclick = function(){
console.log(i);
}
document.body.appendChild(foo);
}
}());
- 然而,用我之前的知识来理解这个代码是不能自圆其说的。因为代码中依然只声明了一个 i,在 for 循环结束后,i 的值还是会变成 5 才对。
所以我去读了ES文档,大致理解如下:
- for( let i = 0; i< 5; i++) 这句话的圆括号之间,有一个隐藏的作用域
- for( let i = 0; i< 5; i++) { 循环体 } 在每次执行循环体之前,JS 引擎会把 i 在循环体的上下文中重新声明及初始化一次。
- 那样的话,5 次循环,就会有 5 个不同的 i,console.log 出来的 i 当然也是不同的值。再加上隐藏作用域里的 i,一共有 6 个 i。
参考: