Skip to content

字符串转数字

JavaScript 内部在进行 字符串转数字 时,主要依赖 ToNumber 抽象操作,该操作遵循 ECMAScript 规范,并且不同的转换方式(Number()parseInt()parseFloat()+ 一元运算符等)在底层实现上有所不同。


1. ToNumber 规则

根据 ECMAScript 规范(ECMA-262),字符串转数字的规则如下:

字符串值转换结果
""(空字符串)0
"-0"-0
"+0"0
"-123"-123
"123"123
" 123 "(前后空格)123
"123.45"123.45
"1e3"1000(科学计数法)
"0x10"16(十六进制)
"Infinity"Infinity
"-Infinity"-Infinity
"NaN"NaN
"123abc"NaN(无法完整解析)
"0b101"NaN(不支持二进制)
null0
undefinedNaN
true1
false0

2. 不同方法的底层转换

(1) Number(str)

  • 遵循 ToNumber 规则,会转换合法数字字符串,但不支持部分匹配(如 "123abc"NaN)。
  • 规范实现:
    1. 去掉前后空格。
    2. 识别 +/- 符号。
    3. 解析十进制、科学计数法、十六进制(0x)。
    4. 其他返回 NaN
js
console.log(Number("123"));       // 123
console.log(Number("  123  "));   // 123
console.log(Number("0x10"));      // 16
console.log(Number("123abc"));    // NaN
console.log(Number("1e3"));       // 1000

(2) parseInt(str, radix)

  • 逐字符解析,遇到非数字字符 停止,不报错(如 "123abc"123)。
  • 可指定 进制(如 0x → 16 进制)。
  • 规范实现:
    1. 跳过前导空格。
    2. 解析 +/- 符号。
    3. 解析 0x(十六进制)。
    4. 遇到 非法字符 停止。
js
console.log(parseInt("123abc"));   // 123  ✅
console.log(parseInt("0x10"));     // 16   ✅ (十六进制)
console.log(parseInt("0123", 10)); // 123  ✅ (显式十进制)
console.log(parseInt("0b101"));    // 0    ❌ (不支持二进制)
console.log(parseInt("Infinity")); // NaN  ❌

(3) parseFloat(str)

  • 类似 parseInt(),但支持 小数点科学计数法
  • 解析 直到非法字符,不会报错。
js
console.log(parseFloat("123.45abc"));  // 123.45 ✅
console.log(parseFloat("1e3"));        // 1000   ✅
console.log(parseFloat("0.1e2"));      // 10     ✅
console.log(parseFloat("Infinity"));   // Infinity ✅
console.log(parseFloat("0b101"));      // 0       ❌

(4) +str(一元加号)

  • 最简洁,等同于 Number(str),遵循 ToNumber 规则。
js
console.log(+"123");       // 123 ✅
console.log(+"  123  ");   // 123 ✅
console.log(+"0x10");      // 16  ✅
console.log(+"123abc");    // NaN ❌
console.log(+"1e3");       // 1000 ✅

3. ToNumber 处理非字符串情况

JavaScript 隐式类型转换 会调用 ToNumber(),它不仅限于字符串,还适用于布尔值、nullundefined、对象等:

Number() 转换结果
true1
false0
null0
undefinedNaN
{}NaN
[]0
['123']123
['123abc']NaN
js
console.log(Number(true));        // 1
console.log(Number(null));        // 0
console.log(Number(undefined));   // NaN
console.log(Number([]));          // 0
console.log(Number(["123"]));     // 123
console.log(Number(["123abc"]));  // NaN
console.log(Number({}));          // NaN

4. 性能比较

方法速度特性适用场景
Number(str)⭐⭐⭐⭐严格转换,不支持部分匹配需要严格转换时
+str⭐⭐⭐⭐⭐最快,等同 Number(str)需要快速转换时
parseInt(str)⭐⭐⭐支持部分匹配,遇到非数字停止解析整数时
parseFloat(str)⭐⭐⭐支持小数,遇到非数字停止解析小数时
js
console.time("Number");
for (let i = 0; i < 1e6; i++) Number("123");
console.timeEnd("Number");

console.time("+");
for (let i = 0; i < 1e6; i++) +"123";
console.timeEnd("+");

结果表明 +str 是最快的。


5. 结论

  • Number(str)+str最严格 的转换方式,不能解析 123abc,但速度最快。
  • parseInt(str)parseFloat(str) 可部分匹配,但 性能略低
  • ToNumber 规则处理 null0undefinedNaN,注意隐式转换。

实际开发中:

  • 需要严格转换Number(str)+str
  • 允许部分匹配parseInt() / parseFloat()
  • 处理 JSON 解析JSON.parse(str)