我正在阅读这篇文章,但我对带有基数参数的parseInt章节中所写的内容感到困惑。
为什么parseInt(8, 3)
→ NaN
,而parseInt(16, 3)
→ 1
?
据我所知,8和16不是基于3的数字,因此parseInt(16, 3)
也应该返回NaN
我正在阅读这篇文章,但我对带有基数参数的parseInt章节中所写的内容感到困惑。
为什么parseInt(8, 3)
→ NaN
,而parseInt(16, 3)
→ 1
?
据我所知,8和16不是基于3的数字,因此parseInt(16, 3)
也应该返回NaN
即使人们知道这一点,他们仍然经常犯错。 :-) 你之所以看到这个问题,是因为parseInt("1abc")
返回1的原因相同:parseInt
在遇到第一个无效字符时停止,并返回此时的内容。如果没有有效字符可解析,则返回NaN
。
parseInt(8, 3)
表示“在基数3中解析"8"
”(请注意,它将数字8
转换为字符串;规范中的详细信息)。但在基数3中,单个数字只有0
、1
和2
。这就像要求它在八进制中解析"9"
。由于没有任何有效字符,所以得到了NaN
。
parseInt(16, 3)
要求将 "16"
以基数3解析。它可以解析 1
,因此解析了它,然后停止在 6
上,因为无法解析它。所以返回值为 1
。
由于这个问题受到了很多关注并且可能在搜索结果中排名较高,因此以下是JavaScript中将字符串转换为数字的选项概述,包括它们各自的特点和应用(摘自我在SO上的另一个答案):
parseInt(str[, radix])
- 把字符串开头尽可能多的部分转换成整数,忽略末尾的额外字符。所以parseInt("10x")
是10
;x
被忽略了。支持可选的进制(数字基数)参数,所以parseInt("15", 16)
是21
(16进制中的15
)。如果没有进制,则假定为十进制,除非字符串以0x
(或0X
)开头,此时会跳过它们并假定为16进制。 (一些浏览器曾经将以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)
- 与隐式转换(例如,像上面的一元+
)完全相同,但在某些实现上速度较慢。 (虽然这不太可能有影响。)
parseInt
首先在第一个参数上使用 toString
?那很有道理。 - evolutionxboxparseInt
算法的第一步:http://www.ecma-international.org/ecma-262/7.0/index.html#sec-parseint-string-radix - T.J. Crowder123e-2
会得到1
,因为它首先变成1.23
,然后解析停在小数点处。 - ilkkachu出于同样的原因
>> parseInt('1foobar',3)
<- 1
在文档中,parseInt
接受一个字符串。如果字符串不是一个字符串,则它会被转换为字符串。因此,16
、8
或'1foobar'
首先被转换为字符串。然后,如果parseInt
在指定基数中遇到一个非数字字符,它将忽略它和所有后续字符,这意味着它会尽可能地进行转换。其中的6
、8
和foobar
都被忽略,只有前面的部分被转换。如果没有任何内容,将返回NaN
。/***** Radix 3: Allowed numbers are [0,1,2] ********/
parseInt(4, 3); // NaN - We can't represent 4 using radix 3 [allowed - 0,1,2]
parseInt(3, 3); // NaN - We can't represent 3 using radix 3 [allowed - 0,1,2]
parseInt(2, 3); // 2 - yes we can !
parseInt(8, 3); // NaN - We can't represent 8 using radix 3 [allowed - 0,1,2]
parseInt(16, 3); // 1
//'16' => '1' (6 ignored because it not in [0,1,2])
/***** Radix 16: Allowed numbers/characters are [0-9,A-F] *****/
parseInt('FOX9', 16); // 15
//'FOX9' => 'F' => 15 (decimal value of 'F')
// all characters from 'O' to end will be ignored once it encounters the out of range'O'
// 'O' it is NOT in [0-9,A-F]
更多例子:
parseInt('45', 13); // 57
// both 4 and 5 are allowed in Radix is 13 [0-9,A-C]
parseInt('1011', 2); // 11 (decimal NOT binary)
parseInt(7,8); // 7
// '7' => 7 in radix 8 [0 - 7]
parseInt(786,8); // 7
// '78' => '7' => 7 (8 & next any numbers are ignored bcos 8 is NOT in [0-7])
parseInt(76,8); // 62
// Both 7 & 6 are allowed '76' base 8 decimal conversion is 62 base 10