Published at
Updated at
2min
This post is part of my Today I learned series in which I share all my web development learnings.

I was in Cluj-Napoca the last few days to speak at the excellent JSHeroes conference and saw a fascinating code snippet in Mathias Bynens' talk "V8 Internals for JS Developers" (the recording is from a different event).

``````Object.is(-0, +0); // false
``````

This single line is fascinating in two ways – let's have a look!

## The two existent zeros in JavaScript

First, JavaScript numbers follow the IEEE Standard for Floating-Point Arithmetic. This standard is available in several variants, and JavaScript uses "Double precision" (also called "binary64") based on 64 bits.

IEEE 754 defines that a sign, a significant, and an exponent to describe each finite number. Understanding how this works may take some time, but the important fact is that one bit (the sign bit) in JavaScript numbers defines if a number is positive or negative. And this definition includes the number zero!

Yes there are negative zeros in JavaScript!

``````const posNumber = 1;
const negNumber = -1;
const posZero = +0;
const negZero = -0;
``````

My first reaction to discovering negative zeros was that I surely don't have these in my code, but you will be surprised! Round `-0.23`, and you'll end up with a negative zero. So it might be possible that you have to treat negative zeros in your code, too.

``````Math.round(-0.23); // -0
``````

But there's more; compare a positive and negative zero and you'll discover that they're treated equal! 😲

``````-0 === +0 // true
``````

Sidenote: you can differentiate `-0` and `0` by using division and the resulting `Infinity`. Positive and negative `Infinity` are not equal.

``````1 / -0 === -Infinity    // true
1 / 0 === Infinity      // true
-Infinity === Infinity  // false
``````

But there's a nicer way of dealing with `-0`!

## Object.is – comparing without quirks?

Strict comparison with `===` treats `0` and `-0` as equal and it just feels like another JavaScript quirk that we all learn over time. It's similar to `NaN`, which is not equal to itself.

``````NaN === NaN // false

// Tip: you can use Number.isNaN as an alternative
Number.isNaN(NaN) // true
``````

These quirks are when `Object.is` comes into play. In most cases, it behaves the same as `===`, but it includes some minor "improvements" making things more logical. Let's look at the zero and `NaN` example.

``````Object.is(-0, 0);    // false
Object.is(NaN, NaN); // true
``````

`Object.is` differentiates positive and negative zeros and it's even able to detect `NaN`. 🎉

I saw `Object.is` for the first time in Mathias' slides, and it doesn't seem to be used that often. Do you have `Object.is` in your source code? 