IsNumeric em JavaScript: 5 erros fatais na validação de números

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Validação de números decimais em JavaScript: por que IsNumeric() quebra o código e como corrigir

\n\n

Todo desenvolvedor que escreveu em JavaScript por pelo menos uma semana, mais cedo ou mais tarde, enfrentou a tarefa: "Verificar se uma string é um número". Parece simples, não? A função embutida isNaN() ou parseFloat() — e pronto. Mas não é bem assim. A pergunta "Validate decimal numbers in JavaScript — IsNumeric()" no Stack Overflow acumulou centenas de milhares de visualizações e dezenas de respostas contraditórias. Por quê? Porque JavaScript é uma linguagem onde typeof NaN === 'number', e uma string vazia é considerada zero.

\n\n

Neste artigo, não vamos apenas fornecer a função isNumeric() pronta. Vamos analisar os 5 erros mais comuns e perigosos que até programadores experientes cometem, e mostrar como evitá-los. Você aprenderá por que isNaN é uma armadilha, como funciona a coerção de tipos e qual método de validação de números em JS realmente usar em produção.

\n\n

Por que isNaN() é o mal (e quando funciona)

\n\n

Vamos começar pelo óbvio. Muitos iniciantes escrevem assim:

\n\n
function isNumeric(n) {\n  return !isNaN(n);\n}\n
\n\n

À primeira vista, é lógico: se não é NaN, então é número. Mas vamos testar:

\n\n
console.log(isNumeric('123'));    // true — ok\nconsole.log(isNumeric('12.3'));   // true — ok\nconsole.log(isNumeric(''));       // true — UPA! String vazia é número?\nconsole.log(isNumeric(' '));      // true — espaço também é número?\nconsole.log(isNumeric(null));     // true — null é número?\nconsole.log(isNumeric(true));     // true — true é 1\n
\n\n

Erro nº1: isNaN() primeiro converte o argumento em número, depois verifica. A string vazia '' é convertida em 0, null em 0, true em 1. Como resultado, a função considera números o que não são números.

\n\n

Existe uma variante estrita — Number.isNaN() (ES6), mas ela verifica apenas se o valor é exatamente NaN, sem conversão. Para validação de números, também não serve.

\n\n

parseFloat: herói ou vilão?

\n\n

A segunda abordagem popular é usar parseFloat():

\n\n
function isNumeric(n) {\n  return !isNaN(parseFloat(n)) && isFinite(n);\n}\n
\n\n

Esta versão já é melhor, mas tem outro problema:

\n\n
console.log(isNumeric('123abc')); // true — parseFloat pega '123', e 'abc' ignora\nconsole.log(isNumeric('12.3.4')); // true — o segundo ponto o parseFloat simplesmente não percebe\nconsole.log(isNumeric('Infinity')); // true — infinito é número?\n
\n\n

Erro nº2: parseFloat() analisa a string até o primeiro caractere inválido. A string '123abc' para ele é 123. Mas o usuário pode ter pressionado uma tecla extra acidentalmente, e somos obrigados a detectar isso.

\n\n

Erro nº3: isFinite() elimina Infinity e -Infinity, mas permite NaN e undefined. O problema é que isFinite(null) retorna true, porque null é convertido em 0.

\n\n

Erro nº4: Expressões regulares — panaceia ou novo inferno?

\n\n

Quando os desenvolvedores percebem que as funções embutidas não são confiáveis, muitas vezes vão para o outro extremo — expressões regulares. E aí começa o verdadeiro caos.

\n\n

Aqui está uma regex típica, mas perigosa:

\n\n
function isNumeric(n) {\n  return /^\\d+$/.test(n);\n}\n
\n\n

Problemas:

\n
    \n
  • Não permite pontos decimais ('12.3' — false)
  • \n
  • Não permite números negativos ('-5' — false)
  • \n
  • Não permite notação científica ('1e5' — false)
  • \n
\n\n

Aqui está um "u

Blogs

Book Recommendations