对象转Number底层实现探究:自定义实现与内置行为差异
Object 转 Number 的完整规范流程
你只实现了OrdinaryToPrimitive这一步,但Number()的转换逻辑是多阶段的,完整流程分两步:
- 先调用
ToPrimitive(input, "number")——对于普通对象来说,这确实会触发你实现的OrdinaryToPrimitive操作 - 拿到第一步返回的原始值后,还要再执行
ToNumber把这个原始值转为数字
你的测试只停留在第一步,所以得到了字符串"[object Object]",但Number({})是走完了全部流程:
- 第一步:
OrdinaryToPrimitive({}, "number")返回字符串"[object Object]" - 第二步:
ToNumber("[object Object]")返回NaN,这才是最终结果
为什么OrdinaryToPrimitive({}, "number")返回字符串?
OrdinaryToPrimitive的逻辑是根据hint指定的优先级调用方法:
- 当hint为
"number"时,优先调用对象的valueOf(),如果返回原始值就用它;否则调用toString(),如果返回原始值就用它;否则抛出错误 - 普通对象的
valueOf()返回对象本身(不是原始值),所以会继续调用toString(),而普通对象的toString()默认返回"[object Object]"(字符串属于原始值),因此这一步返回该字符串
手动模拟完整流程验证
你可以补充完整逻辑来匹配内置Number()的行为:
// 假设这是你实现的OrdinaryToPrimitive function OrdinaryToPrimitive(obj, hint) { if (hint === 'number') { const val = obj.valueOf(); if (typeof val !== 'object') return val; const str = obj.toString(); if (typeof str !== 'object') return str; throw new TypeError('Cannot convert object to primitive value'); } // hint为string的情况省略,当前场景用不到 } // 模拟Number()的完整转换逻辑 function objectToNumber(obj) { const primitive = OrdinaryToPrimitive(obj, 'number'); // 对原始值执行ToNumber转换 return typeof primitive === 'string' ? Number(primitive) : primitive; } // 测试 console.log(objectToNumber({})); // 输出NaN,和内置Number({})一致
内容的提问来源于stack exchange,提问作者Petar
相关产品推荐
相关产品推荐

