
Number.isNaN(), Number.isFinite(), and Number.isInteger() in JavaScript

JavaScript number handling becomes much easier once you stop assuming every "number check" works the same way.
That assumption causes a lot of confusion because older global functions such as isNaN() and isFinite() do a surprising amount of coercion. In other words, they often answer a slightly different question from the one people thought they were asking.
ES6 improved this area with methods attached to Number itself:
Number.isNaN()Number.isFinite()Number.isInteger()
These are small additions, but they make numeric checks much less slippery.
Start with the awkward one: NaN
NaN stands for "Not a Number", but it is still of type number.
That already sounds slightly ridiculous, which is probably why it confuses people so reliably.
You usually meet NaN when numeric work fails:
const result = Number('hello');console.log(result);That gives NaN.
The question then becomes: how do we check for it safely?
The old global isNaN() coerces values first
This is the behaviour that catches people:
console.log(isNaN('hello'));That returns true.
Why? Because the global isNaN() first tries to turn the value into a number, and only then checks whether the result is NaN.
So the question it really answers is closer to:
"Would this value become NaN if JavaScript tried to coerce it into a number?"
That is occasionally useful, but it is not always what we want.
Number.isNaN() is much stricter
Number.isNaN() only returns true when the value is actually the numeric NaN value:
console.log(Number.isNaN(NaN));console.log(Number.isNaN('hello'));That produces:
truefalseThis is usually the safer and clearer check because it does not smuggle coercion into the process.
Why This Distinction Matters in Real Code
Suppose we are reading user input from a form:
const rawValue = '42';If we want to know whether the original value is already NaN, Number.isNaN(rawValue) is correctly false.
If we want to know whether converting it to a number failed, then we should convert explicitly and check that result:
const parsedValue = Number(rawValue);if (Number.isNaN(parsedValue)) { console.log('Invalid number');}That keeps the parsing step visible instead of letting the checker hide it.
Number.isFinite() avoids a similar coercion trap
The same idea applies to finiteness.
The global isFinite() coerces:
console.log(isFinite('10'));That returns true.
Again, JavaScript is converting the string before performing the test.
Number.isFinite() is stricter:
console.log(Number.isFinite(10));console.log(Number.isFinite('10'));console.log(Number.isFinite(Infinity));That gives:
truefalsefalseThis is much more honest. It answers the question "is this already a finite number?" rather than "could this be coerced into one?"
This is Useful When Validating Calculations
If some computation might blow up into Infinity or ‑Infinity, Number.isFinite() gives us a sensible guard:
const percentage = total === 0 ? Infinity : (value / total) * 100;if (!Number.isFinite(percentage)) { console.log('Cannot display percentage');}That is clearer than folding coercion and validation into one fuzzy step.
Number.isInteger() checks whether a number has no fractional part
This is the third method in the set:
console.log(Number.isInteger(3));console.log(Number.isInteger(3.5));console.log(Number.isInteger('3'));The results are:
truefalsefalseThis is helpful when we genuinely need whole‑number values:
- pagination
- item counts
- array indexes
- calendar day values
It is Stricter than Informal Truthiness Checks
Developers sometimes write validation like:
if (value % 1 === 0) { // ...}That can work, but Number.isInteger() expresses the intent much more directly.
It also avoids implying that strings or other coercible values should count as valid without an explicit conversion step.
Parsing and Checking Should Usually Be Separate Steps
This is the habit that makes all three methods easier to use properly.
Instead of:
if (isNaN(inputValue)) { // ...}prefer:
const parsedValue = Number(inputValue);if (Number.isNaN(parsedValue)) { // ...}That keeps the code honest:
- convert the value
- inspect the result
When those two concerns are separated, bugs become easier to reason about.
Floating‑Point Numbers Still Need Caution
Number.isInteger() checks whether the final value is an integer, but JavaScript numbers are still subject to floating‑point precision issues.
For example:
const value = 0.1 + 0.2;console.log(value);console.log(Number.isInteger(value));The result is not an integer, and the familiar precision oddities still apply.
These methods improve clarity, but they do not change how numbers are represented internally.
The Bigger Win is Conceptual Clarity
All three methods push us towards the same healthier habit:
- stop relying on hidden coercion
- make parsing explicit
- validate the actual value you now have
That is why they are better than their older global cousins in most application code.
You can still use isNaN() or isFinite() if you specifically want coercive behaviour, but that should be a deliberate choice rather than an accident.
These are Better Checks Because They Ask Better Questions
Number.isNaN(), Number.isFinite(), and Number.isInteger() are not dramatic features. They are simply better named, stricter, and easier to trust.
That makes them typical of the quieter side of modern JavaScript. They remove some older ambiguity and encourage code that says exactly what it means.
When you are validating numeric data, that is more valuable than it might first appear.
Related Articles

Browser vs. Node.js in JavaScript: Why Code Works in One and Fails in the Other. 
Flattening Arrays in JavaScript. Flattening Arrays in JavaScript

What are CSS Preprocessors, and Why Should You Use Them? What are CSS Preprocessors, and Why Should You Use Them?

What A Levels Do You Need for Software Engineering? What A Levels Do You Need for Software Engineering?

Why HTML Form Values are Always Strings in JavaScript. Why HTML Form Values are Always Strings in JavaScript

Classes in JavaScript: An Introduction. Classes in JavaScript: An Introduction

Single or Double Colons in CSS Pseudo‑Elements (:before vs. ::before). Single or Double Colons in CSS Pseudo‑Elements (
:beforevs.::before)
Finding the Difference Between Two Strings in JavaScript. Finding the Difference Between Two Strings in JavaScript

Creating Custom Vue Directives for Enhanced Functionality. Creating Custom Vue Directives for Enhanced Functionality

JavaScript String Manipulation: substring() vs. substr(). JavaScript String Manipulation:
substring()vs.substr()
LocalStorage in JavaScript. localStoragein JavaScript
Prefix and Suffix Products: Solving 'Product of Array Except Self'. Prefix and Suffix Products: Solving 'Product of Array Except Self'