Type Conversion and Coercion

JavaScript ES2024 · ✓ verified by execution on

JavaScript allows you to convert values from one type to another explicitly, but it will also try to do it for you automatically (implicitly) when operators are involved.

Explicit Conversion

You can strictly convert strings to numbers using Number(), or convert values to strings using String().

javascript
console.log(Number('42'));
console.log(String(100));
Output
42
100

However, Number() is very strict. If it encounters letters, it fails entirely.

javascript
console.log(Number('42px'));
Output
NaN

To extract numbers from mixed strings, you can use parseInt() instead. It parses character-by-character and stops when it hits a letter.

javascript · visualize
console.log(parseInt('42px', 10));
42

Implicit Coercion

Sometimes JavaScript guesses what you want. When you use the + operator, JavaScript prefers joining strings together (concatenation).

javascript
console.log('5' + 3);
Output
53

But what happens when you use other math operators?

Predict the output javascript

Read the code. What exactly will it print? Commit to an answer before you look.

console.log('5' - 3);
Output
2

The Coercion Pitfall

'5' + 3 could plausibly do two things: refuse, the way a strict language would, or quietly produce 8. It does neither. Early JavaScript was built to keep a page running rather than stop it, so instead of refusing it converts — and the direction it converts in depends on the operator.

+ does two jobs — addition and concatenation — so when the types differ it has to pick one, and it picks concatenation whenever either side is a string. -, * and / have no string meaning at all, so there is nothing to pick: they convert to numbers and do the arithmetic.

So the behaviour turns on which operator you used, which is not something you can see by looking at the values. Convert before you calculate — Number(x), or a unary + — and the question stops arising.

The reason this bites in real code is that strings arrive where you did not choose them. Every value read from an <input> element is a string, even when the field is type="number". So is every field of a JSON payload typed as a string by whatever produced it, and every value pulled out of localStorage, which stores nothing else. A total that is correct in testing and becomes "1020" in production usually has one of those three at the far end of it.

parseInt() and parseFloat() are worth knowing for the opposite reason: they are deliberately lenient, reading as far as they can and ignoring the rest. That is what you want for "42px" and exactly what you do not want for validating user input, where parseInt("12 monkeys") quietly yielding 12 hides the problem you were checking for.

"5" + 3 Has string operand? Yes → "53" Concatenates strings "5" - 3 Operator means Math? Yes → 2 Forces numeric coercion
Operator behavior during implicit coercion

Check yourself

What does Number('42px') return?

Reveal answer

NaN — Number() strictly requires a fully numeric string. Any non-numeric characters result in NaN.

What is the result of '5' + 3?

Reveal answer

'53' — The + operator triggers implicit coercion to string, resulting in concatenation: '53'.

What is the result of '5' - 3?

Reveal answer

2 — The - operator triggers implicit coercion to number, evaluating mathematically as 2.

Challenges

Challenge 1 +20 XP

Convert the string variable to a number.

javascript
  • Test 1 — expects "3.14"
Need a hint? (−25% XP)

Use the Number() constructor function to convert the string.

Show solution (0 XP)
const n = '3.14';
const res = Number(n);
console.log(res);

Challenge 2 +20 XP

Extract the integer from the CSS value.

javascript
  • Test 1 — expects "100"
Need a hint? (−25% XP)

parseInt() extracts numbers until it hits a non-numeric character.

Show solution (0 XP)
const s = '100px';
const res = parseInt(s, 10);
console.log(res);