None of the three coerces types: different types are never equal. They differ on exactly two inputs.
| Algorithm | NaN vs NaN |
+0 vs -0 |
Used by |
|---|---|---|---|
| IsStrictlyEqual | not equal | equal | ===, !==, switch, indexOf, lastIndexOf |
| SameValue | equal | not equal | Object.is, property redefinition checks (Object.defineProperty) |
| SameValueZero | equal | equal | includes, Map keys, Set values |
Everything else matches: two Strings are equal when their code units match, two BigInts when their values match, and objects, symbols, null, undefined and Booleans compare by identity or value as you would expect.
Practical consequences:
[NaN].indexOf(NaN)is-1but[NaN].includes(NaN)istrue.- A
MaporSettreatsNaNas one key. It also treats-0and+0as the same key (the spec's key canonicalization turns-0into+0first). Object.is(0, -0)isfalse; use it when the sign matters (for example, detecting-0fromMath.round(-0.4)).- Use
Number.isNaN(x)orObject.is(x, NaN)to test forNaN, neverx === NaN.
=== stays the default for application code. Reach for Object.is when you need a precise "same value" test and for includes when searching arrays that may contain NaN.