JS Drip #70: Even Stricter Equality with Object.is

One of the most common recommendations in JavaScript style guides is to always (or almost always) make comparisons using the === strict equality operator, because it avoids a lot of ambiguities in the ordinary == equality operator. However, === does have two oddities of its own.

First, the special value NaN is not strictly equal to itself.

console.log(NaN === NaN);
// => false

Second, the values 0 (positive 0) and -0 are strictly equal, even though they are distinct values in JavaScript. (The reasons for why they are distinct values is a bit complicated, but Dr. Axel Rauschmayer has a great article on the topic.)

console.log(0 === -0);
// => true

Of course, there are ways to work around these ambiguities. As I've mentioned before, we can detect NaN by using the fact that it is the only value which is not equal to itself.

function isNaNValue (val) {
    return val !== val;
}

console.log(isNaNValue(NaN));
// => true

And we can detect 0 versus -0 by using the fact that JavaScript also distinguishes between Infinity and -Infinity.

function isNegativeZero(val) {
    if (val !== 0) {
        return false;
    }

    var thisInfinity = 1 / val;

    return (thisInfinity < 0);
}

isNegativeZero(-0);
// => true

However, even though we can detect these things, it would be nice if there was something built into the language that would do it for us. That's where Object.is comes in.

ECMAScript 6 adds the new is method to the global Object object. The entire reason for Object.is to exist is resolving these ambiguities.

For Object.is, NaN equals itself:

console.log(Object.is(NaN, NaN));
// => true

Object.is also treats 0 and -0 as distinct values:

console.log(Object.is(0, -0));
// => false

So, when ES6 finally comes around will you be better off using Object.is instead of === to compare values? Probably not. While Object.is resolves some ambiguities in ===, encountering those ambiguities is relatively rare. You should keep Object.is in your JavaScript toolbox, but it's not an everyday tool for most people.

Because it is an ES6 method, Object.is isn't available everywhere yet. But it is available in FireFox and Chrome for the past few versions. And if you'd like use to it in older browsers, you can polyfill it using Paul Miller's es6-shim.

Thanks for reading!

Josh Clanton