Number.isInteger()
Tests whether a value is a number with no fractional part.
Number.isInteger(value)- Added in JavaScript ES2015
Parameters
| Parameter | Type | Description |
|---|---|---|
$value | any | The value to be tested for being an integer. |
Return value
boolean`true` if the value is a number with an integer value, `false` otherwise.
Number.isInteger() answers one question honestly: is this a number, and does it have no fractional part? It never coerces, so "5", true and null are all false. That makes it a safe first line in input validation, unlike the older x % 1 === 0 idiom, which coerces its operand first and so returns true for strings, booleans, null and empty arrays. (That idiom does reject Infinity, since Infinity % 1 is NaN.)
What counts as an integer
There is no separate integer type in JavaScript, so 5.0 and 5 are the same double and both report true. NaN, Infinity and -Infinity are all false.
The precision catch
Very large or very precise literals lose their fraction before this function ever sees them. Number.isInteger(5.0000000000000001) is true because that literal rounds to exactly 5 when stored. Likewise every finite number above 253 reports true, since doubles that large cannot hold a fractional part at all. If you care that arithmetic on the value will stay exact, use Number.isSafeInteger() instead — it adds the magnitude check this function deliberately omits.
When to reach for it
Validating array indices, page numbers, counts, and any API parameter documented as an integer, before passing it on.
Example
When to use it
- Reject a fractional page number before a database query
- Validate that a user-supplied quantity is a whole count
- Guard an array index passed in from external data
Frequently asked questions
How do I check if a number is a whole number in JavaScript?
Use Number.isInteger(value). It returns true only for numbers with no fractional part and never coerces strings or booleans.
Why does Number.isInteger(5.0) return true?
JavaScript has one numeric type, so 5.0 and 5 are the same double. There is no stored difference between them to detect.
What is the difference between Number.isInteger() and Number.isSafeInteger()?
isSafeInteger() adds a magnitude limit of ±(2^53 - 1), so it rejects huge whole numbers where integer arithmetic silently stops being exact.
More examples
Validating a quantity field
Because there is no coercion, a string from a form field fails the check outright — convert with Number() first if you intend to accept text input.
function validQuantity(v) {
return Number.isInteger(v) && v > 0 && v <= 100;
}
console.log(validQuantity(3)); // true
console.log(validQuantity(3.5)); // false
console.log(validQuantity('3')); // false — strings are not numbers
console.log(validQuantity(0)); // false
console.log(validQuantity(101)); // falseWhy the modulo idiom is worse
The modulo test passes for anything that coerces to a whole number, including empty arrays and booleans; Number.isInteger() rejects every non-number.
const cases = ['5', true, [], Infinity, 5];
for (const c of cases) {
console.log(
JSON.stringify(c),
'modulo:', c % 1 === 0,
'isInteger:', Number.isInteger(c),
);
}
// "5" modulo: true isInteger: false
// true modulo: true isInteger: false
// [] modulo: true isInteger: false
// null modulo: false isInteger: false (Infinity serialises as null)
// 5 modulo: true isInteger: truePairing with a range check
isInteger() is satisfied by any whole-valued double; only isSafeInteger() also confirms that adding one to the value will actually change it.
const values = [7, 2 ** 53, 1e100, -3];
for (const v of values) {
console.log(v, Number.isInteger(v), Number.isSafeInteger(v));
}
// 7 true true
// 9007199254740992 true false
// 1e+100 true false
// -3 true true
Discussion