let 和 const 是 es6 推出的声明变量的关键字。
个人觉得这三个关键字最大的区别就是作用域和提升。
(1)作用域
var 声明的范围是函数作用域,let 和 const 声明的范围是块作用域。
{
var varT = "var";
}
console.log(varT); //var
{
let letT = "let";
}
console.log(letT); //Uncaught ReferenceError: letT is not defined
{
let constT = "const";
}
console.log(constT); //Uncaught ReferenceError: constT is not defined
(2)提升
使用 var 关键字声明的变量会自动提升到函数作用域顶部,let 和 const 则不能。
console.log(varT); //undefined
var varT = "var";
这段代码相当于:
var varT;
console.log(varT); //undefined
varT = "var";
对于 let 和 const:
console.log(letT); //Uncaught ReferenceError: Cannot access 'letT' before initialization
let letT = "let";
console.log(constT); //Uncaught ReferenceError: Cannot access 'constT' before initialization
let constT = "const";
《JavaScript 高级程序设计》给出的解释是:在解析代码时,JavaScript 引擎也会注意出现在块后面的 let 声明,只不过在此之前不能以任何方式来引用未生命的变量。在 let 声明之前的执行瞬间被称为 “暂时性死区”,在此阶段引用任何后面才声明的变量都会抛出 ReferenceError。
(3)重复声明变量
var 允许重复声明变量,let 和 const 不允许。
var varT = "v1";
var varT = "v2";
var varT = "v3";
console.log(varT); //v3
对于 let 和 const:
let letT = "l1";
let letT = "l2";
let letT = "l3";
console.log(letT); //Uncaught SyntaxError: Identifier 'letT' has already been declared
const constT = "c1";
const constT = "c2";
const constT = "c3";
console.log(constT); //Uncaught SyntaxError: Identifier 'constT' has already been declared
(4)全局声明
使用 var 在全局作用域中声明的变量会成为 window 对象的属性,而 let 和 const 不会。
var varT = "var";
console.log(varT === window.varT); //true
对于 let 和 const:
let letT = "let";
console.log(letT === window.letT); //false
const constT = "const";
console.log(constT == window.constT); //false
(5)奇妙的 const
var 和 let 声明的变量都可以修改,而用 const 声明变量时还必须同时初始化变量,且尝试修改 const 声明的变量会导致运行时错误。
const constT = "const";
constT = "t"; //Uncaught TypeError: Assignment to constant variable.
不过对于引用类型而言(例如数组和对象),const 声明的变量是保存其引用,所以通过 const 声明的引用类型,只能保证其地址引用不变,而不能保证其中的数据不变。
const arr = [1, 2, 3];
arr[0] = 3; //修改其数据
console.log(arr); //(3) [3, 2, 3]
const arr = [1, 2, 3];
arr = 1; //修改引用
console.log(arr); //Uncaught TypeError: Assignment to constant variable.