Chapters

FundamentalsChapter 20 of 21

Equality

Why === is the default and == is a chapter about history.

Two operators, one recommendation

=== compares without converting: same type and same value, or false. == converts first, then compares. Use === everywhere, and read this chapter so the other one holds no surprises.

JavaScript

JavaScript

console.log(5 === 5);
console.log(5 === '5');
console.log(5 == '5');

Output

true
false
true

What == does

When the types differ, == applies a conversion table. The results are consistent, and almost nobody carries the table in their head.

JavaScript

JavaScript

console.log(0 == '');
console.log(0 == '0');
console.log('' == '0');
console.log(null == undefined);
console.log(null == 0);

Output

true
true
false
true
false

Note the first three: 0 equals the empty string and equals "0", but those two are not equal to each other. Equality that is not transitive is a poor foundation for reasoning about code.

The one useful case

== null is true for both null and undefined and nothing else, which makes it a compact test for absent.

JavaScript

JavaScript

function check(value) {
  return value == null ? 'absent' : 'present';
}

console.log(check(null), check(undefined), check(0), check(''));

Output

absent absent present present

Even here, value === null || value === undefined says the same thing without relying on the reader knowing the table.

Objects compare by identity

Neither operator looks inside an object. Two objects are equal only when they are the same object.

JavaScript

JavaScript

const a = { id: 1 };
const b = { id: 1 };

console.log(a === b);
console.log(a == b);
console.log(a === { ...a });

Output

false
false
false

The two special cases

NaN is not equal to itself, and 0 and -0 are equal to each other. Object.is is a third comparison that treats both the way you would expect.

JavaScript

JavaScript

console.log(NaN === NaN);
console.log(Object.is(NaN, NaN));
console.log(0 === -0);
console.log(Object.is(0, -0));

Output

false
true
true
false

Tip

Use === by default, Number.isNaN to test for NaN, and Object.is only when the sign of zero genuinely matters. That covers everything.

Test yourself

2 questions

Why prefer === over ==

Show the answer

It compares without converting, so the result depends only on the values The conversion table behind == is not even transitive, which makes code using it hard to reason about.

What is the one common use for ==

Show the answer

value == null, which catches both null and undefined And even that can be written out explicitly with === for readers who do not know the rule.

Next chapter

Strict Mode

The safer dialect, why it exists, and where you already have it.