number([])为0、number({})为nan、number(null)为0:空数组经valueof失败后tostring得空字符串再转0;空对象tostring得"[object object]"含非数字字符故为nan;null是规范强制映射的特例,不走转换流程。
![如何利用 number() 转换 []、{} 与 null 的非直观结果分析](https://img.php.cn/upload/article/001/242/473/177804892855737.png?x-oss-process=image/resize,p_40)
Number() 对 []、{} 和 null 的转换结果看似矛盾,实则严格遵循隐式转换协议。关键不在“值像什么”,而在“怎么一步步算出来”。
空数组 [] → 0:toString() 先赢了
数组是对象,Number([]) 不会直接返回 NaN。它按规则先调用 [].valueOf() —— 返回原数组(仍是对象),不满足基本类型,于是继续调用 [].toString(),得到空字符串 ""。再对 "" 执行 Number 转换,规则明确:空字符串转为 0。
-
Number([])等价于Number("".toString()) → Number("") → 0 - 单元素数组如
[5]或["42"]同理:转成"5"或"42",再转数字 - 多元素数组如
[1,2]→"1,2"→ 含逗号 → 非法数字字符 → NaN
空对象 {} → NaN:卡在 toString() 的死胡同里
{} 是普通对象,其 {}.valueOf() 默认返回自身(对象),接着调用 {}.toString(),返回 "[object Object]"。这个字符串含字母和方括号,完全不符合 Number 的字符串解析规则,所以结果是 NaN。
-
Number({})≡Number("[object Object]")→ 包含非数字字符 → NaN - 哪怕加个属性,比如
{a:1},toString 结果仍是"[object Object]"→ 还是 NaN - 自定义
toString()可改变结果,例如:let obj = { toString(){return "123"} }; Number(obj) → 123
null → 0:这是硬编码的例外规则
null 是唯一一个既不是基本数字、也不是字符串或布尔值,却有确定数字映射的原始值。ECMAScript 明确规定:Number(null) 返回 0。这不是推导出来的,而是规范直给的特例。
- 它不走 valueOf/toString 流程(null 没有这些方法)
- 也不等同于“空”或“假值”的语义推断(否则 undefined 也该是 0,但它却是 NaN)
- 设计初衷与表单空输入兼容有关:把未填写的数值字段视作 0 更便于计算
对比记忆要点
三者差异本质在于“触发路径不同”:
-
[]:对象 → valueOf 失败 → toString 得""→ 0 -
{}:对象 → valueOf 失败 → toString 得"[object Object]"→ NaN -
null:原始值 → 绕过所有方法 → 规范强制映射 → 0
理解这三条路径,就不再觉得结果“反直觉”了。










