Most JavaScript programmers are aware that “normal” equality (==) should be avoided in favor of strict equality (===) [1]. However, every now and then you need something even stricter than ===: If you want to check for NaN or if you want to distinguish between -0 and +0. This blog post explains the details and ECMAScript.next’s [2] solution, the “is” operator.
x = xThat law doesn’t hold for === and NaN:
> NaN === NaN falseAs a consequence, you can’t find NaN in arrays via indexOf, because that method relies on === to determine which array elements are equal to its first argument:
> [ NaN ].indexOf(NaN) -1If you can’t use === to check for NaN, what is the alternative? There is the global function isNaN(), but it is problematic, because it converts its argument to number and thus returns true for many values that clearly are not NaN [3]:
> isNaN("foo") trueExplanation: "foo" converted to number is NaN.
> Number("foo") NaNOne way to detect NaN is to exploit the fact that it is the only value that isn’t strictly equal to itself:
function myIsNaN(value) { return value !== value; }A more self-explanatory alternative is to use isNaN() after checking whether the value is a number. This avoids the problematic conversion of non-numbers [3].
function myIsNaN2(value) { return typeof value === 'number' && isNaN(value); }ECMAScript.next will have Number.isNaN(), a fixed version of the global isNaN().
> -0 === +0 trueHow can you make the distinction? It turns out that you can divide by zero in JavaScript. If the number is positive and you divide it by −0, the result is -Infinity. If you divide it by +0, the result is Infinity. Conveniently, the two infinities can be distinguished by ===:
> 1 / -0 -Infinity > 1 / +0 Infinity > Infinity === -Infinity false
> NaN is NaN true > -0 isnt +0 trueThe operator is complemented by a function Object.is() that can be back-ported to older versions of ECMAScript. On those versions, it could be implemented as follows (a slightly edited version of the ECMAScript.next proposal):
Object.is = function(x, y) { if (x === y) { // x === 0 => compare via infinity trick return x !== 0 || (1/x === 1/y); } // x !== y => return true only if both x and y are NaN return x !== x && y !== y; };
Egal is the obsolete Norman term for equal, and Égalité is the French word for social equality.