问题描述
今天,我偶然发现了一个奇怪的JavaScript案例.我将一个非十六进制字符串传递给以16为底的parseInt函数,并且...得到了结果.我希望该函数引发某种异常或至少返回NaN,但它成功解析了该函数并返回了一个int.
today I stumbled on a strange (in my opinion) case in JavaScript. I passed a non-hexadecimal string to the parseInt function with the base of 16 and...I got the result.I would expect the function to throw some kind of exception or at least return NaN, but it succeeded parsing it and returned an int.
我的电话是:
var parsed = parseInt('dsff66', 16); // note the 's' in the first argument
document.write(parsed);
结果为: 13
.
我注意到它会停止"解析不属于第二个参数中指定的数字系统的第一个字符,因此调用 parseInt('fg',16)
我会得到结果是 15
.
I noticed that it "stops" parsing with the first character that doesn't belong to the numeral system specified in the 2nd argument, so calling parseInt('fg',16)
I would get 15
as a result.
在我看来,它应该返回NaN.谁能向我解释为什么不这样做?为什么有人会希望这个函数的行为像这样(即使不是传递的字符串的精确表示,也要返回一个整数)?
In my opinion, it should return NaN. Can anyone explain to me why it doesn't? Why would anyone want this function to behave like this (return an integer even if it isn't the precise representation of the string passed) ?
推荐答案
因为大多数时候(到目前为止)您都在使用基数为10的数字,在这种情况下,JS可以 cast -不解析-将字符串转换为数字.(显然不只是10级;请参见下面的更新.)
Because most of the time (by far) you're working with base 10 numbers, and in that case JS can just cast - not parse - the string to a number. (edit: Apparently not just base-10; see update below.)
由于JS是动态键入的,因此某些字符串可以很好地用作数字,而无需您进行任何操作.例如:
Since JS is dynamically typed, some strings work just fine as numbers without any work on your part. For instance:
"21" / 3; // => 7
"12.4" / 4; // => 3.1
在那里不需要 parseInt
,因为"21"
和"12.4"
本质上已经是数字.但是,如果字符串为"12.4xyz"
,那么除法时您确实会得到 NaN
,因为它绝对不是数字,因此不能隐式转换或强制转换为一个.
No need for parseInt
there, because "21"
and "12.4"
are essentially numbers already. If, however the string was "12.4xyz"
then you would indeed get NaN
when dividing, since that is decidedly not a number and can't be implicitly cast or coerced to one.
您还可以使用 Number(someString)
明确地将字符串广播"为数字.的确会为无效字符串返回 NaN
.
You can also explicitly "cast" a string to number with Number(someString)
. it will indeed return NaN
for invalid strings.
因此,由于JS已经具有隐式和显式类型转换/转换/强制,因此 parseInt
的作用不再是另一个类型转换功能.
So because JS already has implicit and explicit type casting/conversion/coercion, parseInt
's role isn't to be a yet another type casting function.
parseInt
的角色应该是 parsing 函数.一个函数将尽最大努力使其输入有意义,并返回可以返回的内容.这是因为当您有一个不能的字符串时,因为它不是十分完美的数字,所以不能进行强制转换.(而且,就像JS的基本语法一样,它使人联想到C,因为施药者的回答很好地解释了这一点.)
parseInt
's role is instead to be, well, a parsing function. A function that tries its best to make sense of its input, returning what it can. It's for when you have a string you can't just cast because it's not quite perfectly numeric. (And, like JS's basic syntax, it's reminiscent of C, as apsillers' answer explained nicely.)
由于它是解析器,而不是强制转换功能,因此它具有能够处理除10以外的其他基数的附加功能.
And since it's a parser, not a casting function, it's got the additional feature of being able to handle other bases than 10.
which'll throw a SyntaxError
because 0xdsff66
isn't a valid hex literal.
更新:正如Lekensteyn在评论中指出的那样,JS似乎也正确地转换了 0x
前缀的十六进制字符串.我不知道这一点,但实际上这似乎可行:
Update: As Lekensteyn points out in the comments, JS appears to properly cast 0x
-prefixed hexadecimal strings too. I didn't know this, but indeed this seems to work:
1 * "0xd0ff66"; // => 13696870
1 * "0xdsff66"; // => NaN
这是将十六进制字符串转换为数字的最简单方法-如果无法正确表示,则获取 NaN
.
which makes it the simplest way to cast a hex string to a number - and get NaN
if it can't be properly represented.
相同的行为适用于 Number()
,例如 Number("0xd0ff66")
返回一个整数,而 Number("0xdsff66")
返回 NaN
.
Same behavior applies to Number()
, e.g Number("0xd0ff66")
returns an integer, and Number("0xdsff66")
returns NaN
.
(/更新)
或者,您可以事先检查字符串,并在需要时返回 NaN
:
Alternatively, you can check the string beforehand and return NaN
if needed:
function hexToNumber(string) {
if( !/^(0x)?[0-9a-f]+$/i.test(string) ) return Number.NaN;
return parseInt(string, 16);
}
这篇关于为什么parseInt('dsff66',16)返回13?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!