- Published at
- Updated at
- Reading time
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.
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
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
1 / -0 === -Infinity // true 1 / 0 === Infinity // true -Infinity === Infinity // false
Strict comparison with
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 could lead to hard-to-spot bugs. That's maybe the reason why
=== ignores it.
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! :)