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循环。
