JavaScript has one number type for integers and fractions alike: a 64-bit IEEE 754 double-precision float. It holds integers exactly up to 2^53 - 1, fractions only approximately, and the special values Infinity, -Infinity, NaN and -0. For larger integers there is a second numeric primitive, bigint (BigInt). The operators + - * / % ** work on both types; the Math object (Math) supplies the rest.
Strings from forms, URLs and JSON must be converted before you calculate. The converters disagree on edge cases: Number() and unary + require the whole string to be numeric (after trimming whitespace), while parseInt() and parseFloat() read digits until the first invalid character.
| Input | Number(s), +s | parseInt(s) | parseFloat(s) |
|---|---|---|---|
| "42" | 42 | 42 | 42 |
| " 42px" | NaN | 42 | 42 |
| "3.9kg" | NaN | 3 | 3.9 |
| "" | 0 | NaN | NaN |
| "0x1F" | 31 | 31 | 0 |
| null / undefined / true | 0 / NaN / 1 | NaN | NaN |
Validate with Number() plus Number.isNaN(), but check for "" first: an empty form field silently becomes 0. Like new Boolean(), the wrapper new Number(5) (an "object") has no place in modern code.