Skip to main content

Loose (==) vs strict (===) equality in JavaScript

== is loose equality, which first coerces both operands to a common type, while === is strict equality, which demands the same type and the same value. One extra character changes the result: 0 == false is true, but 0 === false is false.

Theory

TL;DR

  • == converts types before comparing, === converts nothing.
  • With ===, a true result is only possible when type and value both match.
  • null == undefined is true, but null === undefined is false.
  • The coercion rules behind == are not obvious, which is exactly where bugs with user input or API data come from.
  • The de facto standard: === and !== everywhere, and == only in the form value == null.

Quick example

javascript
console.log(5 == '5'); // true, the types were coerced console.log(5 === '5'); // false, number versus string console.log(0 == false); // true, false becomes 0 console.log(0 === false); // false, number versus boolean

The == operator, loose (abstract) comparison

== converts the types of the operands before comparing them. In other words, JavaScript tries to "guess" whether the values are equal after type coercion.

Examples:

javascript
5 == '5' // true -> the string '5' turns into the number 5 0 == false // true -> false is coerced to 0 null == undefined // true -> this is the only case where they are equal ' ' == 0 // true -> a whitespace string turns into 0

The danger: implicit conversions are a frequent source of bugs, especially when checking user input or data coming from an API.

The === operator, strict comparison

=== performs no type conversion. The operands must have the same type and the same value for the result to be true.

Examples:

javascript
5 === '5' // false -> different types (number and string) 0 === false // false -> different types null === undefined // false -> different types 5 === 5 // true -> same value and same type

How == actually coerces

The list of rules is short, yet almost nobody remembers it by heart, and that is the main argument against ==:

  1. If the types match, plain strict comparison runs.
  2. null and undefined are equal to each other and to nothing else.
  3. Number versus string: the string is converted to a number.
  4. A boolean on either side becomes a number first (true gives 1, false gives 0).
  5. Object versus primitive: the object is reduced to a primitive via valueOf() or toString().
javascript
[] == false; // true, [] becomes '', then 0, and false is 0 too [1] == 1; // true, [1] becomes '1', then 1 '0' == false; // true, both are reduced to 0 '0' === false; // false

Neither operator helps in two special cases: NaN is not equal to itself, and +0 and -0 count as equal. Object.is() exists for exactly those situations.

javascript
NaN === NaN; // false Object.is(NaN, NaN); // true Object.is(0, -0); // false

Summary: when to use which

OperatorCoerces typesTypical use
=== / !==noalmost always, the default for any check
== / !=yesonly deliberately, as value == null
Object.is()nowhen NaN or the sign of zero must be distinguished

Recommendation: always use === (and !==) unless there is a specific reason for loose comparison. It makes the code predictable and cuts down the number of bugs. The one exception that even strict linters allow is if (value == null), because it covers both null and undefined in a single short check.

Common mistakes

  • Checking form or API data with ==. Input always arrives as a string, so '0' == false is true and the condition fires in a way nobody intended.
  • Assuming === compares object contents. For objects both operators compare references: {} === {} is false.
  • Writing x == NaN. No comparison against NaN ever returns true, you need Number.isNaN(x).
  • Using == null without understanding it. It is a deliberate check for null and undefined together, not a "less strict" emptiness check: 0 and '' do not pass it.
  • Confusing == with =. A single sign is an assignment inside the condition, and it is always truthy for a non-zero value.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.