Entendendo o NaN (Not a Number) no JavaScript e Suas Particularidades
Tags: javascript, frontend, nan
Published: 2023-10-25 16:57:21

## Introdução

O JavaScript, como linguagem de programação, lida com números em várias situações. No entanto, há momentos em que as operações com números podem resultar em valores especiais, ocasionalmente de difícil entendimento até mesmo para os programadores mais experientes. Um desses valores é o NaN (Not-a-Number). Segundo a documentação, o NaN é uma propriedade global que significa que determinado valor não é um número. Sua sintaxe é como descrito: `NaN`.

Em JavaScript, NaN (Not a Number) é considerado um valor numérico especial e tem o tipo de dado "number". Isso pode parecer contra-intuitivo à primeira vista, mas faz sentido no contexto de operações matemáticas. O "NaN" é uma representação única do JavaScript para identificar valores que não podem ser expressos como números válidos. Ele é frequentemente gerado quando ocorrem operações matemáticas inválidas, como `Math.sqrt(-1)`, divisões por 0 ou quando uma função tenta transformar uma string em inteiro (`parseInt("blabla")`).

Uma coisa importante a notar é que o "NaN" é um valor especial e não é igual a si mesmo. Isso significa que, ao comparar um valor com "NaN," você não pode usar a comparação padrão `==` ou `===`. Para identificar e comparar corretamente "NaN," você pode usar a propriedade `Number.NaN` ou `isNaN()`, que é a representação numérica de "NaN."

```javascript
NaN === NaN;          // false
Number.NaN === NaN;   // false
isNaN(NaN);           // true
isNaN(Number.NaN);     // true
```

Vamos explorar mais sobre como o "NaN" funciona, como detectá-lo e como lidar com ele em situações do mundo real neste artigo.

## Causas do NaN

### Operações Matemáticas Inválidas

Qualquer operação matemática que não produza um valor numérico válido, como tentar multiplicar uma string por um número, resultará em "NaN".

```javascript
let resultado = "abc" * 2; // Tentar multiplicar uma string por um número
```

### Conversão de String Inválida

Tentar converter uma string que não representa um número em um número também resultará em "NaN".

```javascript
let numero = parseInt("abc"); // Isso resultará em "NaN"
```

### Operações com "NaN" Existente

Qualquer operação matemática realizada envolvendo um Not-a-Number existente também resultará no mesmo. Considere que o NaN é contagioso.

```javascript
let resultado = NaN + 5; // Isso resultará em "NaN"
```

Vale lembrar que, por ser um valor especial, ele não pode ser usado em operações matemáticas, pois pode causar resultados indeterminados, levando a erros em sua operação e resultado. Uma boa prática é implementar validações e tratamento de erros adequados para evitar comportamentos inesperados em seu código JavaScript.

## Detectando "NaN" com `isNaN()`

Como verificar se um valor é um Not-a-Number? O JavaScript possui uma função chamada `isNaN()` que é utilizada para verificar se um valor é "NaN" ou não. Ela retorna um booleano com valor `true` se o valor passado como argumento for "NaN" e `false` caso contrário. Sua utilização é exibida abaixo:

```javascript
let resultado = 5 / "abc"; // Isso resultará em `NaN`

if (isNaN(resultado)) {
  console.log("O resultado é NaN.");
} else {
  console.log("O resultado não é NaN.");
}
```

Apesar de ser útil para detectar valores NaN, a função `isNaN()` retornará `true` para qualquer valor não numérico, como strings não numéricas. Por isso, é uma boa prática verificar se o valor não é um número antes de usar a função.

Em resumo, a função `isNaN()` é uma ferramenta útil para detectar "NaN" em JavaScript, mas é importante usá-la com cuidado e considerar o contexto em que está sendo aplicada para garantir resultados precisos.

## Diferença entre "NaN" e `undefined`

Em JavaScript, "NaN" e `undefined` são valores diferentes. "NaN" é associado a operações matemáticas inválidas, enquanto `undefined` indica que uma variável foi declarada, mas não recebeu um valor. Ambos são valores especiais em

 JavaScript e são úteis em contextos específicos.

### Exemplo de Diferenciação:

```javascript
let resultadoNaN = "abc" * 2; // Isso resultará em `NaN`
let variavelIndefinida;
console.log(variavelIndefinida); // Isso resultará em `undefined`

console.log(typeof resultadoNaN);      // Isso resultará em 'number'
console.log(typeof variavelIndefinida); // Isso resultará em 'undefined'
```

## Comparando "NaN" em JavaScript

É importante atentar para uma característica peculiar: "NaN" não é igual a ele mesmo. Essa singularidade surge do fato de que "NaN" representa o resultado de operações matemáticas inválidas, e, portanto, a comparação direta não se comporta como esperado.

Devido ao fato de NaN não ser igual a ele mesmo, utilizar os operadores `==` (igualdade solta) e `===` (igualdade estrita) resultará em `false` ao tentar comparar um resultado NaN consigo mesmo. Para lidar com isso, os desenvolvedores comumente preferem a utilização de `isNaN()`, que converte implicitamente o valor para número antes de verificar.

