Back to all blogs
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'
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
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