4eaixa
Last Updated: March 02, 2016
·
7.446K
· rstacruz
F8ec7f90daf8b1defb8e318d663c0f17

parseInt() can be dangerous

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

Prevent this behavior using:

parseInt("023", 10)    //=> 23
Say Thanks
Respond

26 Responses
Add your response

1586
Ebc47ee771e1695743e6b79c0821f37f

Also, beware of optional arguments:

["1","2","3"].map(parseInt)
// => [1, NaN, NaN]
over 1 year ago ·
1594
11904d2d1af36d532f9d78d9d59f6819

Don't use parseInt. Use +:

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

+"42"  //=> 42
+"023" //=> 23
over 1 year ago ·
1597
Profile 2015 2

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

over 1 year ago ·
1614

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

over 1 year ago ·
1667
11904d2d1af36d532f9d78d9d59f6819

@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 ·
1669
F8ec7f90daf8b1defb8e318d663c0f17

@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 ·
1670

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 ·
2037
5f93e10abd0998d0c7e6d3ae32da7b83

Awesome tip! :D

over 1 year ago ·
2039
A4d43c27e73772ba1afcdc5f9b33276a

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 ·
2044
37b092a324da25d53fd63d780692b174
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 ·
2047
81829def637962204635704c091036ea
"023" >> 0

is actually the faster way to perform a integer parsing.

over 1 year ago ·
2054
529a291a6eb6205d850ac47d2c38b24c

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 ·
2059
Peak

@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 ·
2083
11904d2d1af36d532f9d78d9d59f6819

@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 ·
2475

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

over 1 year ago ·
4188
Bea0a2664d192fa5061ba744b8adcaa3

@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 ·
4246

Good discussion, I learned a lot.

over 1 year ago ·
4361
Pppp

Awesome discussion!

over 1 year ago ·
4363
7831f9c652845c34091da263b689cc25

@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 ·
4368

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 ·
5105
Fbef5ed82558aec302bddbac3340ec16

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 ·
8049
1505228 10153667646265066 1410509922 n

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

over 1 year ago ·
8837
06237052745686cba3fcb34d056d3cad

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

over 1 year ago ·
11286
Qweqwe

why does it happen in ruby ?

over 1 year ago ·
12901
My face

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

over 1 year ago ·
17374
704044

Arbitrary input can be dangerous.

over 1 year ago ·