Difference between == and ===
Advertisement
🧩 Scenario
Architecture Walkthrough
How == Performs Type Coercion
The == operator uses the Abstract Equality Comparison algorithm defined in the ECMAScript spec. When the two operands have different types, JavaScript converts one or both to a common type before comparing. The rules are non-trivial: numbers and strings, booleans and numbers, objects and primitives all trigger different conversion paths.
This means 0 == false is true because false is converted to the number 0 first. '' == false is also true for the same reason. [] == false is true because the array is converted to a string (""), then to a number (0), which equals false converted to 0. These results are legal but almost never what a developer intends.
How === Avoids Coercion
The === operator uses the Strict Equality Comparison algorithm. If the two operands have different types, the result is always false immediately, with no conversion. This makes === predictable: 5 === '5' is false because the types differ, regardless of value.
Strict equality is still subject to some nuances. NaN === NaN is false, because NaN is defined as not equal to itself. The correct check for NaN is Number.isNaN(value). And +0 === -0 is true, which is rarely a problem in practice but worth knowing.
The null and undefined Special Case
null == undefined is true under loose equality. The spec treats this as a special case: null and undefined are only loosely equal to each other, not to any other value. null == 0 is false. null == false is false. This special relationship is the one scenario where using == in production code is occasionally intentional: checking value == null catches both null and undefined in a single expression.
null === undefined is false under strict equality because they are different types. Understanding this distinction is a reliable interview signal because it shows you have read through the actual coercion rules rather than relying on intuition.
Key Code Explained
// Loose equality with type coercion
console.log(5 == '5'); // true — string coerced to number
console.log(0 == false); // true — false coerced to 0
console.log('' == false); // true — both coerce to 0
console.log([] == false); // true — [] -> '' -> 0, false -> 0
// Strict equality: no coercion
console.log(5 === '5'); // false — different types
console.log(0 === false); // false — different types
// The null/undefined special case
console.log(null == undefined); // true — special case in the spec
console.log(null === undefined); // false — different types
// NaN edge case
console.log(NaN === NaN); // false — NaN is never equal to itself
console.log(Number.isNaN(NaN)); // true — correct way to check for NaN
The [] == false line is the most commonly cited example of coercion going wrong. It passes through three separate type conversions before reaching the comparison. No reasonable developer would expect this to be true, which is exactly why == is avoided in most style guides and linters.
Tradeoffs
| Operator | Pro | Con |
|---|---|---|
| === (strict) | Predictable, no hidden conversions, lint-friendly | Slightly more verbose in rare null-check scenarios |
| == (loose) | value == null catches both null and undefined in one check | Coercion rules are complex and produce unintuitive results |
| Object.is() | Handles NaN and -0 correctly where === does not | Verbose for everyday comparisons, unknown to many developers |
What Interviewers Actually Check
- Whether you know that
==triggers type coercion and===does not - Whether you can predict surprising results like
0 == falseand[] == false - Whether you know the
null == undefinedspecial case and can explain it - Whether you know that
NaN === NaNisfalseand how to correctly check forNaN - Whether you can articulate a clear recommendation for production code
Follow-Up Questions
- What is
Object.is()and how does it differ from===forNaNand-0? - TypeScript enforces
===by default through itseqeqeqlinting rule. What problem is it solving? - How does the coercion in
==behave when comparing an object to a primitive? - If you are writing a utility function that accepts a value that might be
nullorundefined, how do you check for both in one expression? - A code review comment asks you to replace
value == nullwithvalue === null || value === undefined. Do you agree with the change?
Common Candidate Mistakes
- Not knowing that
null == undefinedistruebutnull === undefinedisfalse - Being surprised that
0, empty string, andfalseall loosely equal each other - Thinking
==only converts strings to numbers, when the full coercion algorithm handles many more cases - Using
==in conditional checks that compare API values where type is uncertain - Saying "always use ===" without being able to explain the one case where
==is intentionally useful
Interview Readiness Checklist
Before you leave this question, make sure you can answer:
- Can you explain the difference between abstract equality and strict equality in plain terms?
- Can you predict the output of
null == undefinedandnull === undefined? - Can you explain why
0 == falseevaluates totrue? - Can you describe at least one legitimate use case for
==in modern code? - Can you state the default recommendation for production code and justify it?
Summary
== and === both test equality, but they differ in whether they allow type conversion before the comparison. Loose equality (==) converts operands to a compatible type using a complex algorithm that produces results most developers would not predict. Strict equality (===) returns false immediately when types differ, making its behavior fully predictable.
The standard recommendation in modern JavaScript is to always use ===. The only common exception is value == null, which deliberately catches both null and undefined in one check because the spec treats them as loosely equal to each other and to nothing else.
Knowing the edge cases (NaN !== NaN, null == undefined, [] == false) is a reliable interview signal because it demonstrates you understand the underlying type system rather than just knowing which operator to use.
Should I ever use == ?
Avoid it. Always use === unless you explicitly need type coercion.
Advertisement
Stay Updated
Get the latest frontend challenges, interview questions and tutorials delivered to your inbox.
Advertisement