let跟var的区别:
1、let声明的是块级作用域,而var声明的范围是函数作用域,
2、let声明的变量不会在作用域中被提升,而var会
3、与 var 关键字不同,使用 let 在全局作用域中声明的变量不会成为 window 对象的属性(var声明的变量则会)。
if(true){
let age = 26;
console.log(age); // 26
}
console.log(age); //ReferenceError: age is not defined
let 也不允许同一个块作用域中出现冗余声明。这样会导致报错 :
var name;
var name;
let age;
let age; // SyntaxError: Identifier 'age' has already been declared
可以这样声明,因为不在同一个作用域
function test() {
let age = 30;
if (true) {
let age = 20;
console.log(age); // 20
}
console.log(age); // 30
}
test();
for循环中的let声明
在let出现之前,for循环定义的迭代变量会渗透到循环体外部
for (var i = 0; i < 5; i++){
}
console.log(i); // 5
改成使用let后,这个问题就消失了,因为迭代变量的作用域仅限于for循环块内部:
for (let i = 0; i < 5; i++){
}
在使用 var 的时候,最常见的问题就是对迭代变量的奇特声明和修改
for (var i = 0; i < 5; i++){
setTimeout(() => {
console.log(i); // 5,5,5,5,5
}, 0)
}
// 之所以会这样,是因为在退出循环时,迭代变量保存的是导致循环退出的值:5。在之后执行超时
逻辑时,所有的 i 都是同一个变量,因而输出的都是同一个最终值。
而在使用 let 声明迭代变量时,JavaScript 引擎在后台会为每个迭代循环声明一个新的迭代变量。
每个 setTimeout 引用的都是不同的变量实例,所以 console.log 输出的是我们期望的值,也就是循
环执行过程中每个迭代变量的值。
for (let i = 0; i < 5; i++){
setTimeout(() => {
console.log(i); // 0,1,2,3,4
}, 0)
}
tips:这种每次迭代声明一个独立变量实例的行为适用于所有风格的 for 循环,包括 for-in 和 for-of
循环。