const 这个关键字,几乎每一门主流语言里都有,但你有没有认真想过,每次在代码里敲下这三个字母,你究竟在表达什么?就拿前端里最常见的 const player = { x: 400, y: 300, speed: 4 } 来说,很多人写它只是因为“ESLint 要求优先用 const”,或者“网上都这么写”,真被问到“为什么不用 var”、“const 到底锁死了什么”,却又说不清。到了 C++、Qt 的环境里,const 的概念更复杂,甚至还会遇到 write access to const memory has been detected 这种让人一头雾水的运行时错误。
这篇文章我就把你可能纠结过的那些点,一次性捋清楚。不管你是刚入门 JavaScript 的新手,还是在 Qt5/C++ 里跟 const 斗智斗勇的老手,希望你看完能明白 const 的真正价值、适用边界,以及它带来的那些“隐藏成本”。
1. const的本质:不是限制,而是契约
很多人对 const 的第一反应是“不让变量被修改”,这个理解没有错,但太浅了。const 真正在做的,是在代码里划定一条“契约边界”:哪些数据是只读的,哪些数据是会被改写的。这条边界如果划得清楚,代码的可读性、可维护性、可并行性都会上一个台阶;如果划得模糊,改 bug 的时间大概率会翻倍。
1.1 const到底在约束什么
不同语言里,const 的约束粒度完全不一样。同样是声明一个对象,JavaScript 里的 const 和 C++ 里的 const,含义差了十万八千里。
先看 JavaScript:
javascript复制const player = { x: 400, y: 300, speed: 4 };
player.x = 500; // 合法,能改
player = { x: 0, y: 0, speed: 1 }; // 报错,不能重新赋值
这里 const 锁的是变量名到对象的绑定关系,而不是对象本身。player 这个名字永远指向那块内存地址,但内存里的内容——也就是 x、y、speed 这些属性——是可以随意改的。这就是所谓的“绑定不可变”,而不是“值不可变”。
再看 C++:
cpp复制const Player player = { 400, 300, 4 };
player.x = 500; // 编译错误,不能改
C++ 里的 const 默认作用于对象本身,一旦定义成 const,它的所有成员都不能修改(除非成员本身被 mutable 修饰)。这是一个更物理、更底层的只读保证,在 JavaScript 里根本做不到同样的效果——除非用 Object.freeze(),但那又是另一套机制了。
1.2 从“防止改错”到“意图表达”
我见过很多项目,const 的使用逻辑完全搞反了:只在编译器报错的时候加 const,别的地方全用 let。这就等于把自己的安全网扔了一半。const 更重要的价值是向读代码的人传递信号。
想象一下,你接手一个别人写的函数,里面有一个变量从头到尾没有被重新赋值。如果它被声明成 const,你一眼就知道:这个变量的值在这个作用域内是稳定的,分析逻辑的时候你可以少考虑一条变化路径。如果它被声明成 let,你就得小心了——虽然实际上它没被改过,但作者也许本来打算改,或者后续某个改动会在这里赋值。这种心智负担在复杂函数里会被放大很多倍。
我自己看代码的习惯是:先扫一眼所有 const 声明,快速建立“哪些东西不会变”的认知,再去看逻辑。 这一步对理解代码特别有帮助。所以 const 不是写给自己看的,是写给所有后来者看的,包括未来的你自己。
注意:const 真正强大的地方,不是你用它省了那几次“不小心改错”的麻烦,而是它让代码里的可变区域变少了。可变性越少,代码的不确定性就越少,bug 的藏身之处就越少。
1.3 不可变性与并发安全的关系
这一点在 C++ 和 Rust 这类系统级语言里感受特别明显。为什么 concurrency(并发)相关的 bug 那么难查?因为多个线程同时读写同一个内存区域,数据竞争一旦发生,崩溃是随机出现的。const 解决不了所有的并发问题,但它能保证一个基本前提:const 对象不会被写入,因此多个线程同时读它是安全的。
这也就是为什么很多大型 C++ 项目在架构设计阶段就会刻意把“只读数据”变成 const。这不是风格偏好,而是一种多线程安全的低成本保障。即使在 JavaScript 这种单线程语言里,随着 Web Worker 的普及,不可变数据在跨线程传递时也能减少很多心智负担。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. JavaScript中的const:let、var、const三者到底怎么选
前端开发里,“let var const 有什么区别”可能是面试中出现频率最高的问题之一。但很多人背完答案就忘了,真正写代码的时候还是随缘。这节我用自己的理解方式重新讲一遍。
