JavaScript数值转换与运算的陷阱在于隐式转换规则:Number("012")→12、parseInt("42px")→42、[]+{}→"[object Object]"、0==""→true等均符合规范但易致逻辑错误。

JavaScript 数值转换与运算中的边界陷阱,核心不在“会不会出错”,而在于“什么时候悄悄出错”。很多问题不是报错,而是结果不对——比如 "012" - 1 得到 11,[] + {} 变成 "[object Object]",或 0 == "" 返回 true。这些都不是 bug,而是规范行为;但若不了解规则,就极易埋下隐患。
字符串转数字:看似简单,实则多层解析
Number()、一元加号 +str、parseInt() 表面都“转数字”,但逻辑完全不同:
-
Number("012") → 12:忽略前导零,按十进制解析(不是八进制);但
Number("0x12") → 18,会识别十六进制前缀 -
Number("") → 0,而
parseInt("") → NaN:空字符串对 Number 是“有效输入”,对 parseInt 却是“无数字可读” -
Number("42px") → NaN,但
parseInt("42px") → 42:后者只取开头连续数字,前者要求整个字符串可完全解析 -
Number(" 42 ") → 42,自动 trim 空格;
parseInt同样跳过首尾空白,但遇到中间空格即停(如parseInt("42 12") → 42)
+ 运算符:加法还是拼接?取决于第一个字符串
只要任一操作数是字符串,+ 就变成拼接操作,且转换不可逆:
-
1 + 2 + "3"→ 先算1 + 2 = 3,再3 + "3" = "33" -
"1" + 2 + 3→ 全部转字符串:"1" + "2" + "3" = "123" -
[] + {}→ 空数组[]转为空字符串"",对象{}转为"[object Object]",结果是"[object Object]" -
true + 0→true先转1,再算1 + 0 = 1;但true + "0"→"true0"
== 比较中的隐式转换链:一次比较,多次转换
双等号会触发 ToPrimitive → ToNumber 或 ToString 的级联转换,极易绕晕逻辑:
立即学习“Java免费学习笔记(深入)”;
-
0 == false→false转0,再比0 == 0→true -
"0" == false→ 两边都转数字:Number("0") → 0,Number(false) → 0→true -
[] == ![]→ 右边![]是false,左边[]转字符串得"",再转数字得0,0 == 0→true -
null == undefined是特例,直接返回true,不走转换流程;但null == 0→false(因为null只与undefined特殊相等)
数值边界值的真假判断:0、-0、NaN 不等于“没值”
在 if、||、&& 中,它们被统一归为 falsy,但语义和行为差异极大:
-
if (0)不执行,但0 === 0为true;0 === -0也是true,但Object.is(0, -0)是false -
NaN == NaN是false,必须用isNaN(x)或Number.isNaN(x)判断 -
null和undefined都是 falsy,但Number(null) → 0,Number(undefined) → NaN,参与运算后果完全不同 -
Boolean(new Date('invalid'))是true,但new Date('invalid').getTime()是NaN,后续计算会污染结果
不复杂但容易忽略


















