Number methods handle two everyday jobs: formatting numbers for display, and converting other values (usually strings from forms) into numbers you can do math with. They come in three groups, and knowing which group a method belongs to tells you how to call it.
| Group | Called on | Examples |
|---|---|---|
| Basic methods | any number: x.toFixed(2) | toString, toFixed, toPrecision, toExponential, valueOf |
| Global functions | on their own: Number(x) | Number, parseInt, parseFloat |
| Static methods | Number itself: Number.isInteger(x) | isInteger, isNaN, isFinite, isSafeInteger, parseInt, parseFloat |
Basic methods work on literals, variables, or expressions: x.toString(), (123).toString(), (100 + 23).toString(). A literal needs parentheses around it, because in 123.toString() the dot looks like a decimal point.
toString() returns the number as a string. Give it a radix (base) from 2 to 36 to convert between number systems:
let n = 255;
console.log(n.toString()); // "255"
console.log(n.toString(2)); // binary
console.log(n.toString(16)); // hex
toFixed(n) rounds to exactly n decimal places, padding with zeros if needed. It is the go-to method for money:
let x = 9.656;
console.log(x.toFixed(0));
console.log(x.toFixed(2));
console.log(x.toFixed(4));
console.log((5).toFixed(2));
price.toFixed(2) + 1 gives "9.661", not 10.66, because the result of toFixed is text and + joins it. Do all your math first, and call toFixed last, only for display.
toPrecision(n) keeps n significant digits in total, not n decimal places. With no value, it leaves the number as is:
let x = 9.656;
console.log(x.toPrecision());
console.log(x.toPrecision(2));
console.log(x.toPrecision(4));
console.log(x.toPrecision(6));
toExponential(n) returns a string in scientific notation, with n digits after the decimal point:
let x = 9.656;
console.log(x.toExponential(2));
console.log(x.toExponential(4));
console.log(x.toExponential()); // no value: no rounding
e+0 means "times 10 to the power of 0", which is times 1. On a big number like 123456 it would be 1.23e+5.
For numbers people will read, toLocaleString() adds thousands separators and currency symbols the way a given country expects:
let big = 1234567.891;
console.log(big.toLocaleString("en-US"));
console.log(big.toLocaleString("en-US", { style: "currency", currency: "USD" }));
console.log(big.toLocaleString("de-DE"));
The { style: ..., currency: ... } part is an options object: a set of named settings in curly braces. (Objects get their own section later.) Notice German formatting swaps the roles of the comma and the dot.
valueOf() returns a number as a number. JavaScript uses it behind the scenes to turn Number objects into plain numbers. There is no reason to use it in your own code, but every data type has a valueOf() and a toString(), so you will see it mentioned.
Number() converts a whole value to a number. Leading and trailing spaces are allowed, but if anything else is not numeric, you get NaN:
console.log(Number("10"));
console.log(Number(" 10 ")); // outer spaces are fine
console.log(Number("10.33"));
console.log(Number("10,33")); // comma: not a number
console.log(Number("10 33")); // space in the middle: not a number
console.log(Number("John"));
console.log(Number("")); // surprise!
console.log(Number(true), Number(false), Number(null), Number(undefined));
Number("") is 0, not NaN. So a blank form field quietly becomes zero and passes a Number.isNaN() check. If blank is not allowed, check for the empty string separately.
Number() can even convert a date: it gives the number of milliseconds since January 1, 1970. Number(new Date("1970-01-02")) is 86400000, one day's worth of milliseconds. The JS Dates section uses this a lot.
These read from the start of a string and stop at the first character that does not fit, returning whatever number they found. parseInt returns a whole number; parseFloat keeps decimals:
console.log(parseInt("-10.33")); // whole numbers only (cuts, no rounding)
console.log(parseInt("10 20 30")); // only the first number
console.log(parseInt("10 years")); // stops at the space
console.log(parseInt("years 10")); // must START with a number
console.log(parseFloat("10.33"));
console.log(parseFloat("3.99kg"));
console.log(parseInt("ff", 16)); // second value: the base
Number() when the whole value must be a valid number, like a form field for a price. Use parseInt / parseFloat when you want to pull a number off the front of text, like the 16 in "16px".
These belong to Number itself. You call them as Number.isInteger(x), passing the value in:
console.log(Number.isInteger(10)); // is it a whole number?
console.log(Number.isInteger(10.5));
console.log(Number.isFinite(123)); // a real number, not Infinity or NaN?
console.log(Number.isFinite(1 / 0));
console.log(Number.isSafeInteger(10)); // small enough to be exact?
console.log(Number.isSafeInteger(12345678901234567890));
Number. let x = 10; x.isInteger() throws TypeError: x.isInteger is not a function. Write Number.isInteger(x).
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN("hello")); // false: it's a string, not the NaN value
console.log(isNaN("hello")); // true: the old global converts first
The older global isNaN() converts its input to a number first, so it really answers "would this become NaN?". Number.isNaN() answers exactly "is this the NaN value?". Prefer the Number. version; isFinite() vs Number.isFinite() differ the same way.
Number.parseInt() and Number.parseFloat() are exactly the same functions as the global parseInt() and parseFloat(). They were added to Number to keep related tools together.
let priceInput = " 12.50 "; // what a text box might give you
let qtyInput = "3";
let price = Number(priceInput);
let qty = Number(qtyInput);
if (!Number.isFinite(price) || !Number.isInteger(qty)) {
console.log("Please enter valid numbers");
} else {
console.log(`Total: $${(price * qty).toFixed(2)}`);
}
Convert, check, calculate, and format last. Number.isFinite rejects both NaN and Infinity in one go, and Number.isInteger makes sure nobody orders 2.5 items.
What does this log?
let total = 4.5;
console.log(total.toFixed(2) + 1);
4.501. toFixed(2) returns the string "4.50", and + 1 joins a 1 onto it. Do the math first: (total + 1).toFixed(2) gives "5.50".You need the number from the CSS value "24px". Which works?
Number("24px")parseInt("24px")"24px".toFixed(0)Number.isInteger("24px")parseInt reads the number from the start and stops at p, giving 24. A gives NaN (the whole value is not a number), C is a TypeError (strings have no toFixed), and D gives false.A user leaves the quantity box blank, so you receive "". What is Number.isNaN(Number(""))?
true: blank is not a numberfalse: Number("") is 0undefined0, which is a perfectly good number. The blank box slips through, so check for "" yourself if blank should not be allowed.toPrecision(3) and toExponential(3) and compare the threeNumber("25%") and parseInt("25%")toString, then back with parseInt(..., 2) and parseInt(..., 16)toLocaleString