# +-0, NaN and Object.is in JavaScript

- Published at
- Updated at
- Reading time
- 3min

The last few days, I was in Cluj-Napoca where I spoke 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 at it.

The first fact is that numbers in JavaScript 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 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. A negative zero likely appears in my (and yours) JavaScript, too.

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

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

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

AbdulFattah Popoola wrote a valuable article on the topic and there is even a section in the "You don't know JavaScript" series on positive and negative zeros going more into more details.

Sidenote: you can differentiate `-0`

and `0`

by using division and the resulting `Infinity`

. Positive and negative `Infinity`

are not equal. **But there's a nicer way!**

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

Strict comparison with `===`

didn't catch that the two zeros are not the same. It's one of these JavaScript quirks similar to `NaN`

, that you may know is not equal to itself.

```
NaN === NaN // false
// you can use Number.isNaN as an alternative
Number.isNaN(NaN) // true
```

These occasions are when `Object.is`

comes into play. It behaves the same as `===`

in most cases but includes some minor "improvements" that make things a bit more logical.

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

Not everybody is aware of the `-0`

existence, which means that for the rounding of `-0.23`

a differentiation between `0`

and `-0`

**could lead to hard-to-spot bugs**. That's maybe the reason why `===`

ignores it.

I saw `Object.is`

for the first time in Mathias' slides, and it doesn't seem to be used that often.

One question that came to mind immediately: is `Object.is`

as fast as `===`

? I created a quick JSPerf to see how `Object.is`

performs in comparison to `===`

. `Object.is`

seems to be significantly slower than `===`

in Safari and Firefox, whereas it's more or less the same in Chrome. That's very interesting!

If you have comments on the performance test, please let me know. Browser internals are incredibly complicated, and sometimes an optimization takes place in a test which then invalidates the whole thing.

I'd also love to hear if you use `Object.is`

in your source code! :)