Numbers are mostly well-behaved. But they have a few oddball relatives that show up at family gatherings and make everybody uncomfortable.
NaN: Not a Number
What happens if you try to do math with something that isn't a number?
const result = "pizza" * 3;
console.log(result);
It prints
NaN
NaN stands for Not a Number. It's JavaScript's way of saying "I tried to do math here, and it made no sense." Three pizzas? Sure. "pizza" times three? That's not math, that's a menu.
And here comes the weirdness. Brace yourself:
console.log(typeof NaN);
console.log(NaN === NaN);
It prints
number false
Yes. The value called "Not a Number" is... a number. And it's not equal to itself. (typeof tells you a value's type, and === checks if two things are equal; we'll properly meet both soon.) Programmers have been making jokes about this for decades.
To check if something is NaN, use Number.isNaN():
console.log(Number.isNaN("pizza" * 3));
console.log(Number.isNaN(42));
It prints
true false
Infinity
What's 1 divided by 0? In math class, your teacher says "you can't do that." JavaScript just shrugs and says:
console.log(1 / 0);
console.log(-1 / 0);
It prints
Infinity -Infinity
Infinity is a special number that's bigger than any other number. You won't need it often, but now you won't be shocked when it appears.
The 0.1 + 0.2 mystery
Okay, try this one in your console. It's a classic:
console.log(0.1 + 0.2);
It prints
0.30000000000000004
Is your computer broken? Nope! This happens in almost every programming language, not just JavaScript.
Computers store numbers in binary (1s and 0s). Some decimals that look simple to us, like 0.1, can't be written exactly in binary, the same way that 1/3 can't be written exactly in decimal (it's 0.33333... forever). So the computer stores a value that's extremely close to 0.1, but not exactly 0.1. When you add two of these tiny approximations together, the tiny errors become visible. The technical name for this kind of number is floating point.
For most things, this doesn't matter at all. But when you're dealing with money, you want your numbers to look right. Two easy fixes:
- Round when you display using
toFixed(), which rounds to a certain number of decimal places:
const total = 0.1 + 0.2;
console.log(total.toFixed(2));
It prints
0.30
- Work in the smallest unit. Instead of storing $1.50, store 150 cents. Whole numbers don't have the rounding problem. Banks and online shops often do exactly this.
toFixed() returns a string, not a number. That's great for displaying, but if you try to do more math with it, you might get surprises (see "Type Coercion" at the end of this grade). Do your math first, and use toFixed() last, just before showing the result.