为什么parseInt('dsff66',16)返回13? [英] Why does parseInt('dsff66',16) return 13?

查看:41
本文介绍了为什么parseInt('dsff66',16)返回13?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,我偶然发现了一个奇怪的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) ?

推荐答案

为什么有人会希望这个函数具有这样的行为(即使不是传递的字符串的精确表示,也要返回整数)?

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)明确地将字符串广播"为数字.虽然它也仅支持10进制,的确会为无效字符串返回 NaN .

You can also explicitly "cast" a string to number with Number(someString). While it too only supports base 10, 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.

现在,您可能会问为什么没有一个严格的 casting 函数来处理非10进制数字,并会随意抱怨,但是...嘿,那里事实并非如此.JS的设计师只是认为 parseInt 就足够了,因为在0x63%的情况下,您处理的是基数10.

Now, you might ask why there isn't a strict casting function that handles non-base-10 numbers, and would complain like you want, but... hey, there just isn't. JS's designers just decided that parseInt would suffice, because, again, 0x63 percent of the time, you're dealing with base 10.

最接近广播"的地方可能是骇人听闻的,例如:

Closest you can get to "casting" is probably something horribly hacky like:

var hexString = "dsff66";
var number = eval("0x" + hexString); // attempt to interpret as a hexadecimal literal

这将引发 SyntaxError ,因为 0xdsff66 不是有效的十六进制文字.

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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