
Object.is() vs. Strict Equality in JavaScript

Most of the time, strict equality does exactly what we want:
valueA === valueBIt is familiar, concise, and far safer than the loose equality operator in ordinary application code.
That is why Object.is() can seem unnecessary at first. Why add another equality check if === is already the sensible choice?
The answer is that Object.is() behaves differently in two specific edge cases:
NaN- signed zero, meaning
+0and‑0
For day‑to‑day work, that difference is not constantly important. Still, understanding it makes your mental model of JavaScript equality much sharper.
Strict Equality is Still the Default Tool
Let us say that clearly first.
For most comparisons in front‑end code, === is exactly right:
const isAdmin = role === 'admin';const isPublished = status === 'published';const hasSameId = currentId === selectedId;Nothing about Object.is() changes that.
The interesting part is what happens at the edges.
NaN breaks the obvious expectation
This is the first strange case:
console.log(NaN === NaN);That returns false.
If you have not met this before, it feels absurd. The same value does not equal itself?
With Object.is():
console.log(Object.is(NaN, NaN));the result is true.
That is one of the main reasons the method exists.
Signed Zero is the Other Difference
JavaScript distinguishes between +0 and ‑0 in certain low‑level numeric situations.
Strict equality treats them as the same:
console.log(+0 === -0);That returns true.
Object.is() does not:
console.log(Object.is(+0, -0));That returns false.
If you rarely work with signed zero directly, this may seem almost comically niche. In much everyday code, it is. But it is still part of the language's equality story.
Everywhere Else, the Behaviour Matches What You Would Expect
For ordinary values:
console.log(Object.is(3, 3));console.log(Object.is('hello', 'hello'));console.log(Object.is(true, true));console.log(Object.is({}, {}));the results are broadly in line with strict equality expectations:
- primitives compare by value
- separate object references are not equal
So the real distinction is not that Object.is() reinvents equality completely. It refines it in a couple of awkward places.
It is Also Worth Separating This from Loose Equality
Because JavaScript has more than one comparison style, people can end up mentally blending the wrong things together.
Object.is() is not an alternative to loose equality in the way === is. It is not there to help with coercive comparisons such as:
0 == '0';That is a completely different discussion.
The useful mental split is:
==performs coercion and is best avoided in most application code===is the normal strict comparison toolObject.is()is a more exact sameness check for a couple of unusual edge cases
Once you keep those roles separate, the method feels far less mysterious.
Why NaN matters more than ‑0 for most developers
You are much more likely to encounter NaN in practical JavaScript:
- failed parsing
- invalid maths
- division‑related bugs
- unexpected input conversion
That means Object.is() occasionally becomes useful when you are doing very deliberate numeric work and want an equality‑style check that treats NaN as matching itself.
Even so, when the goal is specifically "is this value NaN?", Number.isNaN() is usually a clearer tool than Object.is(value, NaN).
The Signed Zero Case Matters Mainly in Technical Code
Most product‑facing UI logic will never care whether a zero is positive or negative. If you are showing a shopping basket total or checking whether a field is empty, +0 versus ‑0 is not the battle you are fighting.
Where it can matter is in lower‑level numeric work, calculations that preserve sign, or code that is intentionally mirroring the language's exact sameness semantics. That is why Object.is() tends to feel more relevant in library code than in ordinary business rules.
So when would you use Object.is() in real code
A few cases stand out:
- low‑level equality helpers
- memoisation or caching logic
- change‑detection code
- library internals where exact sameness rules matter
For example, if a utility needs to know whether two values are identical under the language's most precise sameness rules, Object.is() is a sensible choice.
That is partly why you see it discussed in relation to framework internals and state comparison logic.
What Object.is() is not
It is not:
- a deep equality function
- a replacement for everyday
===comparisons - a magical object comparison helper
This still returns false:
console.log(Object.is({ name: 'Ellie' }, { name: 'Ellie' }));The two objects are different references.
That point is worth stressing because people sometimes see the method name and assume it must somehow compare object contents. It does not.
This is Really About Precision, Not Convenience
=== is convenient and usually correct.
Object.is() is slightly more precise in a very specific technical sense.
That precision matters when the edge cases matter. Otherwise, it can just be unnecessary noise.
If a comparison is about ordinary strings, booleans, IDs, or status values, === keeps the code simpler. Replacing all equality checks with Object.is() would usually make the codebase feel more self‑conscious without improving it.
A Good Rule of Thumb
Use === by default.
Reach for Object.is() when:
- you explicitly care about
NaNcomparing equal to itself - you need to distinguish
+0from‑0 - you are implementing low‑level comparison behaviour rather than ordinary business logic
That is the honest place for the method.
Understanding It is Still Worthwhile
Even if you do not use Object.is() every week, knowing about it sharpens how you think about JavaScript equality overall.
It reminds us that equality is not one giant simple idea in the language. There are a few subtly different comparison rules, and they exist because the awkward corners of numbers forced the language to make choices somewhere.
Seen that way, Object.is() is less a competing equality operator and more a precise diagnostic tool for sameness.
And in JavaScript, it is usually worth knowing where the sharp edges live, even if you do not touch them often.
Related Articles

What is CORS and Why is My JavaScript fetch Blocked? What is CORS and Why is My JavaScript

Check If Three Values are Equal in JavaScript. Check If Three Values are Equal in JavaScript

The Difference Between == and === in JavaScript. The Difference Between
==and===in JavaScript
Check If a String Contains Only Whitespace with JavaScript. Check If a String Contains Only Whitespace with JavaScript

What are CSS Preprocessors, and Why Should You Use Them? What are CSS Preprocessors, and Why Should You Use Them?

Throttling vs. Debouncing in JavaScript: Managing Event Frequency. Throttling vs. Debouncing in JavaScript: Managing Event Frequency

Understanding prototype.apply() in JavaScript. Understanding
prototype.apply()in JavaScript
What is a Static Site Generator? What is a Static Site Generator?

Spread Syntax in JavaScript (...). Spread Syntax in JavaScript (
...)
Tagged Template Literals in JavaScript. Tagged Template Literals in JavaScript

JSON.parse() and JSON.stringify() Explained for Beginners. JSON.parse()andJSON.stringify()Explained for BeginnersDisabling Source Maps in Gatsby for Production. Disabling Source Maps in Gatsby for Production