===) vs. Loose Equality (==)JavaScript comparison operators test two values and return a boolean (true or false). Always default to strict equality (=== and !==) because loose equality (== and !=) converts types silently before comparing.
Strict equality checks whether both operands share the exact same type and value. Loose equality triggers implicit coercion rules that surprise even senior engineers, such as "" == 0 returning true.
flowchart TD
Compare["Compare a and b"] --> Strict{"Using === ?"}
Strict -- "Yes" --> SameType{"Same type?"}
SameType -- "No" --> FalseRes["Return false immediately"]
SameType -- "Yes" --> ValCheck["Compare values directly"]
Strict -- "No (==)" --> Coerce["Apply implicit type coercion rules"]
Object.is()Relational operators (<, >, <=, >=) compare numeric magnitudes reliably when both sides are numbers. However, comparing numeric strings uses UTF-16 character order, so "10" < "2" evaluates to true. Always convert string inputs with Number() before checking ranges or sorting values.
When both sides of a relational check are strings, JavaScript compares character codes from left to right. Comparing a number against a string converts the string into a number, so "10" > 2 becomes true, whereas "abc" > 2 becomes NaN and returns false.
For edge cases involving NaN or -0, ES6 provides Object.is(a, b), which treats NaN as equal to NaN and distinguishes +0 from -0.
console.log("Strict 5 === '5':", 5 === "5"); // false
console.log("Loose 5 == '5':", 5 == "5"); // true (avoid!)
console.log("Strict !==:", 0 !== false); // true
// Explicit nullish check
const token = undefined;
console.log("Missing token:", token === null || token === undefined);
// Object.is handles NaN cleanly
console.log("Object.is(NaN, NaN):", Object.is(NaN, NaN)); // true
"12" > "2" evaluates to false because "1" comes before "2" alphabetically. Convert strings with Number() first.===: { id: 1 } === { id: 1 } is false because they live at different memory addresses. Compare their id fields directly.1 < x && x < 10 works properly, whereas 1 < x < 10 evaluates 1 < x to a boolean (true or false) and then compares 1 < 10 or 0 < 10!== in modern JavaScript?The only common exception in some style guides is value == null, which matches both null and undefined. Even then, value === null || value === undefined is clearer for beginners.
[] == false evaluate to true?Loose equality converts false to 0 and [] to "", then converts "" to 0, making 0 == 0 true. Strict [] === false safely returns false.
Use strA.localeCompare(strB) instead of relational operators, because localeCompare() handles uppercase, lowercase, and accents properly.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.