Why is it recommended to provide optional radix parameter to parseInt()?
Asked Answered
P

3

5

I've always used the parseInt() function in Javascript without passing the radix parameter. As per the MDN documentation here, it's stated that not providing this parameter may result in unpredictable behaviour.

Always specify this parameter to eliminate reader confusion and to guarantee predictable behavior.

Could somebody clarify what does this unpredictable behavior mean with some code examples?

Procryptic answered 7/7, 2017 at 12:53 Comment(1)
"Different implementations produce different results when a radix is not specified, usually defaulting the value to 10."Ohara
A
6

In older versions of the language, parseInt() would cause the function to obey the normal JavaScript numeric constant syntax rules, including the recognition of a leading zero to denote octal constants, and a leading 0x to denote hex constants. Thus, if your code didn't explicitly insist on base 10, stray (possibly user-supplied) numbers with leading zeros would be interpreted as base-8 values, and leading 0x as hex.

The base-8 behavior is gone since ES5.1 (I think; might have been earlier), but the base 16 behavior is still there. (Probably a leading 0x is a little more rare as an accidental prefix than a simple leading 0.)

My experience looking at code here on Stack Overflow is that parseInt() is overused anyway. It's usually cleaner to convert strings (often, strings taken from DOM element .value properties) to numbers with the unary + operator:

var count = +document.getElementById("count").value;

That won't necessarily give you an integer, of course. However, what it will do is notice that the input string has trailing non-numeric garbage. The parseInt() function will simply stop parsing a string like "123abc" and give you 123 as the numeric value. The leading + will however give you a NaN.

If you need integers, you can always use Math.floor() or Math.round().

edit — a comment notes that ES2015 requires a leading 0o or 0O in "strict" mode for octal literals, but that doesn't apply to parseInt() which (in ES2015) only overrides the default radix for hex strings.

Ashleaashlee answered 7/7, 2017 at 12:55 Comment(6)
@Bathsheba I've never seen that mentioned, but of course I cannot say that nobody's whispered about it.Ashleaashlee
@Bathsheba In ECMAScript 6/ES2015, octals literals are in the format 0o like binary: 0b and hex: 0x.Ohara
@AndrewLi that's true in "strict" mode; otherwise (in order not to break the Internet) there's "legacy" mode that continues to recognize just a leading 0. But on the other hand I hadn't noted that about ES2015 (probably because I generally have no need for an octal literal).Ashleaashlee
+ is shortcut for Number(x). this does not function the same as parseInt(x) with undefined, null, and empty string.Shoat
@Shoat that is true. Also, parseInt("123hello world") will return 123, while the + operator would return NaN. Also of course parseInt() only returns integers, with no fractional part.Ashleaashlee
@Ashleaashlee yep. I meant parseFloat(), not parseInt(). With +x being a shortcut for Number(x), Number(x) is easier to search how +x works.Shoat
B
1

For some reason best known to themselves, the folk specifying the behaviour of this function set the radix to be a defaultable parameter but then decided to leave the default value up to the implementation! (Perhaps it would have been sensible to insist on a value of 10 but maybe that would have upset folk progamming in the 1970s who still consider octal literals to be useful.)

So for robust progamming, you need to supply the radix parameter yourself.

Beefwood answered 7/7, 2017 at 12:55 Comment(1)
at least typescript or eslint gives this warningShoat
R
0

Without supplying the radix, parseInt tries to determine what the right radix is by the value you pass in, for example if the value starts 0x then it determines you must be passing in hex values. Same applies with 0 (octal).

This becomes problematic when your input is zero-padded but no radix is supplied. Where the result will (possibly) not be as expected

console.log(parseInt(015))
Retarder answered 7/7, 2017 at 12:58 Comment(3)
You're clearly at the opposite end of the expertise spectrum to me, but does the function have to be implemented in this way?Beefwood
@Beefwood I have no idea. If I was writing it I probably would have defaulted it to 10 as its clearly what 99% of users expect. We're base-10 creatures after allRetarder
@Beefwood the current spec for the language still insists on recognizing a leading 0x or 0X as indicating a hex constant, but only when the radix is not explicitly passed as an argument.Ashleaashlee

© 2022 - 2024 — McMap. All rights reserved.