Type Coercion and == vs ===
How JavaScript converts types implicitly, and why === is almost always the comparison you want.
2 min read
JavaScript will silently convert values from one type to another when an operator needs it to — this is type coercion, and it's the source of some of the language's most notorious surprises.
== coerces, === doesn't
== (loose equality) converts both sides to a common type before comparing. === (strict equality) compares the type and the value with no conversion at all.
"1" == 1 // true -- string coerced to number
"1" === 1 // false -- different types, no coercion
null == undefined // true -- special-cased to equal each other
null === undefined // false
0 == false // true -- both coerce to 0
"" == false // true -- both coerce to 0/emptyThese coercion rules aren't intuitive to memorize, and getting them wrong produces bugs that are hard to spot. The practical fix: use === and !== by default, always. It's predictable — no type gets silently converted, so a comparison either genuinely matches or it doesn't.
Truthy and falsy values
Outside of explicit comparisons, JavaScript also coerces values to true or false wherever a boolean is expected — an if condition, a while loop, the ! operator. Exactly six values are falsy; everything else is truthy:
// Falsy -- these six values only:
false, 0, -0, "", null, undefined, NaN
// Truthy -- everything else, including:
"0", "false", [], {}, " "The two most common surprises: an empty array [] and an empty object {} are both truthy, and the string "0" is truthy (only the number 0 is falsy).
if ([]) {
console.log("this runs -- [] is truthy");
}Coercion in practice
The + operator coerces toward strings if either side is a string; other arithmetic operators coerce toward numbers:
"5" + 1 // "51" -- + prefers string concatenation
"5" - 1 // 4 -- - only makes sense for numbers, so it coerces
"5" * "2" // 10 -- both sides coerced to numbersThe rule to keep
You can't avoid coercion entirely — truthy/falsy checks are genuinely useful shorthand (if (user.name) instead of if (user.name !== "")). What you should avoid is ==. There's essentially no situation where loose equality's coercion rules do something you actually want that === combined with an explicit conversion wouldn't do more clearly.
With the fundamentals of values covered, the next lessons move into controlling how a program flows: conditionals and loops.