This is the comparison operator recommended everywhere, and rightly so. It still holds two surprises: a number that is not equal to itself, and two identical objects the language calls different.
Definition
Strict equality, written with three equals signs, compares two values without performing any conversion. When the types differ, the answer is immediately false, without even looking at the contents.
console.log("2" === 2); // false: string against a number
console.log(2 === 2); // true
console.log(null === undefined); // false
// The opposite is written !==
console.log("2" !== 2); // trueThis is exactly what separates it from Loose equality (==), which converts before comparing and produces results that are hard to predict. The rule agreed across the profession fits in one sentence: always use three equals signs, except in the one case described on the loose equality page.
The two values that escape the rule
Two cases defy intuition, and both come from the floating-point number standard.
console.log(NaN === NaN); // false
console.log(0 === -0); // true
// The right way to test each of them
console.log(Number.isNaN(NaN)); // true
console.log(Object.is(0, -0)); // falseNaN stands for a numeric calculation that failed, and two failures have no reason to be the same failure: it equals nothing, not even itself. Negative zero, on the other hand, is genuinely distinct from positive zero in memory, yet strict equality merges them.
Object.is answers exactly like strict equality, apart from those two exceptions, which it handles the other way round. Useful there, pointless elsewhere.
Objects are compared by address
Here is the point that costs beginners the most time. On an object, an array or a function, the operator does not look at the contents: it asks whether this is the same instance in memory.
const a = [1, 2];
const b = [1, 2];
const c = a;
console.log(a === b); // false: two separate arrays
console.log(a === c); // true: the same array
// Comparing contents takes another approach
console.log(JSON.stringify(a) === JSON.stringify(b)); // trueThat last line helps on simple data, but it depends on key order and handles neither dates nor functions. For a serious comparison, write a dedicated function or reach for a library.
Frequently asked questions
Should === always be preferred over ==?
Yes, with one exception. Writing value == null tests null and undefined in one go, which is genuinely handy. Everywhere else, three equals signs avoid invisible conversions that produce bugs which are very hard to track down.
How do I compare two objects on their contents?
By comparing their properties one by one, something no operator in the language does for you. On flat structures, a loop over the keys is enough. On nested structures, the comparison turns recursive and deserves a well-tested function rather than something written in a hurry.
Why does 0.1 + 0.2 === 0.3 return false?
Because the addition does not yield exactly 0.3 but a very slightly larger value, a consequence of how decimals are encoded in binary. The operator itself is doing its job correctly. To compare decimals, check that the absolute gap stays below a small tolerance.