How do parseInt()
and Number()
behave differently when converting strings to numbers?
-
1I think a closer comparison would be `parseFloat` vs `Number` since all numbers are 64-bit floats. Related: https://stackoverflow.com/q/12227594/4294399 – General Grievance Mar 02 '22 at 14:28
11 Answers
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

- 596
- 5
- 12

- 807,428
- 183
- 922
- 838
-
1Interesting, does parseInt ignore any characters trailing the number? Because in my case I would prefer getting a NaN instead of the 20 when converting. – Mark Nov 03 '10 at 18:59
-
-
Okay, so I guess I will go with Number() but thanks a lot for clearing up this point and all these examples! :-) – Mark Nov 03 '10 at 19:10
-
@Mark, you're welcome, I'm glad to help, as I pointed at the end of the answer, you can use either `Number` or the unary plus operator, I like the operator for its shortness. @Gareth thanks for the comment :) – Christian C. Salvadó Nov 03 '10 at 19:16
-
2Thank you for this. This is the first time I've seen NaN. It may be helpful for some folks to know that NaN is tested with the function isNaN ( value ). Just using "if ( value == NaN )", for example, won't work. – WonderfulDay May 04 '13 at 09:54
-
There is an other feature: `var foo = { valueOf: function() { return 5 } }; Number(foo) === +foo === 5; parseInt(foo) !== parseInt(foo) // NaN` – andre487 Feb 18 '15 at 08:21
-
But value !== value && typeof value === number could be used to test if the value is NaN . NaN sucks – Davet Oct 30 '15 at 03:15
-
2`Number()` does deal with octals much like hex and binary: `Number('0o10') == 8` – Ruan Mendes Sep 21 '16 at 13:32
-
4
-
Note that the behavior of parsing a number with leading 0 in octal base was changed in **ES3**, not ES5. Compare section 15.1.2.2 of [ES2](http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%202nd%20edition,%20August%201998.pdf) and [ES3](http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf) for the details. – ebk Sep 24 '19 at 12:54
-
parseInt() also gives the option to specify the base via the optional radix argument: `parseInt("071", 10); // 71` vs `parseInt("071", 8); // 57`. Especially useful for numbers with leading zeros. – James D Oct 14 '20 at 03:34
-
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.

- 92,235
- 44
- 185
- 247

- 9,002
- 9
- 45
- 53
-
Ah I see Number( someString ) means I pass in a string to its constructor and get an object in return. – Mark Nov 03 '10 at 18:58
-
25`new Number()` is different to `Number()`. `typeof Number("123") => number` – Gareth Nov 03 '10 at 19:04
-
I think this is one of the most important point to take note from performance point of view, as objects consume much more memory and processing time. Nice discussion from you both, letronje and Gareth. – Davis Peixoto Nov 03 '10 at 19:11
-
9Also `new Number("1") != new Number("1")`. **NEVER USE `new Number`**. Never never never never. `Number("1")`, on the other hand, is perfectly reasonable. – Kragen Javier Sitaker Dec 28 '11 at 05:13
-
30@Kragen, it'd be much more beneficial to the community if you explained WHY you shouldn't use "new Number" -- instead of just typing "never" 5 times... – ken Sep 18 '12 at 14:22
-
3@ken Very old comment but for future visitors I imagine its because exactly the reason they mentioned to begin with. I parse two numbers `let x = new Number("2"); let y = new Number("2");` and then later on do an equality check for whatever reason, `if (x == y) { doSomething(); }` logically `doSomething` should be called. But it wont. Also if you were to parse only one number `let x = new Number("2");` then `x === 2` would be false. That is a clear reason why you should not use `new Number` – Tom C Oct 17 '17 at 14:11
-
2@TomC You're seeing the result of an edited comment (that's what the pencil icon following the comment denotes); previously there was zero explanation, just strong admonition. – ken Oct 18 '17 at 16:57
One minor difference is what they convert of undefined
or null
,
Number() Or Number(null) Or Number('') // returns 0
while
parseInt() Or parseInt(null) // returns NaN

- 140,023
- 84
- 646
- 689

