AV
HomeAboutProjectBlog

© 2026 Ave syah Shina. All rights reserved.

  1. Home
  2. Blog
  3. 06 — Equality — == vs === vs Object.is, and Four Algorithms

06 — Equality — == vs === vs Object.is, and Four Algorithms

August 13, 20265 min read
Download as Markdown

"Always use triple equals, move on" was my equality strategy, and it worked until it couldn't explain an edge case. The idea that everything else hangs off: there isn't one equality in JavaScript, there are four algorithms under the hood, and ==, ===, and Object.is each pick a different one — differing only on two edge cases. [1]

The framing that finally landed is the ladder of strictness. Reading from loosest to strictest:

algorithm NaN vs NaN +0 vs -0 == (loose) coerces types before comparing false true === (strict) no coercion; types must match false true SameValueZero used by Map, Set, Array.includes true true SameValue — Object.is() strictest; distinguishes the two zero signs true false

The two operators

== (loose equality) compares two values, performing type coercion if the types differ [2]. "5" == 5 is true because the string is converted to a number first. null == undefined is true (a special-case pair). This is the operator that produces "surprising" results — "0" == false is true, "" == 0 is true — because the Abstract Equality Comparison algorithm coerces both sides through a fixed set of rules. My rule is simple: never write ==. The surprises aren't worth the keystroke.

=== (strict equality) compares without coercion [3]. If the types differ, it returns false immediately. Same type, compare values directly. The one famous wrinkle: NaN === NaN is false, and +0 === -0 is true. This is the default for almost all equality checks.

The reason === wins isn't that it's stricter for its own sake — it's that the result is predictable. With == I had to hold the coercion table in my head; with === the question "are these the same type and value?" answers itself.

Object.is — the strictest

Object.is() is the fourth algorithm, SameValue [4]. It behaves like === except it fixes the two edge cases the spec calls out:

  • Object.is(NaN, NaN) → true (where NaN === NaN is false)
  • Object.is(+0, -0) → false (where +0 === -0 is true)

In normal code these differences almost never matter — but when they do, Object.is is the only correct tool. The classic case is NaN: x === NaN is always false, so the idiomatic check is Number.isNaN(x) or, equivalently, Object.is(x, NaN).

SameValueZero — the one you can't call directly

The fourth algorithm, SameValueZero, is the same as Object.is except it treats +0 and -0 as equal [5]. It's not exposed as a function — it's used internally by Map key comparison, Set membership, and Array.prototype.includes(). That's why [NaN].includes(NaN) is true but [NaN].indexOf(NaN) is -1 (indexOf uses ===). When a Set says "I already have this value," it's using SameValueZero under the hood.

The practical upshot: collection lookups are slightly smarter than ===. If I'm checking whether a value is in an array and NaN is a possibility, arr.includes(x) is correct where arr.indexOf(x) !== -1 is not.

How I use this

The rules I actually apply: default to === for every comparison; reach for Object.is only when NaN or signed-zero is genuinely in play (and Number.isNaN for the NaN check reads cleaner); never write ==; and remember that Array.includes, Set, and Map use SameValueZero, which is more forgiving than === on NaN. That covers 100% of the equality decisions in real code. The four-algorithm view matters because it explains why the four differ — and once I could see the two edge cases (NaN and signed zero) as the only variables, equality stopped being a source of doubt.

References

[1] Mozilla, "Equality comparisons and sameness," MDN Web Docs, 2024. [Online]. Available: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness

[2] Mozilla, "Equality (==) operator," MDN Web Docs, 2024. [Online]. Available: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality

[3] Mozilla, "Strict equality (===) operator," MDN Web Docs, 2024. [Online]. Available: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality

[4] Mozilla, "Object.is() — same-value equality," MDN Web Docs, 2024. [Online]. Available: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is

[5] Mozilla, "Same-value-zero equality," MDN Web Docs, 2024. [Online]. Available: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness#same-value-zero_equality

Knowledge check · Question 1 of 5

Why is `==` generally avoided in favor of `===`?

Comments

Leave a Comment

You must be signed in to comment

0 Comments

No comments yet. Be the first to comment!