
Usa Number(chaine) para converter uma string que tenha de ser inteiramente numérica («42», «3.99»): devolve NaN ao mínimo carácter parasita. Usa parseInt(chaine, 10) ou parseFloat(chaine) para extrair o número no início de uma string como «42px». Verifica sempre o resultado com Number.isNaN() antes de calcular.
Um valor lido de um campo de formulário, de um atributo HTML, de um URL ou de um ficheiro JSON mal tipado chega sempre em forma de string. Antes de calcular, é preciso convertê-lo em número. O JavaScript oferece quatro maneiras de o fazer, e nenhuma reage da mesma forma perante «42px», «3,99» ou uma string vazia. Eis o que cada uma devolve realmente, verificado em Node.js 22.
Os quatro métodos numa tabela
| String | parseInt(s, 10) | parseFloat(s) | Number(s) | +s |
|---|---|---|---|---|
"42" | 42 | 42 | 42 | 42 |
"3.99" | 3 | 3.99 | 3.99 | 3.99 |
"42px" | 42 | 42 | NaN | NaN |
" 42 " | 42 | 42 | 42 | 42 |
"" (vazia) | NaN | NaN | 0 | 0 |
"12,5" | 12 | 12 | NaN | NaN |
"1e3" | 1 | 1000 | 1000 | 1000 |
"0x1f" | 0 (base 10 forçada) | 0 | 31 | 31 |
"abc" | NaN | NaN | NaN | NaN |
"Infinity" | NaN | Infinity | Infinity | Infinity |
null | NaN | NaN | 0 | 0 |
undefined | NaN | NaN | NaN | NaN |
Desenham-se duas famílias. parseInt e parseFloat extraem: leem a string desde o início, param no primeiro carácter que não é um algarismo e devolvem o que leram. Number() e o operador + convertem tudo ou nada: a string inteira tem de representar um número, senão sai NaN. Uma exceção que custa a engolir: a string vazia vale 0 para eles.
parseInt(): o inteiro no início da string
parseInt('42', 10); // 42
parseInt('42px', 10); // 42 : para no «p»
parseInt('3.99', 10); // 3 : a parte decimal é ignorada, não arredondada
parseInt(' 42 ', 10); // 42 : os espaços à volta são tolerados
parseInt('abc', 10); // NaN : nenhum algarismo no início
parseInt('', 10); // NaNO segundo argumento é a base (ou radix). Vale 10 para um número decimal, 16 para o hexadecimal, 2 para o binário:
parseInt('ff', 16); // 255
parseInt('101', 2); // 5
parseInt('0x1f'); // 31 : sem base, o prefixo 0x faz passar para hexadecimal
parseInt('08'); // 8 : os motores modernos já não leem «08» em octalEscrever a base explicitamente, parseInt(s, 10), já não é indispensável por causa dos zeros iniciais desde o ES5, mas continua a ser o bom hábito: torna a intenção legível e neutraliza o caso 0x.
parseFloat(): o número decimal no início da string
parseFloat('3.99'); // 3.99
parseFloat('12.5px'); // 12.5
parseFloat('.5'); // 0.5
parseFloat('1e3'); // 1000 : a notação científica é compreendida
parseFloat('3,99'); // 3 : a vírgula interrompe a leitura
parseFloat('abc'); // NaNparseFloat não tem argumento de base: lê sempre em decimal. É a função a escolher para extrair uma medida de uma string CSS («12.5px», «1.5rem») ou de um texto livre.
Number(): a conversão estrita
Number('42'); // 42
Number('3.99'); // 3.99
Number(' 42 '); // 42 : espaços e mudanças de linha à volta são ignorados
Number('42px'); // NaN : um único carácter a mais e tudo falha
Number(''); // 0 : atenção
Number(' '); // 0 : idem
Number(null); // 0
Number(undefined); // NaN
Number(true); // 1
Number('0x1f'); // 31 : hexadecimal, binário (0b) e octal (0o) com prefixo são aceitesNumber() é a conversão que queres para um valor que tem de ser um número e mais nada: um preço, uma quantidade, um identificador. Se o utilizador escreveu «12 euros», recebes NaN e podes dizer-lho, em vez de calcular com 12 sem saber.
O operador unário +: Number() num carácter
+'42'; // 42
+''; // 0
+'abc'; // NaN
'42' * 1; // 42 : a multiplicação também força a conversão
'42' - 0; // 42
'3' + '4'; // '34' : já a adição concatena!O + colocado à frente de um valor aplica exatamente Number(). É curto, muito frequente no código existente e fácil de deixar passar na releitura: +valeur confunde-se com uma gralha. Num código partilhado, Number(valeur) diz o mesmo com mais clareza. E nunca uses a adição binária para converter: '3' + '4' dá a string '34'.
Tratar o NaN como deve ser
NaN (Not a Number) é o resultado de qualquer conversão falhada. Tem uma propriedade traiçoeira: não é igual a nada, nem sequer a si próprio.
const n = Number('abc');
n === NaN; // false, sempre
Number.isNaN(n); // true : a forma correta de testar
isNaN('abc'); // true : mas isNaN converte primeiro o argumento...
Number.isNaN('abc');// false : ... ao passo que Number.isNaN só deteta os NaN verdadeirosO esquema habitual: converter, testar, aplicar um valor por omissão ou assinalar o erro.
function toNumber(valeur, defaut = 0) {
const n = Number(String(valeur).trim());
return Number.isNaN(n) ? defaut : n;
}
toNumber('42'); // 42
toNumber('42px'); // 0 (valor por omissão)
toNumber('', 10); // 0 : a string vazia vale 0, não o valor por omissãoA última linha lembra a armadilha da string vazia: se um campo vazio tiver de ser tratado como «não preenchido», testa-o antes de converter.
function toNumberStrict(valeur) {
const s = String(valeur).trim();
if (s === '') return NaN;
return Number(s);
}O caso francês: a vírgula decimal
Nenhum dos quatro métodos percebe «12,5». Number devolve NaN, parseFloat para na vírgula e devolve 12, o que é pior: o programa segue com um valor errado. Normaliza o que foi escrito antes de converter.
function parseFr(chaine) {
const normalisee = String(chaine)
.replace(/\s/g, '') // retira os espaços dos milhares: «1 234,56»
.replace(',', '.'); // vírgula decimal -> ponto
return Number(normalisee);
}
parseFr('12,5'); // 12.5
parseFr('1 234,56'); // 1234.56
parseFr('12.5'); // 12.5 : o ponto continua a ser aceiteNum formulário, <input type="number"> evita o problema: o navegador mostra a vírgula ao utilizador francês mas transmite sempre um ponto em value.
Verificar se uma string é mesmo um número
Para saber se uma string representa um número antes de a usar, combina uma conversão estrita com Number.isFinite, que recusa NaN e Infinity.
function estNumerique(chaine) {
const s = String(chaine).trim();
return s !== '' && Number.isFinite(Number(s));
}
estNumerique('42'); // true
estNumerique('3.99'); // true
estNumerique('42px'); // false
estNumerique(''); // false
estNumerique('Infinity'); // falseE para distinguir um inteiro de um decimal depois da conversão: Number.isInteger(42) vale true, Number.isInteger(3.99) vale false.
Os inteiros grandes: quando Number deixa de chegar
Number representa exatamente os inteiros até 253 − 1 (9 007 199 254 740 991). Acima disso, a precisão perde-se sem aviso: um identificador de base de dados em 64 bits ou um montante em cêntimos muito elevado podem ficar falseados.
Number('9007199254740993'); // 9007199254740992 : o último algarismo mudou
BigInt('9007199254740993'); // 9007199254740993n : exato
Number.MAX_SAFE_INTEGER; // 9007199254740991BigInt não se mistura com Number num cálculo e não aceita decimais; reserva-o para os identificadores e para os inteiros verdadeiramente grandes.
Que método escolher?
- O valor tem de ser um número e mais nada (preço, quantidade, identificador):
Number(), depois de pôr de lado a string vazia. - É preciso extrair um número de um texto («12.5px», «3 artigos»):
parseFloat()para um decimal,parseInt(s, 10)para um inteiro. - O que foi escrito vem de um utilizador francês: normalizar a vírgula e os espaços, depois
Number(). - Estás a reler código com
+valeur: isso éNumber(valeur). Mantém-no se a equipa estiver habituada, mas nunca convertas com a adição'3' + '4'. - Em todos os casos: testa com
Number.isNaN()ouNumber.isFinite()antes de calcular.
A operação inversa, transformar um número numa string legível com duas casas decimais ou um separador de milhares, está tratada em Formatar um número em JavaScript. Para as bases da linguagem, o capítulo Variáveis e tipos de dados do tutorial explica porque é que uma string e um número são dois tipos distintos.
Erros frequentes
parseInt("08") vale 8 em todos os motores modernos, mas parseInt("0x1f") vale 31: a string é lida em hexadecimal. Passa sempre a base: parseInt(chaine, 10).Number("12,5") devolve NaN e parseFloat("12,5") devolve 12. Substitui a vírgula por um ponto antes da conversão.NaN === NaN é falso. Usa Number.isNaN(valeur), nunca uma comparação direta.Number("") e +"" valem 0, não NaN. Um campo de formulário deixado vazio torna-se assim um zero silencioso: testa chaine.trim() === "" antes de converter.

