-
使用关键字 var 声明的变量,无论实际上在哪里声明的,都会被当成在当前作用域顶部声明的变量,也就是
变量提升。如下:if (true) { var msg = "Hello World!"; } console.log(msg); // 'Hello World!'循环内变量过度共享:
循环本身及三次 timeout 回调均共享唯一的变量i。for (var i = 0; i < 3; i++) { setTimeout(function() { console.log(i); // 输出了3个3 }, 1000); }
-
使用 let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升。
"use strict"; if (true) { let msg = "Hello World!"; } console.log(msg); // 'msg is not defined'循环变量内不会共享:
循环在每次迭代时都为i创建新的绑定"use strict"; for (let i = 0; i < 3; i++) { setTimeout(function() { console.log(i); // 输出了1,2,3 }, 1000); }用 let 重定义变量会抛出一个语法错误(SyntaxError)。
let a = "a"; let a = "b";临时死区:let 和 const 生命的变量不会被提升到作用域顶部,如果在声明之前访问就会抛出出错。
"use strict"; if (true) { // 此时的msg还位于JavaScript所谓的“临时死区” console.log(msg); // 引用错误 let msg = "Hello World!"; }总结:let 相当于 var 的升级版,是完美版的 var,修复了 var 存在的 bug。
-
与 let 不同的是,使用 const 声明的是常量,在后面出现的代码中不能再修改该常量的值。
"use strict"; const msg = "Hello World!"; // 抛出语法错误:Assignment to constant variable msg = "Goodbye World!";但是 const 却允许修改对象的属性值:
"use strict"; const person = { name: "zane" }; // 可以修改对象属性的值 person.name = "urnotzane"; const arr = ["zane"]; arr.unshift("tong"); // ['tong', 'zane'] console.log(arr);注意:必须声明 'use strict' 后才能使用 let 声明变量,否则浏览并不能显示结果。