var、let、const 的区别
变量提升、暂时性死区、块级作用域的对比
问题
说明 var、let、const 三种变量声明方式的区别。
解答
作用域
// var 是函数作用域
function varScope() {
if (true) {
var x = 1;
}
console.log(x); // 1,可以访问
}
// let 和 const 是块级作用域
function letScope() {
if (true) {
let y = 1;
const z = 2;
}
console.log(y); // ReferenceError: y is not defined
}
变量提升
// var 会提升,初始化为 undefined
console.log(a); // undefined
var a = 1;
// 等价于:
// var a;
// console.log(a);
// a = 1;
// let 和 const 也会提升,但存在暂时性死区
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 2;
暂时性死区(TDZ)
let x = 'outer';
function test() {
// 从块开始到声明之前,x 处于暂时性死区
console.log(x); // ReferenceError
let x = 'inner';
}
// typeof 也不安全
console.log(typeof undeclaredVar); // undefined
console.log(typeof tdzVar); // ReferenceError
let tdzVar = 1;
重复声明
// var 允许重复声明
var a = 1;
var a = 2; // OK
// let 和 const 不允许
let b = 1;
let b = 2; // SyntaxError: Identifier 'b' has already been declared
重新赋值
var a = 1;
a = 2; // OK
let b = 1;
b = 2; // OK
const c = 1;
c = 2; // TypeError: Assignment to constant variable
// const 声明的对象,属性可以修改
const obj = { name: 'Tom' };
obj.name = 'Jerry'; // OK
obj = {}; // TypeError
全局对象属性
var globalVar = 'var';
let globalLet = 'let';
console.log(window.globalVar); // 'var'
console.log(window.globalLet); // undefined
对比表格
| 特性 | var | let | const |
|---|---|---|---|
| 作用域 | 函数 | 块级 | 块级 |
| 变量提升 | 是(初始化为 undefined) | 是(TDZ) | 是(TDZ) |
| 重复声明 | 允许 | 不允许 | 不允许 |
| 重新赋值 | 允许 | 允许 | 不允许 |
| 全局对象属性 | 是 | 否 | 否 |
关键点
var是函数作用域,let和const是块级作用域- 三者都有变量提升,但
let和const存在暂时性死区(TDZ) const声明时必须初始化,且不能重新赋值,但对象属性可修改- 全局作用域下,
var声明的变量会成为window属性 - 优先使用
const,需要重新赋值时用let,避免使用var
目录