在 JavaScript 中,变量的声明方式经历了从 var
到 let
和 const
的演变。let
和 const
是 ES6(ECMAScript 2015)引入的新语法,解决了 var
存在的一些问题,使代码更加安全和可维护。
✅ 一、主要区别对比表
特性 | var |
let |
const |
---|---|---|---|
是否有块级作用域 | ❌ 否 | ✅ 是 | ✅ 是 |
是否存在变量提升 | ✅ 是 | ❌ 否 | ❌ 否 |
是否添加全局属性(如 window ) |
✅ 是 | ❌ 否 | ❌ 否 |
能否重复声明变量 | ✅ 是 | ❌ 否 | ❌ 否 |
是否存在暂时性死区(TDZ) | ❌ 否 | ✅ 是 | ✅ 是 |
是否必须设置初始值 | ❌ 否 | ❌ 否 | ✅ 是 |
能否改变指针指向 | ✅ 是 | ✅ 是 | ❌ 否 |
✅ 二、逐项解析
1️⃣ 块级作用域(Block Scope)
var
没有块级作用域,只区分函数作用域;let
和const
有块级作用域 ,由{}
包裹的区域就是它们的作用域;
示例:
javascript
if (true) {
var a = 1;
let b = 2;
const c = 3;
}
console.log(a); // 1(var 可以访问)
console.log(b); // ReferenceError: b is not defined
console.log(c); // ReferenceError: c is not defined
📌 总结:
使用
let
和const
更加安全,避免了变量污染和意外覆盖。
2️⃣ 变量提升(Hoisting)
var
存在变量提升 :变量会被提升到作用域顶部,并初始化为undefined
;let
和const
不会提升,但会进入"暂时性死区";
示例:
javascript
console.log(a); // undefined(变量被提升)
var a = 1;
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 2;
console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 3;
📌 总结:
let
和const
避免了因变量提升导致的错误逻辑。
3️⃣ 是否添加全局对象属性
- 在浏览器中,全局对象是
window
,Node.js 中是global
; var
声明的变量会成为全局对象的属性;let
和const
不会;
示例:
javascript
var a = 10;
console.log(window.a); // 10
let b = 20;
console.log(window.b); // undefined
const c = 30;
console.log(window.c); // undefined
📌 总结:
使用
let
和const
更加安全,不会污染全局命名空间。
4️⃣ 能否重复声明变量
var
允许重复声明;let
和const
不允许重复声明;
示例:
javascript
var x = 1;
var x = 2; // 合法
let y = 1;
let y = 2; // SyntaxError: Identifier 'y' has already been declared
const z = 1;
const z = 2; // SyntaxError: Identifier 'z' has already been declared
📌 总结:
let
和const
提高了代码的健壮性,防止重复定义带来的混乱。
5️⃣ 暂时性死区(Temporal Dead Zone, TDZ)
let
和const
存在 TDZ:变量在声明前不可访问;var
没有 TDZ;
示例:
javascript
console.log(a); // undefined
var a = 1;
console.log(b); // ReferenceError
let b = 2;
console.log(c); // ReferenceError
const c = 3;
📌 总结:
TDZ 是一种语言设计机制,确保变量在声明之前不能被使用,提高了代码的可读性和安全性。
6️⃣ 是否必须设置初始值
var
和let
可以不设置初始值;const
必须设置初始值;
示例:
javascript
var a; // OK
let b; // OK
const c; // SyntaxError: Missing initializer in const declaration
📌 总结:
const
强制开发者在声明常量时就赋值,有助于编写更清晰的代码。
7️⃣ 是否能改变指针指向
var
和let
可以重新赋值;const
不可以改变指针指向(注意:如果是对象或数组,内容是可以修改的);
示例:
javascript
var a = 1;
a = 2; // OK
let b = 1;
b = 2; // OK
const c = 1;
c = 2; // TypeError: Assignment to constant variable.
const obj = { name: "Tom" };
obj.name = "Jerry"; // OK,修改对象内容
obj = {}; // TypeError: Assignment to constant variable.
📌 总结:
const
表示的是引用不变,不是值不可变。对于对象或数组,仍可以修改其内容。
✅ 三、一句话总结
var
是函数作用域,存在变量提升和重复声明的问题;let
是块级作用域、不可重复声明、没有变量提升;const
与let
类似,但必须初始化且不可重新赋值;- 推荐优先使用
const
,其次是let
,避免使用var
;
💡 进阶建议
- 使用 TypeScript 时,
const
会带来更强的类型推导优势; - 使用 ESLint 规则禁止使用
var
; - 在 Vue / React 开发中,推荐用
const
和let
管理状态; - 使用
Object.freeze()
配合const
实现真正不可变的数据结构;