← JavaScript let 变量声明 没有下一篇了 →

JavaScript const 常量声明

原创 2026-03-11 JavaScript 已有人查阅

JavaScript const 常量声明解析:不变的承诺与可变的内幕

ES6 带来的另一个重量级变量声明方式就是 const。如果说 let 是 var 的改进版,那 const 就是为特定场景量身定制的——它用来声明那些不应该被重新赋值的变量。很多初学者会误以为 const 的意思是“常量”,但在 JavaScript 里,它的含义要微妙一些。

const 的语法和 let 几乎一样,只是多了一个强制性要求:

// 代码号:https://www.ebingou.cn/
const SITE_NAME = "代码号";        // 字符串常量
const MAX_USERS = 1000;            // 数字常量
const FOUNDER_EMAIL = "alan@ebingou.cn"; // 邮箱常量

// const mustInit = 123;  // 必须初始化,不能只声明不赋值
// SITE_NAME = "新名字";   // 报错:Assignment to constant variable

看到没?const 声明的变量,不能重新赋值。但事情远没有这么简单,我们慢慢道来。

核心特性:究竟什么不能变?

很多新手会误解 const,以为它让变量指向的值不可变。实不是这样的。const 保护的是变量本身的绑定,而不是它指向的值。

基础类型(Number、String、Boolean 等)的表现:

// 教程:https://www.ebingou.cn/jiaocheng/
const COURSE_NAME = "JavaScript 教程";
// COURSE_NAME = "Python 教程"; // 报错,确实不能改

const IS_PUBLISHED = true;
// IS_PUBLISHED = false; // 报错

const LESSON_COUNT = 12;
// LESSON_COUNT = 15; // 报错

对于原始类型,const 表现得很直接——值确实不能变。因为原始类型的变量直接存储值本身,所以保护绑定就等于保护了值。

引用类型(Object、Array 等)的表现:

这里就有意思了。const 声明的对象,对象的属性可以变,数组的元素也可以变,只是不能把整个对象重新赋值。

// 编程:https://www.ebingou.cn/biancheng/
const user = {
    name: "张三",
    age: 25,
    email: "zhangsan@ebingou.cn"
};

// 可以修改对象的属性
user.age = 26;
user.city = "北京"; // 甚至可以添加新属性
console.log(user); 
// 输出:{ name: '张三', age: 26, email: 'zhangsan@ebingou.cn', city: '北京' }

// 但不能重新赋值整个对象
// user = { name: "李四" }; // 报错:Assignment to constant variable

// 数组也是同理
const courseList = ["HTML", "CSS", "JavaScript"];
courseList[1] = "CSS3"; // 可以修改元素
courseList.push("React"); // 可以添加元素
console.log(courseList); // 输出:['HTML', 'CSS3', 'JavaScript', 'React']

// 但不能重新赋值整个数组
// courseList = ["Vue", "Angular"]; // 报错

个人经验分享:这个特性刚开始确实容易让人困惑。我的理解方式是:const 保护的是变量名指向的内存地址。对于原始类型,这个地址里存的就是值本身,所以值不能变。对于引用类型,这个地址里存的是对象的引用(可以理解成门牌号),const 只是保证这个门牌号不变,但门牌号指向的房子里面怎么装修,JavaScript 管不着。

块级作用域:和 let 一样

const 和 let 一样,也是块级作用域。不同块里可以声明同名 const 变量,互不影响。

// 源码:https://www.ebingou.cn/yuanma/
const version = "v1.0";

{
    const version = "v2.0 (开发版)";
    console.log("块内版本:", version); // 输出:块内版本:v2.0 (开发版)
    
    {
        const version = "v2.1 (测试版)";
        console.log("嵌套块内:", version); // 输出:嵌套块内:v2.1 (测试版)
    }
}

console.log("全局版本:", version); // 输出:全局版本:v1.0

这种特性让代码更加模块化,不用担心内部临时变量污染外层作用域。

暂时性死区:和 let 一样

