How do I work around JavaScript's parseInt octal behavior?
Try executing the following in JavaScript:
parseInt('01'); //equals 1
parseInt('02'); //equals 2
parseInt('03'); //equals 3
parseInt('04'); //equals 4
parseInt('05'); //equals 5
parseInt('06'); //equals 6
parseInt('07'); //equals 7
parseInt('08'); //equals 0 !!
parseInt('09'); //equals 0 !!
I just learned the hard way that JavaScript thinks the leading zero indicates an octal integer, and since there is no "8"
or "9"
in base-8, the function returns zero. Like it or not, this is by design.
What are the workarounds?
Note: For sake of completeness, I'm about to post a solution, but it's a solution that I hate, so please post other/better answers.
Update:
The 5th Edition of the JavaScript standard (ECMA-262) introduces a breaking change that eliminates this behavior. Mozilla has a good write-up.
This is a common Javascript gotcha with a simple solution:
Just specify the base, or 'radix', like so:
parseInt('08',10); // 8
You could also use Number:
Number('08'); // 8
If you know your value will be in the signed 32 bit integer range, then ~~x
will do the correct thing in all scenarios.
~~"08" === 8
~~"foobar" === 0
~~(1.99) === 1
~~(-1.99) === -1
If you look up binary not (~
), the spec requires a "ToInt32" conversion for the argument which does the obvious conversion to an Int32 and is specified to coerce NaN
values to zero.
Yes, this is incredibly hackish but is so convenient...