Type Coercion and Equality
== vs ===
JavaScript has two equality operators. The strict equality operator (===) compares both value and type without any conversion. The loose equality operator (==) first coerces operands to a common type, then compares. This coercion produces surprising results.
console.log(0 == false); // true
console.log(0 === false); // false
console.log("" == false); // true
console.log(null == undefined); // true
console.log(null === undefined); // false
console.log(1 == "1"); // true
console.log(1 === "1"); // falseAlways use === and !==. Reserve == only for the deliberate null == undefined check (catches both null and undefined at once). Loose equality's coercion rules are complex enough that even experienced developers get them wrong.
Implicit Type Coercion
JavaScript also coerces types in arithmetic and string contexts. The + operator is overloaded: when either operand is a string it concatenates; otherwise it adds numbers.
console.log("5" + 3); // "53" (string concatenation)
console.log("5" - 3); // 2 (numeric subtraction)
console.log(true + 1); // 2
console.log(false + 1); // 1
console.log(null + 1); // 1
console.log(undefined + 1); // NaNTruthy and Falsy
Every value in JavaScript is either truthy or falsy. The falsy values are: false, 0, "" (empty string), null, undefined, NaN, and 0n. Everything else is truthy.
if (0) console.log("runs"); // skipped
if ("") console.log("runs"); // skipped
if ("0") console.log("runs"); // runs! "0" is truthy
if ([]) console.log("runs"); // runs! empty array is truthy