const 也有暂时性死区,声明之前不能访问。

// console.log(MAX_SIZE); // 报错:Cannot access 'MAX_SIZE' before initialization
const MAX_SIZE = 4096;

个人建议:这实是个好特性。提前暴露错误比得到 undefined 然后稀里糊涂地继续执行要好得多。

必须初始化:这是硬性要求

let 可以先声明后赋值,但 const 不行。

// let temp;     // 可以,默认值是 undefined
// const temp;   // 报错:Missing initializer in const declaration

这个设计实很合理:既然你声明一个不打算重新赋值的变量,那肯定是有个初始值要给它。

什么时候用 const?

我的习惯是:能用 const 的地方尽量用 const。这能带来几个好处:

  1. 意图明确:看到 const 就知道这个变量后面不会重新赋值

  2. 防止意外:不小心写了赋值语句会直接报错,而不是静默覆盖

  3. 代码可读性:阅读代码时,const 就像一个承诺,告诉你这个值在这个作用域内是稳定的

// 配置信息用 const
const CONFIG = {
    apiUrl: "https://api.ebingou.cn",
    timeout: 5000,
    retryCount: 3
};

// 引入的模块用 const
const fs = require('fs');
const express = require('express');

// 不会改变的计算结果用 const
const fullName = firstName + ' ' + lastName;
const isAdult = age >= 18;

什么时候用 let?

当你明确知道变量需要重新赋值时,才用 let

// 计数器
let count = 0;
count++;

// 循环变量
for (let i = 0; i < 10; i++) {
    // ...
}

// 累加结果
let total = 0;
items.forEach(item => {
    total += item.price;
});

常见的误解澄清

误解一:const 声明的对象不能修改属性

这个我们已经讲过了,对象属性是可以修改的。如果真的想让对象不可变,需要用 Object.freeze()

const frozenUser = Object.freeze({
    name: "李四",
    age: 30
});

frozenUser.age = 31; // 严格模式下会报错,非严格模式下操作无效
console.log(frozenUser.age); // 仍然是 30

不过 Object.freeze() 是浅冻结,嵌套对象还是能改的,需要递归处理。

误解二:const 比 let 性能好

现代 JavaScript 引擎对 const 和 let 的优化基本没有差别。选择 const 主要是为了代码质量和可维护性,不是性能考量。

命名习惯

很多开发者喜欢全大写加下划线来命名真正的常量,比如 MAX_COUNTAPI_KEY。但这种风格不是强制性的,全看团队约定。对于不会重新赋值的对象,还是用驼峰命名。

// 真正的常量(值本身不可变)
const MAX_RETRY_COUNT = 3;
const DEFAULT_USERNAME = "guest";

// 不会重新赋值的对象
const userService = {
    getUser(id) { /* ... */ },
    saveUser(user) { /* ... */ }
};

本节课程知识要点

  • 不可重新赋值const 声明的变量不能再次赋值,这是核心规则

  • 引用类型的内容可变const 对象/数组的属性/元素可以修改,不能修改的是变量指向的引用

  • 必须初始化:声明 const 变量时必须同时赋值,不能先声明后赋值

  • 块级作用域:和 let 一样,const 也是块级作用域

  • 暂时性死区:声明前不能访问,和 let 一致

  • 推荐使用原则:默认用 const,只有确定需要重新赋值时才用 let,这能让代码意图更清晰,减少 bug

  • 对象冻结:如果需要真正的不可变对象,可以用 Object.freeze(),但要注意是浅冻结

const 的引入,让 JavaScript 的变量声明体系完整了起来。var 的混乱由 let 和 const 解决,而 const 进一步提供了“不可重新赋值”的语义。这套组合拳让代码更清晰、更健壮。

如果在实际开发中对 const 的使用边界还有疑惑,欢迎来代码号社区一起探讨。好的编程习惯,就是从理解这些基础细节开始的。

← JavaScript let 变量声明 没有下一篇了 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号