空对象 {} 转数字得 NaN,因其 toString() 返回 "[object Object]",Number() 无法解析该字符串为有效数字;而空数组 [] 的 toString() 返回空字符串 "",Number("") 依规范返回 0。

空对象 {} 转数字得到 NaN,根本原因是 JavaScript 的类型转换规则在对象到原始值的转换过程中,最终无法生成有效的数值字符串。
对象转数字的底层步骤
当对一个对象(如 {})执行数字转换(比如 +{}、Number({}) 或参与算术运算)时,JavaScript 会按以下顺序尝试转换:
- 先调用对象的
valueOf()方法,如果返回的是原始值(如字符串、数字),就用它继续转数字; - 否则,再调用
toString()方法,把返回的字符串作为输入传给Number(); - 如果两者都返回非原始值(极少见),则抛出 TypeError —— 但空对象不会这样。
对于空对象 {}:
- {}.valueOf() 返回的是对象本身(不是原始值),所以跳过;
- 接着调用 {}.toString(),结果是字符串 "[object Object]";
- 最后执行 Number("[object Object]"),而这个字符串无法被解析为有效数字,因此返回 NaN。
为什么不是转成 0 或其他默认值
JavaScript 的类型转换不基于“语义猜测”,而是严格遵循规范定义的抽象操作:
- 没有规则说“空对象代表零”或“空意味着无,无就是 0”;
- Number() 只接受能明确表示数字的字符串(如 "123"、"-45.6"、"0x1F"),或 null(转为 0)、undefined(转为 NaN)、布尔值等有限几种原始值;
- "[object Object]" 显然不属于这些可解析格式,所以只能是 NaN。
常见误解与对比
有人会疑惑:“空数组 [] 转数字是 0,那空对象为啥不是?”这是因为:
-
[].toString()返回空字符串"",而Number("") === 0(规范规定空字符串转数字为 0); -
{}.toString()返回"[object Object]",不是空字符串,也不匹配任何数字字面量格式。
同理,new Date()、/regex/ 等对象转数字也依赖各自 toString() 的返回值,结果各不相同。
如何避免意外得到 NaN
如果业务中需要安全地将可能为对象的值转数字,建议显式处理:
- 先判断是否为对象且非
null,再决定是否取某个属性(如obj?.value); - 用
typeof x === 'object' && x !== null排除对象; - 使用空值合并或默认值:
Number(x ?? 0)或isNaN(Number(x)) ? 0 : Number(x); - 更稳妥的方式是用
parseFloat(x)配合isFinite()判断,或封装校验逻辑。
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











