Há dois zeros em Javascript. O zero negativo e o zero positivo.
Uma das razões para isto é que os números em JavaScript estão seguindo o padrão IEEE para aritmética de ponto flutuante. Esse padrão está disponível em diversas variantes e o JavaScript usa “Precisão dupla”, também chamada “binary64”, com base em 64 bits.
O IEEE 754 define um sinal, um significando e um expoente para descrever cada número finito. Para entender como isso funciona, pode levar algum tempo, mas o fato importante é que há um bit (o bit de sinal) em números JavaScript que define se um número é positivo ou negativo, o que significa que 0 também pode ser negativo.
Com isto, temos a seguinte situação:
const posNumber = 1; const negNumber = -1; const posZero = +0; const negZero = -0;
O que em termos prático, pode resultar em:
Math.round(-0.1415); // -0 Math.round(0.1415); // +0
Ou seja, arredondar valores entre -1 e +1, onde seria esperado dar zero e pronto. No entanto, vericamos que na prática não é isto que acontece.
Então um ponto necessário observar passa a ser, como o +0 e o -0 se comportam e como podem afetar nossa codificação. Um exemplo muito importante. Seriam os zeros ‘iguais’ numa comparação?
-0 == +0 // true -0 === +0 // true Object.is(-0, +0); // false
Observamos pelos resultados acima que a comparação estrita com === não captou o fato de que os dois zeros não são os mesmos.
Estas ocasiões ocorre quando o Object.is entra em jogo. Na maioria dos casos, ele se comporta da mesma forma que ===, mas inclui algumas pequenas “melhorias” que tornam as coisas um pouco mais lógicas.
A desvantagem disso é que nem todos os programadores estão cientes da existência de -0, o que significa que, para o arredondamento de -0.1415 e +0.1415, uma diferenciação entre 0 e -0 poderia levar a erros difíceis de detectar. É provavelmente por isso que geralmente é ignorado em JavaScript, mas pode certamente levar a uma grande dor de cabeça.