**Update 2012-11-08:**The

`is`operator will not be added to ECMAScript (probably ever). But this article is still relevant, because

`Object.is()`will be part of ECMAScript 6 and because it sheds light on how

`===`works.

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.

### 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 = 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()`.

### 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 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

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

#### 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.

## No comments:

Post a Comment