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