The last few days I was in Cluj-Napoca where I spoke at the excellent JSHeroes conference. In the talk "V8 Internals for JS Developers" (the recording is from a different event though) of Mathias Bynens I saw a very interesting code snippet.
This single line is fascinating in two ways – let's have a look at it.
0 can be negative, too.
const posNumber = 1; const negNumber = -1; const posZero = +0; const negZero = -0;
My first reaction to the discovery of negative zeros was that I surely don't have these in my code, but well... when I round
Math.round(-0.23); // -0
It becomes interesting when you want to compare positive and negative zeros though because they're treated the same.
-0 === +0 // true
Sidenote: you can differentiate
0 using division and the resulting
1 / -0 === -Infinity // true 1 / 0 === Infinity // true -Infinity !== Infinity // true
Object.is – comparing without quirks?
So, the strict comparison with
=== didn't catch the fact that the two zeros are not the same. You may know that
NaN is also not equal to
NaN === NaN // false // you can use Number.isNaN as an alternative Number.isNaN(NaN) // true
These occasions are when
Object.is could come into play. In most cases, it behaves the same as
=== but it includes some minor "improvements" which make things a bit more logical.
Object.is(-0, 0); // false Object.is(NaN, NaN); // true
The downside of this is that not everybody is aware of the existence of
-0 which means that for the rounding of
-0.23 a differentiation between
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 was if it
Object.is is as fast as
===. I created a quick JSPerf to see how
Object.is performs in comparison to
===. In Safari and Firefox
Object.is seems to be significantly slower than
=== whereas in Chrome it's more or less the same. That's very interesting!
If anyone has comments on the performance test, please let me know. Browser internals are extremely 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! :)