DEV Community

Alessio Michelini
Alessio Michelini

Posted on

You should stop using `parseInt()`

This is something I see all the times, you have some code where at some point you have a variable that contains a number, maybe it comes from a form, or from the results of some API calls, or whatever, and you want convert it into an integer.

Something like this for example:

const myNumber = '1';

if (parseInt(myNumber, 10) === 1) {
  // do something
}
Enter fullscreen mode Exit fullscreen mode

While the code above works, it’s an extremely inefficient way to parse it.
What you should use instead is the Number() function, and convert the code above to this:

const myNumber = '1';

if (Number(myNumber) === 1) {
  // do something
}
Enter fullscreen mode Exit fullscreen mode

From the changes above you gain two things:

  • a more readable code
  • a much more performing way to transform a string to an integer

But what’s the difference between Number and parseInt?

The Number(string) function evaluate the full string and converts it to a string, and if the string is not a number it will just return NaN.
While parseInt(string, [radix]) will try to find the first number in the string passed, and convert it to the radix passed, which is 10 by default, and it will return NaN only if it doesn’t find any number.

This means that if you pass a string like 5e2 , it parseInt will stop when it sees the e and it will just return 5, while Number will evaluate the whole string and return the correct value 500.

Here you can see some cases compared between the two functions:

console.log(Number('a')); // NaN
console.log(Number('1')); // 1
console.log(Number('5e2')); // 500
console.log(Number('16px')); // NaN
console.log(Number('3.2')); // 3.2

console.log(parseInt('a')); // NaN
console.log(parseInt('1')); // 1
console.log(parseInt('5e2')); // 5
console.log(parseInt('16px')); // 16
console.log(parseInt('3.2')); // 3
Enter fullscreen mode Exit fullscreen mode

It’s also a matter of execution time

Maybe you are still undecided, and you think that “I just need to convert a simple number to an integer, why I should use Number instead?”.
Well, because of performances.

For example, let’s do a simple function, that loops for 100m times, and that accepts a callback, and we call it twice using Number in the first case and parseInt in the second.

function runBench(cb) {
  const start = new Date();
  for (let i = 0; i < 100000000; i++) {
    cb();
  }
  const end = new Date();
  console.log(`It took ${end - start} ms`);
}

const process1 = () => Number('3.2');
const process2 = () => parseInt('3.2', 10);

runBench(process1); // It took 140 ms
runBench(process2); // It took 4546 ms
Enter fullscreen mode Exit fullscreen mode

Sure, you are not going to run a loop of 100 millions, but it’s to make evident the performance difference between the two functions, and also when you use parseInt in multiple places on the same function, things might just sum up at the end.

So should I just avoid parseInt all the times?

No, not always, there are of course use cases where it’s beneficial to use it, for example if you want to extrapolate an integer out of a floating number, which is a good 50% faster than Math.round().
For example ifyou want to convert a string with pixels on it to just a number, like 32px to 32, then you should use parseInt, but most of the times you better stick with Number instead.
Or even if you want to convert a number from a decimal system to something else.

Conclusions

Unless some specific cases, where parseInt returns what you need and Number doesn’t, for 99% of the cases you should better start to use the latter one.

Update: a few more benchmarks

Just to give a broader picture as there are more ways to convert a string to a number, I also added tests using parseFloat and the Unary operator, here there results:

function runBench(cb) {
  const start = new Date();
  for (let i = 0; i < 100000000; i++) {
    cb();
  }
  const end = new Date();
  console.log(`It took ${end - start} ms`);
}

const process1 = () => Number('1');
const process2 = () => parseInt('1', 10);
const process3 = () => parseFloat('1');
const process4 = () => +'1';

runBench(process1); // It took 70 ms
runBench(process2); // It took 4552 ms
runBench(process3); // It took 5082 ms
runBench(process4); // It took 412 ms
Enter fullscreen mode Exit fullscreen mode

As you can see above, using the Number() is still the fastest way to do the conversion.

Latest comments (48)

