Triple Equals vs Double Equals in JavaScript
In JavaScript, there are technically 4 different ways of comparing whether 2 values are equal. The 2 most common ways are the ==
operator and the ===
operator, also known as abstract equality comparison and strict equality comparison.
Strict Equality With ===
Given 2 values x
and y
, here's how JavaScript checks whether x === y
:
- Check the types of
x
andy
. If they are different types, returnfalse
. - If
x
andy
are numbers, first check if eitherx
ory
isNaN
, and returnfalse
if one isNaN
. If bothx
andy
are either+0
or-0
, returntrue
. Otherwise, check to see if they are the same number. - If
x
andy
are bothnull
or bothundefined
, returntrue
. - If
x
andy
are both booleans, both strings, or both symbols, compare them by value. - If
x
andy
are both objects, return true if and only if they reference the same object.
In short, here are the important details of ===
:
- No implicit type coercions.
===
doesn't callvalueOf()
or do anything else to try to convert objects to primitives. - No value is
=== NaN
. You should not use===
to check forNaN
, useNumber.isNaN()
instead. - Object comparison is by reference - two different objects can contain the exact same keys, but
===
will still say they're different.
const obj1 = { answer: 42 };
const obj2 = { answer: 42 };
obj1 === obj2; // false
Abstract Equality With ==
The ==
operator uses a more complex abstract equality comparison algorithm to compare whether x
and y
are equal. Here's a brief overview:
- If
x
andy
are the same type, check ifx === y
. - If
x
andy
are both eithernull
orundefined
, returntrue
. - If
x
is a number andy
is a string, converty
to a number and then compare using===
. Similarly, ifx
is a boolean or string, andy
is a number, convertx
to a number. - If
x
ory
is a boolean, convert the other value of a number and compare them. - If
x
is an object andy
is a symbol, string, or number, try to convertx
to a primitive usingvalueOf()
and then compare using===
.
Abstract equality comparison is responsible for many of the strange edge cases that JavaScript is so famous for.
' ' == 0; // true
' ' == false; // true
({ valueOf: () => 42 }) == 42; // true
({ valueOf: () => 0 }) == false; // true
In general, you should always use ===
rather than ==
unless you're sure
you know what you're doing. There is one neat functional use for ==
: checking for null
or undefined
(so-called nullish values) with a single check:
// Only true if `v === null` or `v === undefined`
v == null;
// Equivalent:
v === null || v === undefined;
Checking if v == null
is a more concise way of checking if v
is strictly
equal to null
or undefined
. You may choose to do this if you're a more
advanced JavaScript developer, but there is no harm in always using ===
.
ESLint has a rule to disallow ==
unless the right hand side is null
,