How do parseInt()
and Number()
behave differently when converting strings to numbers?
This question is related to
javascript
performance
Well, they are semantically different, the Number
constructor called as a function performs type conversion and parseInt
performs parsing, e.g.:
// parsing:
parseInt("20px"); // 20
parseInt("10100", 2); // 20
parseInt("2e1"); // 2
// type conversion
Number("20px"); // NaN
Number("2e1"); // 20, exponential notation
Also parseInt
will ignore trailing characters that don't correspond with any digit of the currently used base.
The Number
constructor doesn't detect implicit octals, but can detect the explicit octal notation:
Number("010"); // 10
Number("0o10") // 8, explicit octal
parseInt("010"); // 8, implicit octal
parseInt("010", 10); // 10, decimal radix used
And it can handle numbers in hexadecimal notation, just like parseInt
:
Number("0xF"); // 15
parseInt("0xF"); //15
In addition, a widely used construct to perform Numeric type conversion, is the Unary +
Operator (p. 72), it is equivalent to using the Number
constructor as a function:
+"2e1"; // 20
+"0xF"; // 15
+"010"; // 10
If you are looking for performance then probably best results you'll get with bitwise right shift "10">>0
. Also multiply ("10" * 1
) or not not (~~"10"
). All of them are much faster of Number
and parseInt
.
They even have "feature" returning 0 for not number argument.
Here are Performance tests.
parseInt()
-> Parses a number to specified redix.
Number()
-> Converts the specified value to its numeric equivalent or NaN if it fails to do so.
Hence for converting some non-numeric value to number we should always use Number() function.
eg.
Number("")//0
parseInt("")//NaN
Number("123")//123
parseInt("123")//123
Number("123ac") //NaN,as it is a non numeric string
parsInt("123ac") //123,it parse decimal number outof string
Number(true)//1
parseInt(true) //NaN
There are various corner case to parseInt()
functions as it does redix conversion, hence we should avoid using parseInt() function for coersion purposes.
Now, to check weather the provided value is Numeric or not,we should use nativeisNaN()
function
I found two links of performance compare among several ways of converting string
to int
.
parseInt(str,10)
parseFloat(str)
str << 0
+str
str*1
str-0
Number(str)
typeof parseInt("123") => number
typeof Number("123") => number
typeof new Number("123") => object (Number primitive wrapper object)
first two will give you better performance as it returns a primitive instead of an object.
Its a good idea to stay away from parseInt and use Number and Math.round unless you need hex or octal. Both can use strings. Why stay away from it?
parseInt(0.001, 10)
0
parseInt(-0.0000000001, 10)
-1
parseInt(0.0000000001, 10)
1
parseInt(4000000000000000000000, 10)
4
It completly butchers really large or really small numbers. Oddly enough it works normally if these inputs are a string.
parseInt("-0.0000000001", 10)
0
parseInt("0.0000000001", 10)
0
parseInt("4000000000000000000000", 10)
4e+21
Instead of risking hard to find bugs with this and the other gotchas people mentioned, I would just avoid parseInt unless you need to parse something other than base 10. Number, Math.round, Math.foor, and .toFixed(0) can all do the same things parseInt can be used for without having these types of bugs.
If you really want or need to use parseInt for some of it's other qualities, never use it to convert floats to ints.
One minor difference is what they convert of undefined
or null
,
Number() Or Number(null) // returns 0
while
parseInt() Or parseInt(null) // returns NaN
Because none mentioned, when using Number
and parseInt
with numeric separator, they also behave differently:
const num1 = 5_0; // 50
const num2 = Number(5_0); // 50
const num3 = Number("5_0"); // NaN
const num4 = parseInt(5_0); // 50
const num5 = parseInt("5_0"); // 5
parseInt converts to a integer number, that is, it strips decimals. Number does not convert to integer.
I always use parseInt, but beware of leading zeroes that will force it into octal mode.
parseInt()
:
NaN
will be returned.parseInt()
function encounters a non numerical value, it will cut off the rest of input string and only parse the part until the non numerical value.undefined
or 0, JS will assume the following:
ES5
specifies that 10 should be used then. However, this is not supported by all browsers, therefore always specify radix if your numbers can begin with a 0.Number()
:
Number()
constructor can convert any argument input into a number. If the Number()
constructor cannot convert the input into a number, NaN
will be returned.Number()
constructor can also handle hexadecimal number, they have to start with 0x
.console.log(parseInt('0xF', 16)); // 15_x000D_
_x000D_
// z is no number, it will only evaluate 0xF, therefore 15 is logged_x000D_
console.log(parseInt('0xFz123', 16));_x000D_
_x000D_
// because the radix is 10, A is considered a letter not a number (like in Hexadecimal)_x000D_
// Therefore, A will be cut off the string and 10 is logged_x000D_
console.log(parseInt('10A', 10)); // 10_x000D_
_x000D_
// first character isnot a number, therefore parseInt will return NaN_x000D_
console.log(parseInt('a1213', 10));_x000D_
_x000D_
_x000D_
console.log('\n');_x000D_
_x000D_
_x000D_
// start with 0X, therefore Number will interpret it as a hexadecimal value_x000D_
console.log(Number('0x11'));_x000D_
_x000D_
// Cannot be converted to a number, NaN will be returned, notice that_x000D_
// the number constructor will not cut off a non number part like parseInt does_x000D_
console.log(Number('123A'));_x000D_
_x000D_
// scientific notation is allowed_x000D_
console.log(Number('152e-1')); // 15.21
_x000D_
Source: Stackoverflow.com