为什么 parseInt(1/0, 19) 会等于 18 ?
有人说:
JS就是这么神奇! pic.twitter.com/VMSaw7ft0u
— 雪月秋水 (@acgotaku311) 2018年1月18日
这是为什么呢?
1
1/0 是 Infinity
2
ECMA-262 标准里 18.2.5 parseInt(string,radix)
写到:
- Let inputString be ? ToString(string).
7.1.12 ToString(argument)
下面的 7.1.12.1 ToString Applied to the Number Type
里规定:
- If m is +∞, return the String "Infinity".
所以被转换进制的值是 "Infinity"
。
3
ECMA-262 标准里 18.2.5 parseInt(string,radix)
写到:
(跳过移除空白,改变正负等步骤)
- If S contains a code unit that is not a radix‐R digit, let Z be the substring of S consisting of all code units before the irst such code unit;
保留第一个这个基数不认的字符前面的部分,忽略后面的内容。如果是 19 进制,那么 I
是最大的个位数。在这个例子里,"Infinity"
19进制只认第一个 I
,不认识第二个 n
,所以最终字符串就是 I
。
4
然后开始进制转换。以 I
为例, 在 19 进制中表示 18,所以返回 18。没😹病。
5
再来个复杂点的例子,为什么 parseInt(1/0, 24) === 151176378
呢?我们来算一下。
先把 24进制和 10进制对应起来:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
再把 Infinity 跟 10进制数字对应起来,加上进制:
I | N | F | I | N | I | T | Y |
---|---|---|---|---|---|---|---|
18 | 23 | 15 | 18 | 23 | 18 | X | X |
-- | -- | -- | -- | -- | -- | -- | -- |
5 | 4 | 3 | 2 | 1 | 0 |
所以计算:
$$18\times24^5+23\times24^4+15\times24^3+18\times24^2+23\times24^1+18\times24^0=151176378$$