What is type coercion?
Type coercion in javascript is the implicit casting of data types into different ones during operations like comparisons or calculations. If and into to what a data type is coerced depends on the operation and the other data type at play, leading to some confusion. While all data types can be coerced, they can only be coerced into one of 3 primitives: boolean
, string
or number
.
The rules of coercion
Type coercion follows a specific set of rules, making it predictable once understood:
+
operator: If one of the variables is astring
, it coerces the other into astring
and performs string concatenation. If none of them is astring
, it coerces both intonumber
and performs mathematical addition.- Logical operators
&&
and||
: Coerces both variables toboolean
no matter what type they are - Loose equality operators
==
and!=
: Coerces both variables tonumber
unless both arestring
- Strict equality operators
===
and!==
: Never coerce any variable. Differing data types are considered not equal. - All other operators always coerce both variables to
number
About truthy and falsy values
Implicit type coercion with booleans may seem a bit tricky in reality, because they are treated as numbers outside of logical operators. To understand this, we first need to remember that true
is equal 1
and false
equal to 0
when coerced into a number
. When casting other variables into boolean
, the results are a little different. The following values result in false values (i.e. are falsy):
""
0
-0
NaN
null
undefined
false
These are the only values resulting in false
when coerced to boolean
, all other (including empty arrays and objects) are considered truthy (i.e. turn into true
when coerced into boolean
).
Confusion with boolean
expressions
Booleans are tricky because while they behave like booleans with logical operators ||
and &&
, they are coerced into number
data types for all other comparisons.
Here is how that may be confusing:
// returns true
// because && operator coerces 4 into boolean,
// 4 is not a falsy value so it evaluates to true
4 && true // true
// returns false
// because loose equality checks coerce true into a number(1)
// and 4 isn't equal to 1
4 == true // false
// returns true
// because non-exceptional operators coerce true into number(1)
// and 4 is greater than 1
4 > true // true
// returns true
// Boolean(4) evaluates to true
// then both values are coerced into numbers (1)
// and 1 is equal to 1
Boolean(4) == true // true
If you don't want to think about edge cases like this and prefer more straight-forward operator behaviour as in most other programming languages, simply cast primitive data types manually with Number()
, Boolean()
and String()
, and always use strict equality checks like ===
and !==
.