Um nome melhor para NaN
, descrevendo seu significado de maneira mais precisa e menos confusa, seria uma exceção numérica . É realmente outro tipo de objeto de exceção disfarçado de tipo primitivo (pelo design da linguagem), onde, ao mesmo tempo, não é tratado como primitivo em sua falsa auto-comparação. De onde a confusão. E enquanto a linguagem "não se decidir" em escolher entre o objeto de exceção apropriado e o numeral primitivo , a confusão permanecerá.
A infame não igualdade de NaN
si mesma, ambas ==
e ===
é uma manifestação do design confuso que força esse objeto de exceção a ser um tipo primitivo. Isso quebra o princípio fundamental de que um primitivo é determinado exclusivamente por seu valor . Se NaN
preferir ser visto como exceção (da qual pode haver tipos diferentes), não deve ser "vendido" como primitivo. E se se deseja que seja primitivo, esse princípio deve se manter. Enquanto estiver quebrado, como temos em JavaScript, e não podemos realmente decidir entre os dois, a confusão que leva a uma carga cognitiva desnecessária para todos os envolvidos permanecerá. O que, no entanto, é realmente fácil de corrigir, basta escolher entre os dois:
- crie
NaN
um objeto de exceção especial contendo as informações úteis sobre como a exceção surgiu, em vez de jogar fora essas informações como o que está implementado atualmente, levando a um código mais difícil de depurar;
- ou criar
NaN
uma entidade do tipo primitivo number
(que poderia ser menos confundidamente chamado de "numérico"); nesse caso, deve ser igual a si mesmo e não pode conter outras informações; o último é claramente uma escolha inferior.
A vantagem única concebível de forçar NaN
em number
tipo é ser capaz de jogá-lo de volta para qualquer expressão numérica. O que, no entanto, torna a opção frágil, porque o resultado de qualquer expressão numérica que contenha NaN
será NaN
ou levará a resultados imprevisíveis, como NaN < 0
avaliar false
, ou seja, retornar em boolean
vez de manter a exceção.
E mesmo que "as coisas sejam do jeito que são", nada nos impede de fazer essa distinção clara para nós mesmos, para ajudar a tornar nosso código mais previsível e mais fácil de depurar. Na prática, isso significa identificar essas exceções e lidar com elas como exceções. O que, infelizmente, significa mais código, mas espero que seja atenuado por ferramentas como o TypeScript do Flowtype.
E então nós temos a distinção bagunçada silenciosa vs barulhenta, também conhecida como sinalizaçãoNaN
. O que realmente é sobre como as exceções são tratadas, não as próprias exceções e nada diferente de outras exceções.
Da mesma forma, Infinity
e +Infinity
são elementos do tipo numérico que surgem na extensão da linha real, mas não são números reais. Matematicamente, eles podem ser representados por sequências de números reais convergindo para um +
ou para -Infinity
.