Last Updated: May 27, 2020
·
17.56K
· rstacruz

parseInt() can be dangerous

parseInt("23")          //=> 23
parseInt("023")         //=> 19 (octal)

Prevent this behavior using:

parseInt("023", 10)    //=> 23

25 Responses
Add your response

Don't use parseInt. Use +:

parseInt("42")   //=> 42
parseInt("023") //=> 19

+"42"  //=> 42
+"023" //=> 23
over 1 year ago ·

Here is some benchmarks of String to Number conversions using JavaScript: http://phrogz.net/JS/string_to_number.html

over 1 year ago ·

@passcod Avoid type coercion at all costs, it can backfire at you pretty hard

over 1 year ago ·

@brokenseal Err what? The only two outputs +anything can give me are a number or NaN. Statements like “Avoid X at all costs” are never useful: instead, explain why it should be avoided, and how it can backfire.

over 1 year ago ·

@brokenseal There are legitimate uses for type coercing strings to integers. For instance, HTML attributes from the DOM are always strings, if you need it as a number, you'll still need to cast it.

@passcod Thanks for the tip on +"023"! One case this won't cover though is when you're working on a string with numbers and letters, with one typical case being parseInt("32px", 10).

over 1 year ago ·

Correct, the fact that it doesn't always return what you want (like in the case you @rstacruz, just described) makes me dislike that approach @passcod.

Even more, I come from a Python background and I always try to avoid anything that it is not clear to read. And that is not clear at all.
I mean, you can turn anything into a boolean adding !! in front of it, but do you really want to use that approach?

I'm all for type casting, not so for type coercion.

over 1 year ago ·

Awesome tip! :D

over 1 year ago ·

Also if want 0 instead of NaN use ~~:

~~"42"        //=> 42
~~"042"       //=> 42
~~"the 42"     //=> 0    <- Advantage of using ~~
~~"42px"      //=> 0

+"42"         //=> 42
+"042"        //=> 42
+"the 42"      //=> NaN
+"42px"       //=> NaN

parseInt("42")         //=> 42
parseInt("042")        //=> 34 (Firefox) || 42 (Chrome)
parseInt("09")         //=> NaN (Firefox) || 9 (Chrome)
parseInt("the 42")      //=> NaN
parseInt("42px")       //=> 42  <- Advantage of using parseInt
over 1 year ago ·
parseInt("42", 10); 

is correct, if you use JsLint it will point out the omission of the second param of parseInt.

Just yet another reason to parseInt.

over 1 year ago ·
"023" >> 0

is actually the faster way to perform a integer parsing.

over 1 year ago ·

You should do a better job of explaining why that happens and why setting the radix to 10 solves that problem.

Also, mention hexadecimal numbers (which start with 0x).

over 1 year ago ·

@passcod
- +"23 people" == NaN
- parseInt("23 people", 10) == 23

I will stick with parseInt. (unless I want it to fail when it contains non numeric chars)

over 1 year ago ·

@jisaacks I never said otherwise. In fact, my position on this is that +"" is safer, and that you should consider doing some proper parsing and checking for anything more complicated (what if someone passes nonsense that happens to start with a number? Suddenly: the unexpected happens).

Also see @pickachu's comment for both: a solution that always returns a actual number (0 instead of NaN), and more importantly, browser inconsistency using parseInt().

over 1 year ago ·

@pickachu parseInt("42px") //=> 42 <- Advantage of using - Agreed totally useful !!

over 1 year ago ·

@pickachu Avoid using ~~, won't correctly parse exponential, for example:

 +"4.5e+10" = 45000000000
parseInt("4.5e+10") = 45000000000
 ~~"4.5e+10" = 2050327040
over 1 year ago ·

Good discussion, I learned a lot.

over 1 year ago ·

Awesome discussion!

over 1 year ago ·

@passcod, @mlb If you work with other your code should be easy to read and understand. Using + or >> to convert something into an integer is totally verbose. The right way would be to use parseInt always with the second radix parameter and lint your code.

over 1 year ago ·

Prevent this behavior using:

Prevent what? Hey, guys, are you fucking kidding me? RTFM. The second argument for parseInt is numeral system. When you ignore this argument, parseInt try to choose the most proper numeral system. So, when you call parseInt("023") (without second argument) you will get parsed integer in octal numeral system

parseInt("023", 8); // 19
parseInt("023", 10); // 23
over 1 year ago ·

Just as @passcod said browser inconsistencies will kill you using parseInt without the radix parameter.

Eg.

// Chrome
parseInt("023");  // 23

// Firefox
parseInt("023");  // 19
over 1 year ago ·

Why avoid using parseInt instead ? https://coderwall.com/p/cbabhg

over 1 year ago ·

@poupugnac: thanks for great post. please avoid using parseInt :)

over 1 year ago ·

why does it happen in ruby ?

over 1 year ago ·

realise i have always been using it wrong...great tip

over 1 year ago ·

Arbitrary input can be dangerous.

over 1 year ago ·