Glossary / Object.is

Object.is

Object.is(a, b) compares two values using ECMAScript’s SameValue algorithm. It is close to strict equality, but deliberately resolves two Number edge cases differently: it considers NaN equal to itself and distinguishes positive zero from negative zero. Objects and functions are still compared by reference identity. It is useful when those exact numeric distinctions matter, but it is not a structural equality operation.

Comparison table

Values === Object.is Why
NaN, NaN false true NaN is unequal under ordinary Number strict equality.
0, -0 true false Signed zero is distinguished by SameValue.
two object literals with same fields false false References differ.

Map and Set use SameValueZero rather than SameValue: like Object.is it equates NaN, but like === it treats +0 and -0 as equal. This detail matters when porting comparison assumptions into caches or set membership.

Object.is(NaN, NaN); // true
Object.is(0, -0);    // false
Object.is({}, {});   // false

When it matters

Libraries may use Object.is-style equality for memoization or state-change detection. If an object is mutated in place, its identity remains the same and shallow comparison can miss the change. If an equivalent object is reconstructed, identity changes even when fields do not. For domain equality, compare stable identifiers or explicitly selected fields; deep-equality libraries must define behavior for cycles, prototypes, Symbols, accessors, and special numeric values.

Interview questions

  1. How does Object.is differ from ===? It equates NaN with itself and distinguishes positive from negative zero.
  2. Does it deep-compare objects? No; objects compare by identity.
  3. How does Map differ? Map uses SameValueZero: NaN matches NaN, but signed zeros are treated as the same key.
  4. Why can mutation break memoization? The object reference stays identical even though nested state changed.

References