为什么parseInt(8,3)== NaN和parseInt(16,3)== 1?

Dev*_*lli 191 javascript numbers parseint radix

我正在阅读这篇文章,但我对parseInt中使用radix参数章节所写的内容感到困惑

parseInt(_,3)结果表

为什么parseInt(8, 3)NaNparseInt(16, 3)1

据我所知8和16不基地,3个数字,所以parseInt(16, 3)应该返回NaN

前十个基数为3的自然数

T.J*_*der 372

这是人们一直绊倒的事情,即使他们知道这件事.:-)你看到这个因为同样的原因parseInt("1abc")返回1:parseInt停在第一个无效字符并返回它在那一点上的任何东西.如果没有要解析的有效字符,则返回NaN.

parseInt(8, 3)表示" "8"在基数3中解析"(请注意,它将数字8转换为字符串; 规范中的详细信息).但在基地3个,个位数的数字只是0,12.就像要求它以"9"八进制解析一样.由于没有有效的字符,你得到了NaN.

parseInt(16, 3)要求它"16"在基数3中进行解析.既然它可以解析1它,它就会解析它,然后它就会停止,6因为它无法解析它.所以它回来了1.


由于这个问题引起了很多关注并且可能在搜索结果中排名很高,所以这里有一个简单的选项,用于将字符串转换为JavaScript中的数字,以及它们的各种特性和应用程序(取决于我的另一个答案):

  • parseInt(str[, radix]) - 尽可能多地将字符串的开头转换为整数(整数),忽略最后的额外字符.所以parseInt("10x")10; 该x被忽略.支持可选的基数(基数)参数,因此parseInt("15", 16)21(15十六进制).如果没有基数,则假定为十进制,除非字符串以0x(或0X)开头,在这种情况下,它会跳过那些并假定为十六进制.(有些浏览器用于处理0以八进制开头的字符串;从未指定过该行为,并且在ES5规范中明确禁止该行为.)NaN如果找不到可解析的数字,则返回.

  • parseFloat(str)- 喜欢parseInt,但是浮点数并且只支持小数.再串上多余的字符被忽略,所以parseFloat("10.5x")10.5(将x被忽略).因为只支持十进制,parseFloat("0x15")所以0(因为解析结束于此x).NaN如果找不到可解析的数字,则返回.

  • 一元+,例如+str- (例如,隐式转换)使用浮点和JavaScript的标准数字表示法将整个字符串转换为数字(只是数字和小数点=十进制; 0x前缀=十六进制; 0o前缀=八进制[ES2015 +]; 一些实现扩展它将前导0视为八进制,但不是严格模式).+"10x"NaN因为x忽略.+"10"10,+"10.5"10.5,+"0x15"21,+"0o10"8[ES2015 +].有一个问题:+""0,不像NaN你想象的那样.

  • Number(str)- 完全像隐式转换(例如,像+上面的一元),但在某些实现上更慢.(不是说它很重要.)

  • @evolutionxbox:是的,这是`parseInt`算法的第一步:http://www.ecma-international.org/ecma-262/7.0/index.html#sec-parseint-string-radix (16认同)
  • 所以`parseInt`首先在第一个参数上使用`toString`?这是有道理的. (8认同)
  • "这是人们一直绊倒的事情,即使他们知道这件事" - >我是唯一认为这应该是一个错误的人吗?例如,在Java中执行相同操作将每次都给出一个`NumberFormatException`. (6认同)
  • 我想`123e-2`给出`1`,因为它首先变成`1.23`,然后解析停在小数点? (5认同)
  • @SvenMarnach:**parseInt`的一部分(将第一个参数强制转换为string)是有道理的.`parseInt`的目的是*将*解析为整数.因此,如果你给它一些不是字符串的东西,那么从它开始的字符串表示是有意义的.它是什么*之后*这是一个完整的'其他故事...... (4认同)

njz*_*zk2 54

出于同样的原因

>> parseInt('1foobar',3)
<- 1
Run Code Online (Sandbox Code Playgroud)

doc中,parseInt需要一个字符串.和

如果string不是字符串,则将其转换为字符串

所以16,8或者'1foobar'首先转换为字符串.

然后

如果parseInt遇到的字符不是指定基数中的数字,则忽略它和所有后续字符

意味着它可以转换到它可以的位置.的6,8以及foobar被忽略的,只有什么是之前被转换.如果没有,NaN则返回.