## DEV Community

Sam Sedighian

Posted on • Originally published at Medium

# Everything you need to know about NaN in JavaScript

`NaN` is a global property that represents the value of Not-A-Number, hence the name. It is possible to get the value `NaN` returned when doing an arithmetic operation or coercing some value to a number. Here are some operations that result in `NaN`

``````0 / 0; // NaN
Infinity / Infinity; // NaN
1 / undefined; // NaN
undefined / 1; // NaN

// [almost] all arithmetic operation involving NaN

NaN + 1; // NaN
NaN - 1; // NaN
NaN * 1; // NaN
NaN / 1; // NaN
NaN ** 1; // NaN
NaN % 1; // NaN
// with the exception of
NaN ** 0; // 1

// Finally, coercing any value that does not have a numeric value

parseInt('hi', 10); // NaN
parseFloat(undefined); // NaN
+"hi"; // NaN
Number({}); // NaN
"hi" - 1; // NaN
"hi" * 1; // NaN
"hi" / 1; // NaN
"hi" % 1; // NaN
"hi" ** 1; // NaN
``````

it is worth mentioning that most of the confusion about `NaN` comes from the behavior of coercing a non-numeric-value to a numeric-value which results in `NaN`. For this reason, I recommend getting yourself familiarized with the last few examples from the code above and better yet why some values such as booleans, `[1]` and `''` do not result in `NaN`

### Interesting facts about `NaN`

`NaN` has a bad reputation for being tricky, however, if you familiarize yourself with the following few facts you will be able to work with `NaN` with no issue.

`NaN` unlike it's name is actually from the type Number

``````typeof NaN; // 'number'
``````

`NaN` Has a falsy value

``````Boolean(NaN); // false
``````

`NaN` is the only value in JavaScript that does not equal itself. Hint: this will become useful later on.

``````NaN === NaN; // false
NaN == NaN; // false
NaN !== NaN; // true

// No, it is not pointing to a differnt NaN object (no such thing)
const iAmNaN = NaN;
iAmNaN == iAmNaN; //false
``````

You can access `NaN` in four different ways.

``````NaN;
this.NaN;
globalThis.NaN;
Number.NaN
``````

Avoid comparisons with `NaN`

``````NaN > 0; // false
NaN >= 0; // false
NaN < 0; // false
``````

### Let's look at an example

Let's say we have a function that takes one argument and increments it by `10` . We want to accept both numbers and strings representing a number so we will use `parseFloat`

``````const incrementByTen = function(val) {
const n = parseFloat(val, 10);
return n + 10;
};

incrementByTen(0); // 10 ✅
incrementByTen('2.3'); // 12.3 ✅

/*
result of parseFloat will be NaN in examples below
hence the addition operations will also return NaN
*/
incrementByTen(NaN); // NaN ❌
incrementByTen(false); // NaN ❌
incrementByTen({}); // NaN ❌
incrementByTen([]); // NaN ❌
incrementByTen('a'); // NaN ❌
incrementByTen(true); // NaN ❌
incrementByTen(['a', 1]); // NaN ❌
``````

We just learned there are plenty of arguments which would result in `NaN`. Perhaps a better way to handle this is to throw an error for those cases. However, as we learned earlier the usual comparisons will not work for `NaN` as we can see below. For this reason, we will use the global function `isNaN`.

``````typeof NaN === NaN; // false
NaN === NaN; // false
``````

## what is `isNaN` and how it works?

`isNaN` is a global function, takes a single argument and returns a boolean indicating whether or not the argument passed is `NaN`. MDN explains `isNaN` as such:

The function [ `isNaN` ] should be interpreted as answering the question, "is this value, when coerced to a numeric value, an IEEE-754 'Not A Number' value?"

We now write our function with `isNaN` to throw an error when the result of the `parseFloat` is `NaN`.

``````const incrementByTen = function(val) {
const n = parseFloat(val, 10);
if (isNaN(n)) {
throw new Error('Resulted in NaN!');
}
return n + 10;
};

incrementByTen(0); // 10 ✅
incrementByTen('2.3'); // 12.3 ✅
incrementByTen(NaN); // Error: Resulted in NaN! ✅
incrementByTen(false); // Error: Resulted in NaN! ✅
incrementByTen({}); // Error: Resulted in NaN! ✅
incrementByTen([]); // Error: Resulted in NaN! ✅
incrementByTen('a'); // Error: Resulted in NaN! ✅
incrementByTen(true); // Error: Resulted in NaN! ✅
incrementByTen(['a', 1]); // Error: Resulted in NaN! ✅
``````

Great, our function works as expected. Now let's learn a bit more about `isNaN`. Best way to understand how `isNaN` works is to create our own [basic version] polyfill for it. Polyfill is not required to use `isNaN`, It is super old...IE 3 old! 👴🏽

``````const isNaN = function(value) {
// coercing it into a numeric value. BEWARE OF THIS LINE
const n = Number(value);
// now checking to see if it does not equal itself
// only NaN does not equal itself 🤯
return n !== n;
};
``````

When working with `isNaN` you need to beware of the coercion of the value to a numeric-value. Remember some values cannot be coerced to a numeric-value and will result in `NaN` so even though your argument to `isNaN` might not have been `NaN` it could become one.

Here are a few examples where this happens and `isNaN` does not work as we perhaps expect it to:

``````isNaN(NaN); // true ✅

isNaN(undefined); // true ❌
isNaN('a'); // true ❌
isNaN({}); // true ❌
isNaN(['a']); // true ❌
isNaN(10n); // TypeError: Cannot convert a BigInt value to a number ❌
isNaN(Symbol()); // Uncaught TypeError: Cannot convert a Symbol value to a number ❌
``````

## `Number.isNaN` to the rescue 🦸🏻‍♀️

For the reasons that should be clear from above using `isNaN` is not ideal. This is why `Number.isNaN` has been added to JavaScript starting from ES6. The main difference between the two functions is that `Number.isNaN` does not convert its argument to a numeric-value before determining whether it is `NaN`.

``````Number.isNaN(NaN); // true ✅

Number.isNaN(undefined); // false ✅
Number.isNaN('a'); // false ✅
Number.isNaN({}); // false ✅
Number.isNaN(['a']); // false ✅
Number.isNaN(10n); // false ✅
Number.isNaN(Symbol()); // false ✅
``````

Great, it is working as expected. I recommend to always use `Number.isNaN`. Even if you want to coerce the value to a numeric-value do it yourself and then use `Number.isNaN` that way you are clearly expressing your intentions.

``````// Bad
isNaN(someValue);

// Good
Number.isNaN(someValue)

// And if we do need someValue to be coerced to a numeric-value
const numericalValue = +someValue; // or Number(someValue)
Number.isNaN(numericalValue);
``````

# Alternatives to native `isNaN` and `Number.isNaN`

As you can imagine before `Number.isNaN` was introduced there were some workarounds for us to handle this which perhaps are no longer needed but worth noting.

If you are not going to use `Number.isNaN`, this is perhaps the quickest and fastest way to get going. The key to understanding this function is that `isNaN` is the only value that does not equal itself.

``````const _isNaN = function(value) {
return value !== value;
}
``````

### Lodash and Underscore

Both of these popular utility libraries have their own version of the functionality which works similar to `Number.isNaN`

``````import lodash from 'lodash';
import underscore from 'underscore';

lodash.isNaN();
underscore.isNaN();
``````