为什么要使用 const?使用 const 有什么好处和坏处?

22 阅读3分钟

为什么要使用 const?使用 const 有什么好处和坏处?

核心答案

const 是 ES6 引入的声明常量的关键字,用于声明不可重新赋值的变量。使用 const 的核心价值在于:

  1. 语义化表达意图:明确告诉其他开发者这个变量不会被重新赋值
  2. 防止意外修改:在编译/运行时捕获意外的重新赋值错误
  3. 代码可预测性:减少变量状态追踪的心智负担

深入解析

原理层面

1. const 的本质:绑定不可变,而非值不可变

const obj = { name: 'Alice' };
obj.name = 'Bob';      // ✅ 允许:修改对象属性
obj = { name: 'Bob' }; // ❌ TypeError:不允许重新赋值

const 保证的是变量与内存地址之间的绑定关系不变,而不是内存中的值不变。

2. 块级作用域

let 一样,const 具有块级作用域,解决了 var 的变量提升和函数作用域问题:

if (true) {
  const x = 10;
}
console.log(x); // ReferenceError: x is not defined

3. 暂时性死区(TDZ)

console.log(a); // ReferenceError
const a = 1;    // 在声明前访问会报错

好处

优点说明
意图清晰一眼就知道这个变量不会被重新赋值
防止 bug避免意外覆盖重要变量
便于优化引擎可以做更好的优化(理论上)
函数式友好符合不可变数据的编程范式
团队协作代码更易读、更可维护

坏处/局限

缺点说明
引用类型可变对象、数组的内容仍可被修改,容易误解
必须初始化声明时必须赋值,不能先声明后赋值
循环中受限不能用于需要递增的传统 for 循环计数器

常见误区

误区一:const 声明的对象完全不可变

错误!只是引用不可变,需要 Object.freeze() 实现浅层冻结:

const obj = Object.freeze({ a: 1 });
obj.a = 2; // 静默失败(严格模式报错)

误区二:const 比 let 性能更好

现代 JavaScript 引擎对 constlet 的性能优化几乎相同,选择应基于语义而非性能。

代码示例

// ✅ 推荐:不会重新赋值的变量用 const
const API_URL = 'https://api.example.com';
const user = { name: 'Alice', age: 25 };
const numbers = [1, 2, 3];

// 对象和数组的内容可以修改
user.age = 26;           // ✅
numbers.push(4);         // ✅

// ❌ 不能重新赋值
// API_URL = 'xxx';      // TypeError
// user = {};            // TypeError

// ✅ 循环中使用 const(for...of / for...in)
for (const item of numbers) {
  console.log(item);     // 每次迭代创建新的绑定
}

// ❌ 传统 for 循环计数器不能用 const
// for (const i = 0; i < 10; i++) {} // TypeError

// ✅ 用 let 处理需要重新赋值的场景
let count = 0;
count++;

实现真正的不可变

// 浅冻结
const frozen = Object.freeze({ a: 1, b: { c: 2 } });
frozen.a = 100;      // 无效
frozen.b.c = 100;    // 有效!嵌套对象未冻结

// 深冻结需要递归处理或使用 Immutable.js / Immer 等库

面试技巧

可能的追问

  1. const、let、var 的区别?

    • 作用域、变量提升、TDZ、重复声明、全局对象属性
  2. const 声明的对象如何实现完全不可变?

    • Object.freeze()(浅)、递归冻结、Immutable.js、Immer
  3. 什么时候用 let,什么时候用 const?

    • 默认用 const,只有需要重新赋值时才用 let
  4. const 在循环中的表现?

    • for...of/for...in 可用(每次迭代新绑定)
    • 传统 for 循环计数器不可用

展示深度的回答技巧

  • 提到 TDZ(暂时性死区) 展示对执行机制的理解
  • 区分 绑定不可变 vs 值不可变 展示对底层原理的掌握
  • 结合 函数式编程不可变数据 展示编程范式视野

一句话总结

const 保证的是"变量绑定不可变"而非"值不可变",默认优先使用 const,只有需要重新赋值时才用 let,永远不用 var。