parseInt() can be dangerous
parseInt("23") //=> 23
parseInt("023") //=> 19 (octal)
Prevent this behavior using:
parseInt("023", 10) //=> 23
Written by Rico Sta. Cruz
Related protips
25 Responses
Don't use parseInt. Use +:
parseInt("42") //=> 42
parseInt("023") //=> 19
+"42" //=> 42
+"023" //=> 23
Here is some benchmarks of String to Number conversions using JavaScript: http://phrogz.net/JS/string_to_number.html
@passcod Avoid type coercion at all costs, it can backfire at you pretty hard
@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.
@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)
.
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.
Awesome tip! :D
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
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.
"023" >> 0
is actually the faster way to perform a integer parsing.
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
).
@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)
@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().
@pickachu parseInt("42px") //=> 42 <- Advantage of using - Agreed totally useful !!
@pickachu Avoid using ~~, won't correctly parse exponential, for example:
+"4.5e+10" = 45000000000
parseInt("4.5e+10") = 45000000000
~~"4.5e+10" = 2050327040
Good discussion, I learned a lot.
Awesome discussion!
@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.
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
Just as @passcod said browser inconsistencies will kill you using parseInt without the radix parameter.
Eg.
// Chrome
parseInt("023"); // 23
// Firefox
parseInt("023"); // 19
Why avoid using parseInt instead ? https://coderwall.com/p/cbabhg
@poupugnac: thanks for great post. please avoid using parseInt :)
why does it happen in ruby ?
realise i have always been using it wrong...great tip
Arbitrary input can be dangerous.