var arr = []
for (var i = 0; i < 5; i++) {
arr[i] = function() {
console.log(i);
}
}
arr[0]() //5
arr[2]() //5
console.log(arr[1]);
for (var j = 0; j < 5; j++) {
setTimeout(() => {
console.log(j);
}, 0);
}
//输出 5 5 5 5 5
由于循环内部是异步代码会在for循环结束后才会执行,而var关键字没有块级作用域,只有函数作用域,每一个i都会被下一个i的值所覆盖,当异步代码执行时会沿着作用域链向上查找i的值,由于i最后的值为5,所以每次执行的结果都为5
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
}, 0);
}
//输出 1 1 1 1 1
而let关键字的作用域是块级作用域,在每次循环中都会产生一个新的块,每个块都是独立的作用域,不会互相影响,而每个块中i的值为当前循环i的值。 最后执行的异步代码会在自己的块级作用域中找到i值。
var和let的区别
1.var可以被重复定义,let不可以(条件声明)
2.var会声明提升,let不会(暂时性死区)
3.var声明的全局变量会成为window身上的一个属性而let不会
4.var为函数作用域,let为块级作用域