Object.is Equality (SameValue)
`Object.is` performs JavaScript’s SameValue comparison. Unlike `===`, it treats `NaN` as equal to itself and distinguishes `+0` from `-0`.
`Object.is(a, b)` compares two values using the SameValue algorithm. For most primitive values and object references, its behavior matches strict equality (`===`), but there are two important numeric differences.
First, `Object.is(NaN, NaN)` is `true`, whereas `NaN === NaN` is `false`. Second, `Object.is(+0, -0)` is `false`, whereas `+0 === -0` is `true`.
For objects, arrays, and functions, `Object.is` compares references rather than their contents. Two separately created objects with identical properties are therefore not the same value.
`Object.is` is useful when exact JavaScript value identity matters, particularly when code must preserve the distinction between signed zero or recognize `NaN` as the same value. It does not perform coercion, so values of different types are not converted before comparison.
Key points
- Uses SameValue semantics without type coercion.
- `NaN` is equal to itself under `Object.is`.
- `+0` and `-0` are considered different.
- Objects are equal only when both operands reference the same object.
- For most ordinary values, `Object.is` and `===` produce the same result.
Interview questions
What is the difference between `Object.is` and `===`?
Both perform non-coercing comparisons, so they agree for most values. The key difference is that `Object.is(NaN, NaN)` returns `true`, while `NaN === NaN` returns `false`. They also differ for signed zero: `Object.is(+0, -0)` is `false`, while `+0 === -0` is `true`. For object references, both use reference identity.
Why does `Object.is(NaN, NaN)` return true?
`NaN` represents an invalid or undefined numeric result, but JavaScript gives it special comparison behavior under strict equality. With `===`, `NaN` is not equal to itself. `Object.is` uses SameValue semantics, which explicitly treats `NaN` as equal to `NaN`. This makes it possible to test whether two values are both `NaN` without a separate `Number.isNaN` check.
Why does `Object.is(+0, -0)` return false?
JavaScript numbers can represent both positive zero and negative zero. They compare as equal under `===`, but SameValue preserves the sign distinction. Therefore `Object.is(+0, -0)` returns `false`. This distinction can matter in numerical code where the sign of zero carries information.
How does `Object.is` compare objects?
Objects are compared by reference identity rather than by their properties. Two separately created objects are different values even if they contain exactly the same data. If two variables point to the same object, `Object.is` returns `true`. This is the same reference-based behavior used by `===` for objects.
Where does SameValueZero differ from `Object.is`?
Both SameValue and SameValueZero consider `NaN` equal to itself. Their difference is signed zero: SameValue distinguishes `+0` from `-0`, while SameValueZero considers them equal. This distinction is relevant because different JavaScript operations use different equality algorithms. For example, `Array.prototype.includes` uses SameValueZero semantics.