NaN in JavaScript
source link: https://dmitripavlutin.com/nan-in-javascript/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
The number type in JavaScript holds integers and floats:
const integer = 4; const float = 1.5; typeof integer; // => 'number' typeof float; // => 'number'
Plus there are 2 special number values: Infinity
(a number bigger than any other number) and NaN
(representing “Not A Number” concept):
const infinite = Infinity; const faulty = NaN; typeof infinite; // => 'number' typeof faulty; // => 'number'
NaN
is a special number that indicates a faulty operation on numbers. While working directly with NaN
is rare, it can appear surprisingly after a failed operation on numbers.
Let’s take a closer look at NaN
special value: how to check if a variable has NaN
, and importantly understand the scenarios that create “Not A Number” values.
1. NaN number
The number type in JavaScript is a set of all number values, including “Not A Number”, positive infinity and negative infinity.
“Not A Number” numeric value can be accessed using a special expression NaN
, or as a property of the global object or Number
function:
typeof NaN; // => 'number' typeof window.NaN; // => 'number' typeof Number.NaN; // => 'number'
“Not a Number” is a numeric value that does not represent a real number, even having the number type. In simpler words, NaN
becomes useful to represent faulty operations on numbers.
For example, multiplying a number with undefined
is not a valid operation, thus the result is NaN
:
1 * undefined; // => NaN
Also trying to parse an invalid numeric string like 'Joker'
results in NaN
too:
parseInt('Joker', 10); // => NaN
The section3. Operations resulting in NaNdetails into the operations that generate NaN
.
2. Checking for equality with NaN
The interesting property of NaN
is that it doesn’t equal to any value, even with the NaN
itself.
NaN === NaN; // => false
This behavior is useful to detect if a variable contains NaN
value:
const someNumber = NaN; if (someNumber !== someNumber) { console.log('Is NaN'); } else { console.log('Is Not NaN'); } // logs "Is NaN"
The above snippet logs to console "Is NaN"
. someNumber !== someNumber
expression is true
only if someNumber
is NaN
.
JavaScript has bult-in functions that let’s you detect NaN
value: isNaN()
and Number.isNaN()
:
isNaN(NaN); // => true isNaN(1); // => false Number.isNaN(NaN); // => true Number.isNaN(1); // => false
The difference between these functions is that Number.isNaN()
doesn’t convert its argument to a number:
isNaN('Joker12'); // => true Number.isNaN('Joker12'); // => false
isNaN('Joker12')
converts the argument 'Joker12'
into a number, which is NaN
. Thus the function returns true
.
On the other side, Number.isNaN('Joker12')
checks without conversion if the argument is NaN
. The function returns false
because 'Joker12'
doesn’t equal NaN
.
3. Operations resulting in NaN
3.1 Parsing numbers
JavaScript allows parsing numeric strings into numbers. For example, you could easily transform the '1.5'
string into a 1.5
number.
const numberString = '1.5'; const number = parseFloat(numberString); number; // => 1.5
But not all string values can be parsed to numbers, in which case the parsing function returns NaN
value (which indicates that parsing has failed). Here are some examples:
parseFloat('Joker12.5'); // => NaN parseInt('Joker12', 10); // => NaN Number('Joker12'); // => NaN
When parsing numbers, it’s always a good idea to verify if the parsing result is not NaN
:
let inputToParse = 'Invalid10'; let number; number = parseInt(inputToParse, 10); if (isNaN(number)) { number = 0; } number; // => 0
If parsing of the inputToParse
failed, the number
variable gets a default number 0
.
3.2 undefined as an operand
Another common case when NaN
value is created is when undefined
is an operand in arithmetical operations like addition, multiplication, etc.
For example:
function getFontSize(style) { return style.fontSize; } const fontSize = getFontSize({ size: 16 }) * 2; const doubledFontSize = fontSize * 2; doubledFontSize; // => NaN
getFontSize()
is a function that accesses the fontSize
from a style object. When invoking getFontSize({ size: 16 })
, the result is undefined
( fontSize
property does not exist in { size: 16 }
object).
fontSize * 2
is evaluated as undefined * 2
, which results in NaN
.
“Not A Number” is generated when a missing property or a function returning undefined
is used as a value in arithmetical operations.
Making sure that undefined
doesn’t reach arithmetical operations is a good approach to prevent generating NaN
. Handle missing properties correctly (for example by using default values). Feel free to check “7 Tips to Handle undefined in JavaScript”
.
3.3 NaN as an operand
NaN
value is also generated when an operand in aritemtical operations is NaN
:
1 + NaN; // => NaN 2 * NaN; // => NaN
It might be difficult to find the source of the problem because NaN
spreads across the arithmetical operations:
let invalidNumber = 1 * undefined; let result = 1; result += invalidNumber; // appendresult *= 2; // duplicate result++; // increment result; // => NaN
Operations on result
variable are broken after invalidNumber
value (which has NaN
) is appended to result
.
3.4 Indeterminate forms
NaN
value is created when arithmetical operations are in indeterminate forms.
The division of 0 / 0
and Inifinity / Infinity
:
0 / 0; // => NaN Infinity / Infinity; // => NaN
The multiplication of 0
and Infinity
:
0 * Infinity; // => NaN
Additions of infinite numbers of different signs:
-Infinity + Infinity; // => NaN
3.5 Invalid arguments of math functions
The square root of negative number:
Math.pow(-2, 0.5); // => NaN (-2) ** 0.5; // => NaN
Or the lograrithm of a negative number:
Math.log2(-2); // => NaN
4. Conclusion
“Not A Number” concept, expressed in JavaScript with NaN
, is useful to represent faulty operations on numbers.
NaN
doesn’t equal to any value, even with NaN
itself. The recommended way to check if a variable contains NaN
value is to use Number.isNaN(value)
.
Parsing numerical strings to numbers could result in “Not A Number”. It’s a good idea to check whether parseInt()
, parseFloat()
or Number()
don’t return NaN
value.
undefined
or NaN
as an operand in arithmetical operations almost always result in NaN
. Correct handling of undefined
(providing defaults for missing properties) is a good approach to prevent this situation.
Indeterminate forms or invalid arguments for mathematical functions also result in “Not A Number”. But these cases happen rarely.
Here’s my pragmatic advice: “Got NaN
? Search for undefined
!”
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK