back arrow

Back to all blogs

NaN: Not a Number or Invalid Number?

NaN: Not a Number or Invalid Number?

We have this thing in Javascript called NaN. Actually it's not created by JavaScript. It is invented by IEEE. If you have something that is not a number and use it in places that'll end up coercing it to a number you'll get NaN as result. Let me show this with an example:

'hello' * 2; // NaN

We used 'hello' that is not a number in a arithmatic operation (multiplication) which is going to coerce any non-number values to number (useing toNumber() abstract operation), and coercing 'hello' to number ends up in NaN:

NaN * 2; // NaN

Any mathematic operation with NaN results in NaN.

Minus, divide and multiply operators will try to coerce non-number values into number. And if we use a value that is not a number in these operations the result is NaN :

'hello' * 2; // NaN
'hello' / 2; // NaN
'hello' - 2; // NaN

Plus operator will try to coerce different types to string. So if we have a number in this operation it's gonna coerce it to string:

'hello' + 2; // 'hello2'

Corner Cases

If you ask for NaN type using typeof operator you get "number" back:

typeof NaN; // "number"

This is reasonable since you are using it in numeric operations. Like:

Number('my age'); // NaN
2022 - 'last year'; // NaN

Wait, if its type is number why we're calling it "not a number"? well, we better start calling it invalid number. It is a number but an invalid one.

It is the only thing in Javascript that does not equal to itself (neither loose equality nor strict equality) or any other value:

NaN == NaN; // false
NaN === NaN; // false

NaN === 'NaN'; // false
NaN === 2; // false

And doing any sort of mathematic operations with NaN is going to result in NaN

NaN - NaN; // NaN
NaN - 0; // NaN
NaN - 'hello'; // NaN

NaN is also one of the falsy values in JavaScript:

Boolean(NaN); // false
!!NaN; // false

Testing NaN

So how we can determine if a value is NaN? We can use a built-in utility called isNaN():

isNaN(2022); // false

isNaN(Number('my age')); // true

const thisYear = 'MMXXII';
isNaN(thisYear); // true

We know that Number('my age') is NaN. But what about 'MMXXII'? Obviously, it is not a number but it is not a NaN value either. It is not NaN untill it get coerced to number and then result in NaN.

So what happened? Turns out isNAN utility tries to coerce non-number values into number, which is not the exact behavior we want.

We can use Number.isNaN() method instead. It doesn't do any coercing.

Number.isNaN(2022); // false

Number.isNaN(Number('my age')); // true

const thisYear = 'MMXXII';
Number.isNaN(thisYear); // false

We can also use Object.is() to test if a value is NaN or not:

function isItNaN(val) {
	if (typeof val !== 'number') return false;

	return Object.is(val, NaN);
}

isItNaN(2022); // false

isItNaN(Number('my age')); // true

const thisYear = 'MMXXII';
isItNaN(thisYear); // false
All Blogs