In JavaScript, type coercion affects how values are converted when used with arithmetic and logical operators. Let's look at how coercion works with each operator type, covering both implicit and explicit coercion in arithmetic and logical operations.
Arithmetic Operators and Coercion
JavaScript has five main arithmetic operators: +
, -
, *
, /
, and %
. Here’s how each one handles coercion:
1. +
(Addition)
-
Behavior: If one operand is a string,
+
coerces the other operand to a string and performs string concatenation. - Otherwise: Both operands are coerced to numbers, and addition is performed.
console.log(5 + "3"); // "53" (5 is coerced to "5" and concatenated)
console.log("10" + 2); // "102" (2 is coerced to "2")
console.log(5 + 3); // 8 (no coercion needed)
2. -
(Subtraction), *
(Multiplication), /
(Division), %
(Modulus)
- Behavior: All these operators expect numeric values, so both operands are coerced to numbers if they’re not already.
-
If coercion fails: Non-numeric values that cannot be converted result in
NaN
.
console.log(10 - "3"); // 7 ("3" is coerced to 3)
console.log("20" / "5"); // 4 (both "20" and "5" are coerced to numbers)
console.log(5 * "2"); // 10 ("2" is coerced to 2)
console.log("hello" - 2); // NaN ("hello" can't be coerced to a number)
Logical Operators and Coercion
Logical operators in JavaScript include &&
(AND), ||
(OR), and !
(NOT). These operators don’t directly perform arithmetic operations, but they use truthy and falsy values in coercion.
Truthy and Falsy Values
In JavaScript:
-
Falsy Values:
false
,0
,""
(empty string),null
,undefined
, andNaN
. - Truthy Values: Everything else, including non-empty strings, non-zero numbers, objects, and arrays.
1. &&
(Logical AND)
- Behavior: If the first operand is falsy, it’s returned immediately. Otherwise, the second operand is returned.
- Coercion: Operands are coerced to Boolean values to determine truthiness, but the actual operand values are returned (not Boolean results).
console.log(true && "hello"); // "hello" (true is truthy, so it returns the second operand)
console.log(0 && "hello"); // 0 (0 is falsy, so it returns 0 without checking the second operand)
console.log("world" && 42); // 42 ("world" is truthy, so it returns the second operand)
2. ||
(Logical OR)
- Behavior: If the first operand is truthy, it’s returned immediately. Otherwise, the second operand is returned.
- Coercion: Operands are coerced to Boolean values for the check, but the actual operand values are returned.
console.log(false || "hello"); // "hello" (false is falsy, so it returns the second operand)
console.log(0 || 42); // 42 (0 is falsy, so it returns 42)
console.log("hi" || "world"); // "hi" ("hi" is truthy, so it returns "hi" without checking the second operand)
3. !
(Logical NOT)
- Behavior: Coerces the operand to a Boolean and then inverts it.
- Coercion: Non-Boolean values are coerced to Boolean for the inversion.
console.log(!"hello"); // false ("hello" is truthy, so `!` inverts it to false)
console.log(!0); // true (0 is falsy, so `!` inverts it to true)
console.log(!undefined); // true (undefined is falsy, so `!` inverts it to true)
Comparison Operators and Coercion
Comparison operators include ==
, ===
, !=
, !==
, >
, <
, >=
, and <=
. Type coercion affects some of these operators in specific ways:
1. ==
(Loose Equality) and !=
(Loose Inequality)
- Behavior: These operators perform type coercion if the types of operands differ. They convert both operands to comparable types (usually numbers or strings).
console.log(5 == "5"); // true (string "5" is coerced to number 5)
console.log(null == undefined); // true (null and undefined are loosely equal)
console.log(0 == false); // true (false is coerced to 0)
2. ===
(Strict Equality) and !==
(Strict Inequality)
- Behavior: No coercion is performed; both value and type must be the same.
console.log(5 === "5"); // false (no coercion, different types)
console.log(0 === false); // false (no coercion, different types)
console.log(null === undefined); // false (no coercion, different types)
3. Relational Operators (>
, <
, >=
, <=
)
- Behavior: If both operands are strings, they are compared lexicographically (alphabetical order). If one or both operands are non-strings, they are coerced to numbers first.
console.log(5 > "3"); // true ("3" is coerced to 3)
console.log("10" < "2"); // true (both are strings, so compared lexicographically)
console.log("10" < 2); // false ("10" is coerced to 10, compared to 2)
Summary Table
Operator | Example | Coercion Result | Explanation |
---|---|---|---|
+ |
5 + "3" |
"53" |
String concatenation (5 coerced to "5" ) |
- |
10 - "5" |
5 |
"5" coerced to number |
* |
4 * "3" |
12 |
"3" coerced to number |
/ |
"20" / 4 |
5 |
"20" coerced to number |
% |
10 % "3" |
1 |
"3" coerced to number |
&& |
"hello" && 0 |
0 |
"hello" is truthy; returns 0 as falsy |
` | ` | `"" | |
{% raw %}==
|
5 == "5" |
true |
"5" coerced to number |
=== |
5 === "5" |
false |
No coercion; different types |
> |
"10" > 5 |
true |
"10" coerced to number |
< |
"10" < "2" |
true |
Lexicographic comparison since both are strings |