### Exemplo:

```javascript
let resultado = 5 / "abc"; // Isso resultará em `NaN`

console.log(isNaN(resultado));    // Isso resultará em `true`
```

```javascript
let resultado = 5 / "abc"; // Isso resultará em `NaN`

if (isNaN(resultado)) {
  console.log("O resultado é NaN.");
} else {
  console.log("O resultado não é NaN.");
}
```

Se você precisa de uma comparação estrita para "NaN", pode usar a seguinte abordagem:

```javascript
let resultado = 5 / "abc"; // Isso resultará em `NaN`

if (resultado !== resultado) {
  console.log("O resultado é NaN.");
} else {
  console.log("O resultado não é NaN.");
}
```

## Evitando "NaN" em JavaScript: Dicas e Boas Práticas

1. **Validação de Entradas do Usuário:**
   Sempre espere resultados diversos ao dar entrada em um valor. Uma validação básica utilizando o `isNaN()` pode afastar valores diferentes de numérico numa entrada de dados.

   ```javascript
   let userInput = prompt("Digite um número:");

   if (isNaN(userInput)) {
     alert("Por favor, digite um número válido.");
   } else {
     // Continue com as operações, sabendo que a entrada é numérica.
   }
   ```

2. **Verificação de Valores Antes de Operações Matemáticas:**
   Uma boa prática, especialmente para valores de formulários web, é checar os dados antes de realizar operações matemáticas com eles, assim certificando-se de que eles são válidos.

   ```javascript
   let valor1 = parseFloat(document.getElementById("input1").value);
   let valor2 = parseFloat(document.getElementById("input2").value);

   if (!isNaN(valor1) && !isNaN(valor2)) {
     let resultado = valor1 + valor2;
     console.log("Resultado:", resultado);
   } else {
     console.log("Entradas inválidas. Certifique-se de que ambos os valores são numéricos.");
   }
   ```

3. **Utilizando Operadores Matemáticos com Cuidado:**
   Esteja ciente de como os operadores matemáticos se comportam em diferentes contextos. Por exemplo, a concatenação de strings com o operador `+` pode resultar em resultados não numéricos.

   ```javascript
   let numero = "10";
   let resultado = numero + 5; // Isso resultará em "105" (concatenação), não em 15 (adição)

   // Certifique-se de converter para número antes de operações matemáticas
   let resultadoNumerico = Number(numero) + 5; // Agora o resultado é 15
   ```

   Se suas entradas são complexas ou de operações específicas, considere utilizar validações personalizadas ou utilizar bibliotecas de validação. Frameworks como o Angular contam com o padrão utilizado em seus formulários, onde pode-se passar como parâmetro um regex que garante que contenha apenas valores numéricos.

   ```javascript
   function validarNumero(valor) {
     // Lógica personalizada de validação
     return !isNaN(valor) && valor > 0;
   }

   let entrada = parseFloat(prompt("Digite um número maior que zero:"));

   if (validarNumero(entrada)) {
     alert("Número válido!");
   } else {
     alert("Por favor, digite um número válido maior que zero.");
   }
   ```

## Compatibilidade com Outras Linguagens

O conceito de "NaN" (Not-a-Number) é específico para linguagens de programação que seguem as especificações do padrão IEEE 754 para aritmética de ponto flutuante. Outras linguagens que possuem conceitos semelhantes incluem o Python, com o objeto `float('nan')`. O Java utiliza a constante `Double.NaN` ou `Float.NaN`. Em C/C++, é representado pela

 função `nan()` ou `NAN` em cabeçalhos como `<cmath>` ou `<math.h>`.

## Resolução de Problemas

Como mencionado neste artigo, existem validações e meios para resolver problemas com o NaN. Para isso, é necessário sempre verificar os valores de entrada a fim de afastar qualquer valor não numérico. Uma forma de fazer isso é utilizando as validações. Caso uma operação resulte neste valor, pode-se utilizar logs de depuração para imprimir valores e identificar em qual parte do código está ocorrendo o "NaN". Isso ajuda a rastrear a origem do problema. Para evitar também o uso da função `isNaN()` é um excelente aliado.

## Considerações Finais

- "NaN" é um conceito fundamental em linguagens que seguem o padrão IEEE 754.
- Representa resultados inválidos em operações matemáticas.
- A validação cuidadosa de entradas e o uso de funções de validação são essenciais para evitar problemas com "NaN".
- Logs de depuração são ferramentas poderosas para identificar a origem de "NaN" em seu código.
- Compreender e lidar corretamente com "NaN" contribui para a robustez e confiabilidade do código em linguagens que envolvem operações numéricas.

## Referências

1. **MDN Web Docs - NaN:**
   - [MDN Web Docs - NaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN)

3. **Exploring ES6 (Livro online):**
   - Autor: Axel Rauschmayer
   - [Exploring ES6 - Numbers](https://exploringjs.com/es6/ch_numbers.html)