When you mix different types in an operation, JavaScript doesn't throw an error. Instead, it quietly converts one of the values to make the operation work. This automatic conversion is called type coercion. Sometimes it's helpful. Sometimes it's... a surprise gift that you didn't ask for.
console.log("5" + 3);
console.log("5" - 3);
console.log("5" * "2");
console.log("10" / 2);
console.log(true + 1);
console.log("Score: " + 10 + 5);
console.log("Score: " + (10 + 5));
It prints
53 2 10 5 2 Score: 105 Score: 15
What's going on here? It comes down to one simple rule:
- With
+, if either side is a string, JavaScript converts the other side to a string too, and glues them together. - With
-,*,/(and other math operators), JavaScript converts everything to numbers and does math.
So "5" + 3 is glue ("53"), but "5" - 3 is math (2), because you can't "un-glue" strings. And true + 1 is 2 because true converts to the number 1 (and false converts to 0).
The last two are sneaky. JavaScript works left to right: "Score: " + 10 gives the string "Score: 10", and then + 5 glues on a 5, giving "Score: 105". Wrap the math in parentheses so it happens first, and you get the right answer.
Type coercion is the source of a huge number of JavaScript bugs. Our advice: don't rely on it. When you need a number, convert it yourself with Number(). When you need a string, use a template literal or String(). Being explicit means there are no surprises.