看了很多解释,感觉都不好理解。这个文章是我自己的理解,可以做个参考,如果我理解的不对,欢迎在评论区指正:
var:使用var声明的变量具有全局作用域 (循环中每次声明的是同一个变量)
let:使用let声明的变量具有局部作用域 (循环中每次声明的是新的变量)每次是新的作用域
为什么var使用的是同一个呢?因为var可以变量提升,let不可以;
可以把for循环拆解成这样的代码去理解,就通顺了:
for(var i=0;i<2;i++){
setTimeout(()=>console.log(i),1000)
}
// 相当于
var i; // 变量提升
function q(){
i=0;
setTimeout(()=>console.log(i),0)
}
q();
function w(){
i=1;
setTimeout(()=>console.log(i),0)
}
w();
function e(){
i=2;
}
e();
然后let可以拆解成这样:
for(let i=0;i<2;i++){
setTimeout(()=>console.log(i),1000)
}
// 相当于
function q(){
let i=0; // 变量提升不了
setTimeout(()=>console.log(i),0)
}
q();
function w(){
let i=1;
setTimeout(()=>console.log(i),0)
}
w();
function e(){
let i=2;
}
e();
var里面由于改变的都是同一个变量,setTimeout引用的变量地址指向同一个值,所以最后值是相同的。
let里面由于每次都开辟了一个新的内存空间,setTimeout引用的变量地址指向的是不同的值,所以最后值是不同的。
==================================
以上是对let解决方法的语意化,如果使用闭包那么就转化为这样:
for(var i=0;i<2;i++){
(function(j){
setTimeout(()=>console.log(j),0);
})(i)
}
var i; // 变量提升
function q(){
i=0; // 闭包
(function(j){
setTimeout(()=>console.log(j),0);
})(i)
}
q();
function w(){
i=1;
(function(j){
setTimeout(()=>console.log(j),0);
})(i)
}
w();
function e(){
i=2;
}
e();
如果说的不对,欢迎指正🎉