原文链接 Solving a Mystery Behavior of parseInt() in JavaScript — 作者 Dmitri Pavlutin

parseInt() 是一个内置的 JavaScript 函数,它能够将数字字符串解析为整数。比方,咱们将数字字符串 '100' 解析为整数:

const number = parseInt('100');
number; // 100

如预期那样,'100' 被解析为整数 100

parseInt(numericalString, radix) 也接受第二个参数:radix(基数),另一个参数是数字字符串 numericalStringradix 参数答应你解析来自不同数字基数的字符串为整数,基数通常有 2,8, 10 和 16

咱们运用基数为 2parseInt() 来解析一个数字字符串:

const number = parseInt('100', 2);
number; // 4

parseInt('100', 2) 以基数 2 解析 '100' 为一个整数:所以它返回十进制数值 4

上面便是对 parseInt() 办法的简略介绍。

1. parseInt() 中的一个奇怪行为

parseInt(numericalString) 总是将其第一个参数转化成字符串(假如它不是字符串的话),然后将这个字符串数字解析成整数。

这便是为什么你能够(但是不该这么做! )运用 parseInt() 来提取浮点数的整数部分:

parseInt(0.5); // => 0
parseInt(0.05); // => 0
parseInt(0.005); // => 0
parseInt(0.0005); // => 0
parseInt(0.00005); // => 0
parseInt(0.000005); // => 0

取出浮点数,比方 0.50.05 等等整数的部分。结果便是 0。这跟咱们的预期结果一样。

那么提取 0.0000005 整数的部分会怎样呢?

parseInt(0.0000005); // => 5

parseInt() 将浮点数 0.0000005 解析为 5。这就很风趣且不符合预期…

为什么 parseInt(0.0000005) 会有如此奇怪的行为呢?

2.解决 parseInt() 该奇怪行为

咱们回忆下,parseInt(numericalString) 对它的第一个参数做了什么:假如不是字符串,就将其转化为一个字符串,然后解析,之后返回解析的整数。

这可能是第一个线索。

咱们手动将浮点数转化为字符串表现方式:

String(0.5); // => '0.5'
String(0.05); // => '0.05'
String(0.005); // => '0.005'
String(0.0005); // => '0.0005'
String(0.00005); // => '0.00005'
String(0.000005); // => '0.000005'
String(0.0000005); // => '5e-7'

String(0.0000005) 数值的显式转化和其它浮点数不同:它是指数符号exponential notation 字符串表现方式。

这是第二个线索 — 很重要!

然后当指数符号字符串解析为整数,你就会得到整数 5

parseInt(0.0000005); // => 5
// same as
parseInt(5e-7); // => 5
// same as
parseInt('5e-7'); // => 5

parseInt('5e-7') 考虑第一个数字 '5',跳过了 'e-7'

解密了!由于 parseInt() 总是将它第一个参数转化为字符串,浮点数字小于 10−610^{-6} 就会被写成指数符号的方式。parseInt() 从浮点数的指数符号中取出整数。

译者加 — 注意,parseInt() 取字符串前面整数的部分,比方:parseInt('12Jimmy34') 则有返回结果 12

备注,安全地取出浮点数整数的部分,我推荐运用 Math.floor() 函数:

Math.floor(0.5); // => 0
Math.floor(0.05); // => 0
Math.floor(0.005); // => 0
Math.floor(0.0005); // => 0
Math.floor(0.00005); // => 0
Math.floor(0.000005); // => 0
Math.floor(0.0000005); // => 0

3. 总结

parseInt() 是个将数字字符串转化为整数的函数。

当你运用 parseInt() 获取浮点数的整数部分的时候,要小心。

小于 10−610^{-6} 的浮点数(比方 0.0000005 等同于 5∗10−75 * 10^{-7})被转化为以指数符号表示方式(比方 5e-70.0000005 指数符号方式)。这便是为什么运用 parseInt() 作用于如此小的浮点数会出现非预期效果:仅解析指数表示方式的重要部分(比方 5e-7 中的 5)。

挑战:你能够解释为什么 parseInt(999999999999999999999) 会等于 1 能够在下面评论区写出你的思路。

本文正在参与「金石计划 . 分割6万现金大奖」