Equality Operators (=== and ==)
Strict equality (===) never coerces types; loose equality (==) coerces one side according to a specific set of rules.
a === b / a == b
Purpose
=== (strict equality) compares type and value with no conversion. == (loose equality) converts
one or both sides to a common type first, following a specific set of rules, then compares. ===
is the recommended default because its behavior needs no memorized rule list.
Syntax
5 === 5; // true
5 === '5'; // false โ different types, no coercion
5 == '5'; // true โ '5' is coerced to 5 first
Behavior notes
Selected == coercion rules worth knowing exist, even if you default to ===:
| Comparison | Result | Rule |
|---|---|---|
0 == false |
true |
Boolean is coerced to a number. |
"" == false |
true |
Both sides coerce toward 0/false. |
null == undefined |
true |
Special-cased; true only for each other. |
null == 0 |
false |
null does not coerce to 0. |
NaN == NaN |
false |
NaN never equals anything, == or ===. |
Object.is(a, b) is a third comparison, rarely needed, that differs from === only for NaN
(Object.is(NaN, NaN) is true) and signed zero (Object.is(0, -0) is false).
Common mistakes
- Treating
==as โa more forgiving===โ rather than a specific, sometimes counterintuitive rule table โnull == 0beingfalsesurprises people expecting a general leniency. - Using
===(or==) to check forNaN. UseNumber.isNaN(x)instead.
Runtime notes
Both operators and their coercion rules are defined by ECMAScript and behave identically everywhere.