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)?
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.)
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
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.
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.
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
'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.)
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.
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
which'll throw a SyntaxError
because 0xdsff66
isn't a valid hex literal.
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
which makes it the simplest way to cast a hex string to a number - and get NaN
if it can't be properly represented.
Same behavior applies to Number()
, e.g Number("0xd0ff66")
returns an integer, and Number("0xdsff66")
returns NaN
.
(/update)
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("2foo",10)
you get2
. This is as expected. It parses up to the first non-numeric character – RainieIf parseInt encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters and returns the integer value parsed up to that point.
source: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… – RainieNaN
is if it can't be parsed in the radix specified. For exampleparseInt('9',8);
isNaN
. – Rainiewhy did they decide it should behave this way.
since we can't read minds, that makes this question opinion based. – Rainiestrtol()
behaves this way". – AuscultationNumber
instead. – Marijo