- 15,331
- 6
- 50
- 88
-
1That’s because _ToNumber_ (**null**) is [specified](https://tc39.es/ecma262/#sec-tonumber) to return `0`. [`parseInt`, however expects _strings_](https://tc39.es/ecma262/#sec-parseint-string-radix), so `null` and `undefined` are coerced to the strings `"null"` or `"undefined"`, respectively, first, which don’t start with digits. `Number(undefined)` is `NaN`, not `0`, which is a [special step of the `Number(`…`)` algorithm](https://tc39.es/ecma262/#sec-number-constructor-number-value). At any rate, the question asked about “when converting strings to numbers”, not about these special cases. – Sebastian Simon Mar 16 '21 at 06:38
Summary:
parseInt()
:
- Takes a string as a first argument, the radix (An integer which is the base of a numeral system e.g. decimal 10 or binary 2) as a second argument
- The function returns a integer number, if the first character cannot be converted to a number
NaN
will be returned. - If the
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. - If the radix is
undefined
or 0, JS will assume the following:- If the input string begins with "0x" or "0X", the radix is 16 (hexadecimal), the remainder of the string is parsed into a number.
- If the input value begins with a 0 the radix can be either 8 (octal) or 10 (decimal). Which radix is chosen is depending on JS engine implementation.
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. - If the input value begins with any number, the radix will be 10
Number()
:
- The
Number()
constructor can convert any argument input into a number. If theNumber()
constructor cannot convert the input into a number,NaN
will be returned. - The
Number()
constructor can also handle hexadecimal number, they have to start with0x
.
Example:
console.log(parseInt('0xF', 16)); // 15
// z is no number, it will only evaluate 0xF, therefore 15 is logged
console.log(parseInt('0xFz123', 16));
// because the radix is 10, A is considered a letter not a number (like in Hexadecimal)
// Therefore, A will be cut off the string and 10 is logged
console.log(parseInt('10A', 10)); // 10
// first character isnot a number, therefore parseInt will return NaN
console.log(parseInt('a1213', 10));
console.log('\n');
// start with 0X, therefore Number will interpret it as a hexadecimal value
console.log(Number('0x11'));
// Cannot be converted to a number, NaN will be returned, notice that
// the number constructor will not cut off a non number part like parseInt does
console.log(Number('123A'));
// scientific notation is allowed
console.log(Number('152e-1')); // 15.21

- 33,665
- 16
- 190
- 155
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.

- 1,736
- 20
- 29
-
1The speed of the various approaches appears to change with browser revisions over time. The linked test also has changed, and the latest version as of this comment is here - http://jsperf.com/number-vs-parseint-vs-plus/39 - fortunately the site contains previous versions of the test as well – phoenixdown Aug 04 '14 at 16:01
-
@bobo, sure. Out of curiosity checked with chrome - `Number` and `parseInt` still slower 99% than the rest. Plus to me they are less attractive visually too :-) – Saulius Aug 05 '14 at 12:19
-
-
33Always prefer code clarity over "useless" optimizations. For most use cases `parseInt` or `Number` are more preferable. If you are programming a N64 emulator with millions of conversions per seconds, you might consider those tricks. – ngryman May 20 '15 at 12:10
-
1Question is about behavior, discussion of performance is off-topic. – pneumatics Jun 09 '17 at 22:37
-
2Note that this can't be used for large integers -- specifically integers that don't fit in a signed 32-bit integer -- because in JavaScript, bitwise operators treat their operands as a sequence of 32 bits, rather than as decimal, hexadecimal, or octal numbers. Hence `(2**31).toString() >> 0` will overflow to `-2147483648`. You can use `>>>` instead of `>>` to have JavaScript treat the operand as an *unsigned* 32-bit integer, but then any numbers larger than `2**32 - 1` will also overflow. – hasc May 16 '19 at 11:12
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)

- 43,869
- 19
- 177
- 214
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

- 7,009
- 3
- 31
- 45

- 339
- 2
- 7
-
parseInt() only parses a number out of a string that contains letters if the number part comes first – nCardot Aug 30 '21 at 01:35
-
"it parse decimal number" parseInt() parses the integer, leaves the decimal part, for example parseInt('1.1') returns 1 – nCardot Aug 30 '21 at 01:39
I always use parseInt, but beware of leading zeroes that will force it into octal mode.

- 112,730
- 33
- 157
- 176
-
39I think it's always a good idea to supply a radix to `parseInt(value, radix)` that way you don't have accidental *octal mode* conversions, etc. – awesomo Nov 03 '10 at 18:59
-
Leading zeroes *will* force it into octal mode in ECMAScript 3. ECMAScript 5 will parse it to `0`, even in non-strict mode. But this has been fixed and now leading zeroes are just ignored, so `parseInt("070")` would become `70`. – Piotrek Hryciuk Sep 20 '16 at 10:28
-
3You should be using a linter as well that will warn you to provide a radix value into `parseInt()`. – Justin Oct 14 '16 at 00:42
It's 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 completely 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.floor
, 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.

- 41,009
- 21
- 145
- 105

- 2,552
- 1
- 24
- 29
-
2Wow, this is really useful! Bugs from parseInt could be hard to find indeed. Your answer deserves many more upvotes! – James D Oct 14 '20 at 03:40
-
8That’s because `parseInt` _expects_ strings. Any non-string is first coerced to a string. Since `4000000000000000000000` is not a safe integer, its string representation is `4e+21`, and `parseInt`’s left-to-right parsing stops before the non-digit `e`. Using `parseInt` with numeric arguments or to round a number is a misuse. – Sebastian Simon Mar 16 '21 at 06:56
-
1The MDN reference for `parseInt` should be checked by anyone who thinks this answer deserves an upvote. The `parseInt` function does not accept a number. It's for parsing strings. If you use JavaScript, it will coerce the number into a string before the function receives the argument (which is what causes the rounding) and if you use TypeScript it won't even compile because it's wrong. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt – FlippingBinary Oct 11 '22 at 14:50
parseInt converts to a integer number, that is, it strips decimals. Number does not convert to integer.

- 35
- 4
-
Just for fun it seems that e.g. `Number("10.0")` does return `10`, but `Number("10.1")` returns `10.1`. So, that's a fun special case to watch out for. – Charles Wood Aug 04 '21 at 16:01
Another way to get the result is to use the ~ operator
For most circumstances
~~someThing === parseInt(something)
but ~~ will return zero for strings that parseInt will accept with trailing other characters or with the number base spec (eg hex) and will also return zero when parseInt returns NaN. Another difference is that ~~ if given a bigint returns a bigint to which you can add another bigint whereas parseInt returns an ordinary floating point number (yes really - it gives exactly the same value as parseFloat) if the bigint is large
However for most circumstances ~~ is 30% faster than parseInt. It is only slower by 10% when something is a floating point represented as a string.
So if the more restricted scope of ~~ fits your need then save the computer time and give yourself less to type

- 1
- 2