const和let出现在ES6及更晚的版本中
var关键字
var声明的作用域
函数作用域,变量将在函数退出时被销毁
function test() {
var message = "hi"; // 局部变量
}
test();
console.log(message); // 出错!
var变量提升
使用var关键字声明的变量会自动提升到函数作用域顶部,下面的代码不会报错:
function foo() {
console.log(age);
var age = 26;
}
foo(); // undefined
把所有变量声明都拉到函数作用域的顶部,等价于如下代码:
function foo() {
var age;
console.log(age);
age = 26;
}
foo(); // undefined
let声明
块级作用域
let和var最明显的区别是,let 声明的范围是块作用域,而 var 声明的范围是函数作用域。
if (true) {
var name = 'Matt';
console.log(name); // Matt
}
console.log(name); // Matt
if (true) {
let age = 26;
console.log(age); // 26
}
console.log(age); // ReferenceError: age 没有定义
暂时性死区
let 与 var 的另一个重要的区别,就是 let 声明的变量不会在作用域中被提升。
// name 会被提升
console.log(name); // undefined
var name = 'Matt';
// age 不会被提升
console.log(age); // ReferenceError:age 没有定义
let age = 26;
在 let 声明之前的执行瞬间被称为“暂时性死区”(temporal dead zone),在此阶段引用任何后面才声明的变量都会抛出 ReferenceError。
全局声明
与 var 关键字不同,使用 let 在全局作用域中声明的变量不会成为 window 对象的属性(var 声明的变量则会)。
var name = 'Matt';
console.log(window.name); // 'Matt'
let age = 26;
console.log(window.age); // undefined
- for循环中的let声明
for 循环定义的迭代变量会渗透到循环体外部:
for (var i = 0; i < 5; ++i) {
// 循环逻辑
}
console.log(i); // 5
使用let之后,迭代变量的作用域仅限于 for 循环块内部。
const声明
const 的行为与 let 基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改 const 声明的变量会导致运行时错误。
const 声明的限制只适用于它指向的变量的引用。换句话说,如果 const 变量引用的是一个对象,
那么修改这个对象内部的属性并不违反 const 的限制。
const person = {};
person.name = 'Matt'; // ok
ECMAScript 6 增加 let 和 const 从客观上为这门语言更精确地声明作用域和语义提供了更好的支持。很多开发者开始不使用var,只使用 let 和 const有助于提升代码质量,因为变量有了明确的作用域、声明位置,以及不变的值。