Types and Converting Between Them
Tell numbers, strings and booleans apart with typeof, turn text into numbers and back with Number() and String(), and know why '5' + 3 is '53' and where NaN comes from.
Apprentice · JavaScript · Updated
After this lesson you can
- Tell numbers, strings and booleans apart, and check a value's type with typeof
- Convert between text and numbers with Number() and String(), and explain results like NaN and '5' + 3
Key takeaways
- Every value has a type. typeof tells you which one, as a string such as 'number', 'string' or 'boolean'.
- When either side of + is a string, + joins instead of adding, so '5' + 3 is '53'.
- Text a person types, into a form or a prompt, always reaches your code as a string, even when it's digits.
- Number('2') turns text into the number 2, and String(4.75) turns a number into the text '4.75'.
- Number() gives NaN, "not a number", for text that isn't a number, and any math with NaN gives NaN.
A customer orders 2 lattes and 1 extra shot on a coffee shop's website, and the cart says 21 items. It's a real kind of bug, and it happens because the 2 and the 1 the customer typed arrived as text, not as numbers. Once you can tell the kinds of value apart and convert between them, you can find bugs like this in seconds, and stop them before a customer sees them.
Every value has a type
You've met three kinds of value in this chapter: numbers (4.75), strings ('latte') and booleans (true). The kind of value is its type. Textbooks call these simple, single values primitive values, or primitive types.
typeof, read "type of", tells you a value's type. It answers with a string:
const lattePrice = 4.75;
const drink = 'latte';
const isOpen = true;
const typedPrice = '4.75';
console.log(typeof lattePrice);
console.log(typeof drink);
console.log(typeof isOpen);
console.log(typeof typedPrice);
number
string
boolean
string
The last line is the one to remember: '4.75' has digits in it, but the quotes make it a string. In JavaScript the value has the type, not the variable, so a let variable can hold a number now and a string later. typeof looks at whatever it holds right then.
Why '5' + 3 is '53'
+ has two jobs: between numbers it adds, and between strings it joins. When one side is a string and the other a number, JavaScript can't do both, so it turns the number into text and joins. -, * and / only do math, so they go the other way and turn the text into a number:
console.log(5 + 3);
console.log('5' + 3);
console.log('5' - 3);
console.log('5' * 3);
8
53
2
15
JavaScript changing a value's type on its own like this is called type coercion, read "co-ER-shun", or implicit conversion. It's why the rule of thumb is: don't let JavaScript guess. Convert the value yourself, and you always know what you'll get.
Text a person types is always a string
Whatever a person types, into a box on a web page or a prompt in a terminal program, reaches your code as a string, even when it's only digits. You'll read form boxes in Module 4; for now, a string in quotes stands in for what the customer typed:
const typedQuantity = '2';
const typedExtraShots = '1';
const lattePrice = 4.75;
console.log(typedQuantity * lattePrice);
console.log(typedQuantity + typedExtraShots);
9.5
21
The first line works by luck: * turned '2' into 2. The second is the bug: 2 drinks plus 1 extra shot came out as 21, because + joined two strings.
Converting with Number() and String()
Number(...) turns text into a number, and String(...) turns a value into text. Converting on purpose like this is called type conversion:
const typedQuantity = '2';
const typedExtraShots = '1';
const quantity = Number(typedQuantity);
const extraShots = Number(typedExtraShots);
console.log(quantity + extraShots);
console.log(typeof quantity);
console.log(String(1042).length);
3
number
4
Convert once, as soon as the text arrives, and store the number in a well-named variable. From then on, every + adds. String(1042).length is a handy trick too: a number has no length, but its text does, so it says how many digits an order number has.
Try it. In your practice folder, make a file named typed.js. Pretend a customer typed '3' in the muffin box and '1' in the cookie box. Add the two with + and print how many items that makes, then convert both with Number() and print it again. Use typeof to check each value.
NaN: not a number
What happens when the customer types two instead of 2? Number('two') can't make a number from that, so it gives NaN, read "not a number" (or "nan"). NaN spreads: any math with NaN gives NaN, so one bad box can turn a whole receipt into NaN.
const quantity = Number('two');
console.log(quantity);
console.log(quantity * 4.75);
console.log(typeof quantity);
console.log(Number.isNaN(quantity));
console.log(Number(' 3 '));
NaN
NaN
number
true
3
Two surprises here. typeof NaN is 'number': NaN is JavaScript's way of saying "a number that went wrong". And Number(' 3 ') is 3: spaces at the ends are ignored. (An empty box is a third surprise: Number('') is 0, not NaN.) To test for NaN, use Number.isNaN(value), which answers true or false; in the next chapter you'll use that answer to show the customer a helpful message instead of a broken total.
Try it. In typed.js, print Number('4.75'), Number('$4.75'), Number('12 lattes') and Number('1,000'). Predict each one first. Which ones surprise you?
Check yourself
2 questions to try on the lesson page.
So what
Most confusing bugs in beginners' JavaScript, and plenty in professionals', come from a value being a different type than the code expected. Check with typeof, convert typed text with Number() as soon as it arrives, and watch for NaN.