为什么JavaScript的Number构造函数无法解析带数值分隔符的字符串?
核心原因
数值分隔符_是JavaScript源码词法阶段的字面量语法,仅在引擎解析你写的代码文本时生效,从来没被纳入运行时字符串转数字的解析规则,和0x十六进制前缀的适用场景完全不同,二者根本不存在要保持逻辑一致的前提。
具体规则差异
- 源码中写
3_0时,JS引擎在代码加载的词法分析阶段就会处理这个值:按照数值字面量(NumericLiteral)的解析规则,下划线只是给开发者看的视觉分隔符,会被直接忽略,最终得到的字面量值就是数字30。也就是说执行Number(3_0)的时候,传给Number()的参数已经是解析完成的数字30,完全没有运行时识别下划线的步骤。 - 调用
Number("3_0")走的是运行时字符串转数字的类型转换逻辑,对应规范里的StringNumericLiteral解析规则:这套规则从设计上就没把下划线列为合法字符,只要字符串里出现规则允许范围外的字符,直接返回NaN。
为什么
Number("0x08")能正常返回8 0x作为十六进制前缀,本身就是StringNumericLiteral规则里明确支持的合法标记,后面跟的十六进制数字也在允许的字符范围内,自然能正常解析出数值8。这是字符串转数字规则原生支持的写法,和只在源码层面生效的数值分隔符根本不属于同一套规则的覆盖范围,不能直接类比。
你可以通过示例代码直观看到二者的行为差异:
Number.isNaN(Number("3_0")) // true,字符串解析不识别下划线 Number.isNaN(Number(3_0)) // false,源码字面量阶段已经把3_0解析成30 Number("3_0") === 30 // false Number(3_0) === 30 // true
常见踩坑:
parseInt("3_0")同样不识别下划线,它会在碰到第一个非数字字符时直接截断解析,最终返回3,不会得到30。
内容的提问来源于stack exchange,提问作者Wersjon
相关产品推荐
相关产品推荐

