- 文档
- 教程
- 前端
【免费下载链接】zh.javascript.info
现代 JavaScript 教程(The Modern JavaScript Tutorial),以最新的 ECMAScript 规范为基准,通过简单但足够详细的内容,为你讲解从基础到高阶的 JavaScript 相关知识。
本篇围绕《现代 JavaScript 教程》中文版(zh.javascript.info)变量章节中的经典练习「大写的常量?」展开,系统讲解 JavaScript 中const常量的两种命名风格——大写加下划线(如BIRTHDAY)与常规驼峰式(如age)——各自的适用场景与判断标准。读完你不仅能正确解答这道练习题,还能在真实项目中建立一套可复用的常量命名决策规则,写出可读性更高、更符合社区惯例的代码。
一、原题复现:一个关于常量大写命名的判断题
练习位于 3-uppercast-constant/task.md,题目给出了一段代码(task.md):
const birthday = '18.04.1982'; const age = someCode(birthday);场景设定如下:
birthday是一个日期常量,其值'18.04.1982'在写代码时就已经确定;age是通过一些代码(题目中简写为someCode,细节无关紧要)从birthday计算出来的常量。
问题由此而来:对birthday使用大写命名正确吗?对age呢?还是两者都用大写?
const BIRTHDAY = '18.04.1982'; // 使用大写? const AGE = someCode(BIRTHDAY); // 使用大写?表面上看,birthday和age都是用const声明的、赋值后不再改变的常量,似乎「一视同仁」地大写最省事。但这正是本题要纠正的常见误区——「常量」与「大写命名」并不是同一回事。
二、标准答案:只有硬编码的BIRTHDAY应该大写
官方题解位于 3-uppercast-constant/solution.md,结论非常明确(solution.md):
我们通常用大写字母表示「硬编码(hard-coded)」的常量。或者,换句话说就是,当值在执行之前或在被写入代码的时候,我们就知道值是什么了。
birthday应该用大写:'18.04.1982'这个值在代码被写入的那一刻就已经确定,不依赖任何运行时信息,属于典型的硬编码常量,因此写成BIRTHDAY是正确的。age应该用小写:它的值是在程序运行时由someCode(birthday)计算出来的。今天的年龄是一个数,一年之后重新运行又会得到另一个数。它虽然被const锁定、赋值后不会改变,但它的值并非「写代码时已知」,而是运行时推导的结果,因此应保持常规命名age。
一句话总结题解的核心逻辑:「大写」不是「const」的附属品,而是「硬编码」的标识。判断标准只有一个——这个值是否在代码执行之前就已经已知。
三、判断依据:大写命名只用于「硬编码」值的别名
这道题的背后,是 article.md 中「大写形式的常数」一节的完整理论。原文给出了一个经典的应用场景——用大写常量作为难以记忆的值的别名(article.md):
const COLOR_RED = "#F00"; const COLOR_GREEN = "#0F0"; const COLOR_BLUE = "#00F"; const COLOR_ORANGE = "#FF7F00"; // ……当我们需要选择一个颜色 let color = COLOR_ORANGE; alert(color); // #FF7F00这里的COLOR_RED、COLOR_ORANGE等,就是把「执行之前就已知的难以记住的值」翻译成有语义的名字。原文档总结了三个核心好处:
- 更易记忆:
COLOR_ORANGE比"#FF7F00"更容易记住; - 更不易出错:比起
COLOR_ORANGE,手写"#FF7F00"更容易打错; - 更易阅读:阅读代码时,
COLOR_ORANGE比#FF7F00的含义直观得多。
这一实践的本质,是把魔法值(magic value)提炼为具名常量,属于代码可读性优化中最低成本、最高回报的一步。凡是在执行之前、写代码时值就已确定的常量——颜色值、端口号、正则表达式片段、业务中的固定日期等——都适合用大写加下划线命名。
对照组:运行时计算出的「常量」仍用常规命名
原文档紧接着给出了一个与题目完全同构的示例(article.md):
const pageLoadTime = /* 网页加载所需的时间 */;pageLoadTime的值在页面加载之前是未知的,需要运行时测量,因此采用常规命名;- 但它依然是个常量,因为初始赋值之后不会改变。
于是整个命名体系就清晰了:const只负责「不可重新赋值」,而命名风格由「值何时可知」决定。文档的结论原话是:大写命名的常量仅用作「硬编码(hard-coded)」值的别名(article.md)。回到题目:AGE是计算值而非硬编码别名,所以用大写反而会误导读者——让人误以为它是写代码时就定死的魔数,从而掩盖了「年龄会随时间变化」这一语义信息。
四、从const到let/var:常量与变量的完整命名图景
要真正掌握这道题,还需要把它放回「变量」大章节的坐标系里,看清const与另外两个声明关键字的区别,以及整套命名规范。
4.1 三种声明关键字的分工
article.md 对常量做了明确定义:
const:声明「常量」,赋值后不可修改。尝试重新赋值会直接报错(article.md):
const myBirthday = '18.04.1982'; myBirthday = '01.01.2001'; // 错误,不能对常量重新赋值let:现代 JavaScript 的变量声明方式,值可以任意修改;var:老式的变量声明方式,与let大体相同但存在微妙差别,属于「老派」写法。相关差异在 var 章节中专门讲解,日常新代码中一般不再使用。
当程序员能确定某个变量永远不会被改变时,就应该使用const——它既是一种运行时保护(阻止误赋值),也是一种对读者的明确信号(「这个值不会变」)。
4.2 变量命名的硬性语法约束
无论let、var还是const,标识符命名都要满足两条语法规则(article.md):
- 名称只能包含字母、数字、符号
$和_; - 首字符不能是数字。
合法示例:userName、test123、$、_($和_是普通符号,没有特殊含义)。非法示例:1a(不能以数字开头)、my-name(连字符-不允许)。
另外注意两点:
- 区分大小写:
apple与APPLE是两个完全不同的变量——这正是BIRTHDAY与birthday可以同时存在、含义各异的前提; - 保留字不可用作变量名:
let、class、return、function等保留字都会导致语法错误(article.md)。
多单词变量名遵循驼峰式命名法(camelCase),例如myVeryLongName。
4.3 命名质量:清晰、准确、符合团队术语
除了语法合规,article.md 还给出了一组可落地的命名建议:
- 使用易读的命名,如
userName、shoppingCart; - 远离
a、b、c这类无意义缩写,除非你确切知道自己在做什么; - 在准确描述变量的同时保持简洁——
data、value这类「什么都没说」的名字要慎用; - 与团队术语保持一致:如果访客被称为「用户」,就用
currentUser、newUser,而不是自创currentVisitor。
「为不同的值使用不同的变量」也是一条重要经验:额外声明一个变量绝对利大于弊。现代 JavaScript 压缩器和浏览器都能很好地对代码进行优化,多变量不会带来性能问题,反而能帮助引擎优化代码。这道「大写的常量?」练习正是这套命名哲学的具体考题:好的命名不仅要「合法」,更要「准确传达值的性质」。
五、实战决策清单
把原文档理论与本题结合,可以得到一张可直接套用的常量命名决策清单:
| 场景 | 示例 | 命名风格 | 理由 |
|---|---|---|---|
| 值在写代码时已知(硬编码) | 颜色值、固定日期、端口号 | UPPER_SNAKE_CASE(如BIRTHDAY、COLOR_ORANGE) | 用作难以记忆值的具名别名,语义清晰 |
| 值在运行时计算得出,赋值后不变 | 年龄、页面加载时间、用户年龄 | camelCase(如age、pageLoadTime) | 值依赖运行时,大写会误导读者 |
| 值会随程序执行而改变 | 计数器、用户输入 | let+ camelCase | 本质是变量,不是常量 |
判断口诀:先问「这个值在执行前是否已知」,再决定大写还是常规命名;const只负责锁定赋值,不决定命名风格。
六、总结
「大写的常量?」这道看似简单的判断题,浓缩了 JavaScript 命名规范中最容易被忽略的一条原则:大写命名是「硬编码」的记号,而非「不可变」的记号。BIRTHDAY因为值在写代码时已知而大写,AGE因为是运行时计算值而保持小写。理解并内化这条规则,配合let/var/const的语义差异与驼峰式命名习惯,你就能在任何 JavaScript 项目中写出「看一眼名字就知道值是什么、什么时候确定」的代码。
相关资源汇总:
- 练习题原文:3-uppercast-constant/task.md
- 官方题解:3-uppercast-constant/solution.md
- 变量章节正文(含「大写形式的常数」完整论述):04-variables/article.md
- 同章节其他练习:1-hello-variables/task.md、2-declare-variables/task.md
- 后续深入阅读
var与let的差异:var 章节
- 文档
- 教程
- 前端
【免费下载链接】zh.javascript.info
现代 JavaScript 教程(The Modern JavaScript Tutorial),以最新的 ECMAScript 规范为基准,通过简单但足够详细的内容,为你讲解从基础到高阶的 JavaScript 相关知识。
相关推荐
AVA 断言计划(t.plan)深度指南:什么时候该用、什么时候不该用
AVA 断言计划(t.plan)深度指南:什么时候该用、什么时候不该用 t.plan 是 AVA 测试运行器提供的一项"断言计划"能力,它允许你预先声明一个测试
测试Rocket.Chat 什么时候该把端点放进 /api/experimental 命名空间?
Rocket.Chat 什么时候该把端点放进 /api/experimental 命名空间? 当你在 Rocket.Chat 里开发一个新的 REST API
即时通讯后端前端raylib 跨平台安装:Windows、macOS、Linux 从第一个窗口到接入项目
raylib 跨平台安装:Windows、macOS、Linux 从第一个窗口到接入项目 raylib 是一个用 C 语言编写的开源游戏开发库,提供窗口、图形、
任务调度后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考