Why === Isn’t Enough: Mastering Precise Equality with Object.is() in JavaScript
While the strict equality operator (===) works well for most cases, it fails with special values like NaN and distinguishes +0 and -0 incorrectly; JavaScript’s Object.is() method provides a more precise same‑value equality, correctly handling these edge cases and improving comparisons in Maps, Sets, and other structures.
Strict Equality (===) in JavaScript
The === operator checks both value and type without performing type conversion. In the majority of situations it behaves as expected:
'1' === 1; // false (different types)
true === 1; // false (different types)
null === undefined; // false (different types)However, two special cases expose its limitations.
Problem 1: NaN Self‑Inequality
According to the IEEE‑754 standard, NaN is not equal to any value, including itself: NaN === NaN; // false This makes checking for NaN cumbersome, especially when using array methods like indexOf or includes (pre‑ES6) which rely on ===.
Problem 2: Positive Zero vs. Negative Zero
JavaScript represents zero as two distinct values, +0 and -0, which can have different meanings in low‑level contexts such as graphics. Yet === treats them as identical: -0 === +0; // true For most applications this is acceptable, but high‑precision calculations may require a distinction.
Object.is(): Same‑Value Equality
ECMAScript introduced Object.is() to provide a stricter equality comparison, often called “same‑value equality”. Its behavior matches === in most cases, but differs for NaN and signed zeros.
In the vast majority of scenarios, Object.is(a, b) yields the same result as a === b . The only differences lie in how it treats NaN and -0 / +0 .
How Object.is() Solves the Issues
NaN Equality : Object.is(NaN, NaN) returns true, making NaN checks straightforward. Object.is(NaN, NaN); // true Signed Zero Distinction : Object.is(-0, +0) returns false, correctly differentiating the two.
Object.is(-0, +0); // false
Object.is(0, 0); // truePractical Usage
Many newer JavaScript features already rely on Object.is() for internal equality checks, such as key matching in Map and value storage in Set. It is not a replacement for === but a complementary tool for edge‑case handling.
Recommended practice:
Use === for everyday comparisons – it is fast, reliable, and sufficient for 99 % of cases.
When dealing with NaN or needing to differentiate +0 and -0, switch to Object.is().
Conclusion
Understanding the subtle differences between === and Object.is() enables developers to write more accurate comparison logic, avoid bugs in numeric edge cases, and leverage the full power of JavaScript’s equality semantics.
JavaScript
Provides JavaScript enthusiasts with tutorials and experience sharing on web front‑end technologies, including JavaScript, Node.js, Deno, Vue.js, React, Angular, HTML5, CSS3, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
