Difference between == and ===

Beginner6 min interview
Skills tested:
Type coercion mechanicsAbstract equality comparison algorithmStrict equality vs loose equalitynull and undefined equality edge casesTruthy and falsy value coercion

Advertisement

🧩 Scenario

In a real codebase, you will encounter this when reading or writing conditional checks that compare values from different sources such as API responses, form inputs, and URL parameters, where types are often inconsistent. Using the wrong equality operator in these cases silently passes values through that should have been rejected, leading to bugs that are hard to reproduce.

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

OperatorProCon
=== (strict)Predictable, no hidden conversions, lint-friendlySlightly more verbose in rare null-check scenarios
== (loose)value == null catches both null and undefined in one checkCoercion rules are complex and produce unintuitive results
Object.is()Handles NaN and -0 correctly where === does notVerbose 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 == false and [] == false
  • Whether you know the null == undefined special case and can explain it
  • Whether you know that NaN === NaN is false and how to correctly check for NaN
  • Whether you can articulate a clear recommendation for production code

Follow-Up Questions

  1. What is Object.is() and how does it differ from === for NaN and -0?
  2. TypeScript enforces === by default through its eqeqeq linting rule. What problem is it solving?
  3. How does the coercion in == behave when comparing an object to a primitive?
  4. If you are writing a utility function that accepts a value that might be null or undefined, how do you check for both in one expression?
  5. A code review comment asks you to replace value == null with value === null || value === undefined. Do you agree with the change?

Common Candidate Mistakes

  • Not knowing that null == undefined is true but null === undefined is false
  • Being surprised that 0, empty string, and false all 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 == undefined and null === undefined?
  • Can you explain why 0 == false evaluates to true?
  • 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.

Related Videos
Watch these videos to learn more about this topic
Frequently Asked Questions

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