Collapse
 
augustoapg profile image
Augusto Peres

Very useful and well written post! Thank you!

Collapse
 
orora profile image
n • Edited

I can't confirm this with my smartphone now with Android, Qualcomm's Snapdragon 665 and schedutil governor.

parseInt('3.2') and parseInt('3.2', 10) and Math.trunc(Number('3.2')) are consistently within 0,5% of each other in terms of time with stable Firefox 121.0 (20231214155439).

Only Math.trunc('3.2') is always slower by 90%-98% with Chromium 120.0.6099.144 (Official Build) (64-bit), 122.0.6215.0 (Official Build) canary (64-bit) and Firefox 121.0 (20231214155439), 123.0a1 (20231230094435).

I also noticed that Math.trunc(Number('3.2')) is 3%-5% slower with Chromium 122.0.6215.0 (Official Build) canary (64-bit). I don't know why.

Use this or something better jsbench.me/bflqt42rdh/1

Collapse
 
lczw profile image
lczw

Today is finally the day I could use the information from this article. I came across a case where I had to cast a string to number. Worked flawlessly and Number() provides a nice interface to work with 👍

Collapse
 
uapuniverse profile image
Mike Becker

This post is already a bit old, but the topic is still relevant. And the advice in this post is very much incomplete. Watch this:

Number('0x4') // 4
Number('-0x4') // NaN
Number(null) // 0
Number(undefined) // NaN
Number('') // 0
Number('  ') // 0
Enter fullscreen mode Exit fullscreen mode

The Number constructor is highly unreliable when it comes to interpreting user input from a form.

Unfortunately all oneliners in Javascript are broken. Nothing works. Neither parseInt nor Number nor any other implicit or explicit attempt to convert the value.

You always have to use a combination of different functions plus some manual checking for special cases like empty string, null, or undefined... otherwise you will always experience inconsistent behavior.

Collapse
 
billylabool profile image
Billy-La-Bool

Thanks a lot! this helped me fix a bug I couldn't figure out where it came from

Collapse
 
ky1e_s profile image
Kyle Stephens

If the title/content of the article were about warning against using parseInt in canvas art or game development then that's a different conversation.

Collapse
 
athenaozanich profile image
Athena Ozanich

Valid, and in the case of any kind of game development this could have a massive impact on the performance of said game.

Collapse
 
receter profile image
Andreas Riedmüller

Keep in mind that both return different results when when passing nullish or boolean values:

parseInt(); // NaN
parseInt(null); // NaN
parseInt(''); // NaN
parseInt(true); // NaN

Number(); // 0
Number(null); // 0
Number(''); // 0
Number(true); // 1
Enter fullscreen mode Exit fullscreen mode
Collapse
 
maorkavod profile image
maorkavod • Edited

You can also use this :

~~'234';

or even :

'234' | 0;

Collapse
 
domagojvidovic profile image
Domagoj Vidovic

This is cool, thanks for sharing.

Btw. for measuring the performance use performance.now() instead of Date, it's more precise.

Collapse
 
darkmavis1980 profile image
Alessio Michelini

Thanks, forgot about that one!

Collapse
 
avngarde profile image
Kamil Paczkowski

Cool, i didnt knew about it!

Collapse
 
talorlanczyk profile image
TalOrlanczyk

Just small update instead of Number(something)
you can write +something and it will convert it to number

Collapse
 
darkmavis1980 profile image
Alessio Michelini

I know, it's on the article as well, it's called unary operator ;-)

Collapse
 
jonosellier profile image
jonosellier

FYI, Math.round() will round the number, not chop off the decimal. Use floor or better yet |0 to drop the decimal

Collapse
 
mhoumann87 profile image
Michael Houmann

Why not save some time and use the simple '+' before the string you want to parse? Same result as Number, but quite faster to write

Collapse
 
kigiri profile image
Clément

One thing to note that caugth me by surprise is that Number will parse any falsy value as 0, so undefined, null, false all parse fine and return 0, can be unexpected.