JavaScript 作为我的主力开发语言已有多年(当然现在主要是 TypeScript 😉)。我从 ES6 之前就开始接触它,那时候的语言特性比现在基础得多——没有 let 或 const,没有展开运算符,没有 Promise,甚至没有类,只有原型。
那时候编写 JavaScript 代码如同惊险刺激的冒险,必须深入理解语言特性,才能避免误入陷阱。我记得为此研读了大量资料。让我印象最深刻的是 Kyle Simpson 的 《你不知道的 JavaScript》(后更名为《你不知道的 JavaScript(上中下)》)。这些书至今还能在 GitHub 上找到,堪称 JavaScript 知识的宝库。
所以现在,当又有后端同事对 true + true === 2 这样的 JavaScript 特性表示不解时,我只是礼貌地微笑点头……内心却在思索:"但这完全合理啊,因为这样那样再加上……" 哈哈。我以前还会尝试解释,但通常短时间内对方就会露出困惑的表情,所以我放弃了 😅
但在技术社区里,我希望能找到真正想了解技术原理的同行 😂
为什么true + true === 2
这是人们经常讨论的 JavaScript 经典案例:
true + true === 2 // 结果为true
第一眼看上去确实令人困惑。
两个布尔值相加怎么会得出数字?
关键点:+ 主要执行数值运算
在 JavaScript 中,+ 运算符有两种行为模式:
- 如果操作数包含字符串 → 字符串连接
- 其他情况 → 数值加法
由于 true 不是字符串,JavaScript 默认进行数学运算并将两个值转换为数字。
布尔值的数值转换规则
JavaScript 使用名为 ToNumber 的标准内部转换规则:
true→1false→0
因此运算过程如下:
true + true
// 转换为
1 + 1
// 结果等于
2
这并非随意设计。许多编程语言在底层都将布尔值视为数值:
- Python:
True + True === 2 - C/C++:
true表现为1
由此可见,JavaScript 的这种处理方式并非特例——这是编程语言中相当常见的行为。
其他相关案例的分析
基于相同的转换规则,以下表达式的结果都变得容易理解:
true * 10 // 10
false * 10 // 0
true - 1 // 0
一旦理解布尔值会转换为 1 和 0 的机制,这些运算结果就不再令人意外。
技术要点总结
- 除非涉及字符串,否则
+运算符执行数值加法 true转换为1,false转换为0- 这种行为符合编程语言的常见设计模式
这就是为什么 true + true === 2 不是语言缺陷……而是编程逻辑的趣味体现 😎