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:
constmyNumber='1';if (parseInt(myNumber,10)===1){// do something
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:
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.
functionrunBench(cb){conststart=newDate();for (leti=0;i<100000000;i++){cb();constend=newDate();console.log(`It took ${end-start} ms`);constprocess1=()=>Number('3.2');constprocess2=()=>parseInt('3.2',10);runBench(process1);// It took 140 msrunBench(process2);// It took 4546 msEnter fullscreen modeExit fullscreen mode
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:
functionrunBench(cb){conststart=newDate();for (leti=0;i<100000000;i++){cb();constend=newDate();console.log(`It took ${end-start} ms`);constprocess1=()=>Number('1');constprocess2=()=>parseInt('1',10);constprocess3=()=>parseFloat('1');constprocess4=()=>+'1';runBench(process1);// It took 70 msrunBench(process2);// It took 4552 msrunBench(process3);// It took 5082 msrunBench(process4);// It took 412 msEnter fullscreen modeExit fullscreen mode
Unless you're doing this in the order of hundreds of thousands, performance is neglible (I've rarely come across use cases like this in prod systems)
While it's nice to think about these things and how you write code, I will always push back on people looking to enforce issues or 'standards' like this in PRs because they're rather subjective POV on style or rely on contrived performance benefits. If this seems like a harsh response, I apologise, but I'm wary of articles with titles like you 'should' be doing this, or you 'must not' do this, etc.
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().
Two things here -
parseInt doesn't do any rounding, only truncation. The equivalent Math function would be Math.trunc:
Ok, but you did sum up the issue yourself in the examples. ParseInt will order to an integer whereas Number will get the proper numeric representation. Which means the outcome ma not be an int, which is what ParseInt guarantees .
The use of ParseInt can be replaced with Number if and only if it's accompanied by Math.round. This is not an edge case or an odd use case, it's the missing piece to have the intended outcome: an integer. The odd case is requiring the use of radix.
the performance comparison is moot because the functions discussed don't do the same thing
the correct way to formulate the use case for Number is: you should use Number when you want to extract the correct numeric value in full from a string AND you don't care about the resulting type.
use case for ParseInt: you want to ensure conversion to an integer OR the partial extraction of an integer (similar for float)
The most common case for ParseInt is to get the correct number from a string with the even expectation of getting a float .... from a function that has int in the name? I hardly believe that.
I have never seen in 20 years a case of parseInt used with the expectation of getting anything except an int.
If you are referring to checking if the string contains function call by searching for "()", no it won't work because there are way too many scenarios. Consider a case when there are spaces in between the parenthesis, e.g. foo( ) and your code will then allow it to run. It will be better if you only allow whitelisted characters. However, it will still take unnecessary effort and still potentially cause the program to hang (if you are going to search/parse the whole string which can be very long). So just use the built-in functions that work just fine and don't reinvent the wheel, which is something stupid.
eval() should never be used on user input.
Often parsing strings to Int is done for security reasons. Using eval() would just lead you to code injection and XSS problems.
Don't do it!
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.
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.