# Stricter Equality in JavaScript: ECMAScript.next's Solution

# Stricter Equality in JavaScript: ECMAScript.next's Solution

Join the DZone community and get the full member experience.

Join For FreeDeploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

### Checking for NaN

NaN is not strictly equal to itself, breaking the fundamental law of reflexivity: In mathematics, any value x is always equal to itself:

x = x

That law doesn’t hold for === and NaN:

> NaN === NaN false

As 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) -1

If 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") true

Explanation: "foo" converted to number is NaN.

> Number("foo") NaN

One 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().

### Distinguishing between -0 and +0

This use case is rare, but sometimes you might want to distinguish between -0 and +0 – which are distinct values in JavaScript. === does not let you do that:
> -0 === +0 true

How can you make the distinction? It turns out that there is one number that you can divide by 0 – the number 1. Dividing 1 by -0 results in -Infinity, dividing it by +0 results in Infinity. And the two infinities can be distinguished by ===:

> 1 / -0 -Infinity > 1 / +0 Infinity > Infinity === -Infinity false

Stricter equality in ECMAScript.next: the “is” operator

ECMAScript.next will have an
“is” operator that performs “stricter equality”: It considers NaN equal to itself and distinguishes between -0 and +0. Its negation is called “isnt”. Examples:
> NaN is NaN true > -0 isnt +0 true

The 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; };

**Why does the ECMAScript.next proposal use the name “egal”?**

The reason that the
ECMAScript.next proposal uses the name “egal” for the “is” operator is due to the seminal paper on equality, “
Equal Rights for Functional Objects or, The More Things Change, The More They Are the Same” by Henry G. Baker, 1990. Quoting that paper’s explanation for calling its equality operator “egal”:
Egalis the obsolete Norman term for equal, and Égalité is the French word for social equality.

**Trying out Object.is()**

If you want to try out Object.is(), you can use the es6-shim [4] that backports some of ECMAScript.next (which is the current code name for ECMAScript 6) to ECMAScript 5.

References

- Equality in JavaScript: === versus ==
- ECMAScript.next: the “TXJS” update by Eich
- NaN and Infinity in JavaScript
- es6-shim – ECMAScript 6 functionality on ECMAScript 5

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

Opinions expressed by DZone contributors are their own.

## {{ parent.title || parent.header.title}}

## {{ parent.tldr }}

## {{ parent.linkDescription }}

{{ parent.urlSource.name }}