NaN in JavaScript
NaN, which stands for "Not a Number", is a value that JavaScript returns from certain functions and operations
when the result should be a number, but the result is not defined or not representable as a number. For example:
parseInt()returnsNaNif parsing failed:parseInt('bad', 10)Math.sqrt()returnsNaNif the given value is negative:Math.sqrt(-1)- Math operators return
NaNwhen one of the operands isn't a number:2 * NaN,3 ** undefined,4 / 'foo', etc. The exception is+, which JavaScript may treat as string concatenation.
Checking for NaN
The biggest quirk of NaN is that the === operator says that NaN is not equal to itself:
NaN === NaN; // false
To check if a value is NaN, you should use the Number.isNaN() function:
Number.isNaN(NaN); // true
Number.isNaN('test'); // false
You should not use the legacy global function isNaN(). This function checks if the given value would
result in NaN if you tried to convert it to a number, which can lead to surprising behavior:
isNaN(NaN); // true
isNaN('test'); // true
Be careful when using the typeof operator with NaN: the typeof operator reports that NaN is a number!
const v = parseInt('bad', 10);
v; // NaN
typeof v; // "number"
Serializing
One of the major reasons to avoid NaN is that most serializers don't have good support for NaN.
For example, NaN is not representable in JSON. The JSON.stringify() function converts NaN into null:
const obj = { x: NaN };
JSON.stringify(obj); // '{"x":null}'
On the other hand, Mongoose validation throws an error when a numeric value is NaN:
const Model = mongoose.model('Test', Schema({ test: Number }));
// Throws 'Cast to Number failed for value "NaN" at path "test"'
const doc = await Model.create({ test: NaN });
In general, you should consider encountering NaN an error unless you have a good reason not to. Writing NaN
to a database or in an HTTP request usually ends up either causing an error or ending up as a null value.