Conversões de Tipo em JavaScript
Aprenda como o JavaScript converte valores entre strings, números e booleans — conversões explícitas com String(), Number(), Boolean(), regras de coerção implícita e armadilhas comuns.
JavaScript é uma linguagem de tipagem dinâmica: uma variável pode conter uma string em um momento e um número no seguinte, e você nunca declara o tipo de um valor antecipadamente. Por causa dessa flexibilidade, os valores precisam constantemente se mover entre tipos — um número vira texto para ser exibido, o texto de um campo de formulário vira um número para um cálculo, um object é testado quanto à "veracidade" dentro de um if. Essas conversões acontecem de duas formas: explicitamente, quando você mesmo chama uma função como String() ou Number(), e implicitamente (também chamada de coerção), quando a linguagem converte um valor automaticamente para adequá-lo à operação. Este capítulo aborda ambas, as regras exatas para cada tipo-alvo e as surpresas que pegam quase todos de surpresa em algum momento.
Se você ainda não leu sobre os tipos de dados disponíveis, é útil dar uma olhada nisso primeiro — as conversões só fazem sentido quando você sabe o que está convertendo.
As Três Conversões
Quase toda conversão em JavaScript tem como alvo um dos três tipos primitivos: string, number ou boolean. Não existe uma operação genérica de "converter para o tipo X"; em vez disso, cada alvo tem suas próprias regras. Veremos cada um por vez e, em seguida, quando a linguagem os aplica por você.
Conversão para String
A conversão para string transforma um valor em sua forma textual. Acontece explicitamente com a função String(), e implicitamente sempre que um valor se encontra com uma string em concatenação ou é interpolado em um template literal.
String(123); // "123"
String(true); // "true"
String(null); // "null"
String(undefined); // "undefined"
`Value: ${42}`; // "Value: 42"As regras são intuitivas para primitivos — o valor é renderizado exatamente como você esperaria lê-lo. Note que null e undefined se tornam o texto literal "null" e "undefined", não uma string vazia.
Objects e arrays são mais interessantes. Um array se torna seus elementos unidos por vírgulas, e um object simples se torna o famoso e inútil "[object Object]":
Portanto, um array vazio converte para uma string vazia, e null/undefined dentro de um array renderizam como slots vazios (então [null, 5] resulta em ",5"). O resultado "[object Object]" para objects é o motivo pelo qual você recorre a JSON.stringify(obj) quando realmente quer ler o conteúdo de um object.
Conversão Numérica
A conversão numérica transforma um valor em um número. A forma explícita é a função Number(); implicitamente, acontece com o operador unário de adição (+valor) e com a maioria dos operadores aritméticos e de comparação.
Vale a pena memorizar as regras, pois nem sempre são óbvias:
| Valor | Number(value) |
|---|---|
undefined | NaN |
null | 0 |
true / false | 1 / 0 |
"" (string vazia) | 0 |
" 42 " (espaços em branco ao redor dos dígitos) | 42 |
"42px" (conteúdo não numérico) | NaN |
"3.14" | 3.14 |
Alguns desses são notórios. Number(null) é 0, mas Number(undefined) é NaN — os dois valores "vazios" se comportam de forma diferente. Uma string vazia também vira 0, não NaN. As strings são primeiro removidas dos espaços em branco ao redor, depois analisadas; se restar qualquer conteúdo não numérico, o resultado é NaN (que significa "Not a Number", ou "Não é um Número").
Unário Mais
O operador unário de adição é a forma mais curta de forçar uma conversão numérica. Colocado antes de um valor, +valor faz exatamente o que Number(valor) faz:
+"42"; // 42
+""; // 0
+true; // 1
+"abc"; // NaNIsso é prático, mas fácil de ler errado, portanto reserve-o para lugares onde a intenção esteja clara (como +event.target.value ao ler um campo de formulário numérico).
parseInt e parseFloat vs Number
Number() é estrito: a string inteira deve ser um número válido, ou você obtém NaN. As funções parseInt() e parseFloat() são mais permissivas — elas leem a partir do início da string e param no primeiro caractere que não se encaixa, retornando o que foi analisado até então.
Dois cuidados com parseInt:
- Ele retorna
NaNsomente se a string não começa com um número analisável —"px12"falha, mas"12px"tem sucesso com12. - Sempre passe o radix (base) como segundo argumento para evitar surpresas:
parseInt("08", 10)retorna8com confiabilidade. Sem ele, os motores modernos assumem a base 10 por padrão, mas ser explícito elimina qualquer dúvida e documenta sua intenção.
parseInt("FF", 16); // 255 (hexadecimal)
parseInt("101", 2); // 5 (binary)
parseInt("08", 10); // 8 (decimal, explicit radix)Use Number() (ou +) quando quiser validar que um valor inteiro é numérico, e parseInt/parseFloat quando deliberadamente quiser extrair um número do início de uma string maior, como "24px" de CSS.
Conversão para Boolean
A conversão para boolean responde a uma única pergunta: este valor é "verdadeiro" (truthy) ou "falso" (falsy)? Acontece explicitamente com Boolean() e implicitamente em qualquer lugar onde uma condição é avaliada — dentro de if, while, o ternário ?, e operadores lógicos.
A regra é surpreendentemente simples porque a lista de valores falsy é curta e fixa. Estes oito valores convertem para false:
false
0
-0
0n // BigInt zero
"" // empty string
null
undefined
NaNTodo o resto é truthy. Esse "todo o resto" inclui alguns valores que surpreendem os iniciantes:
A string "0" é truthy porque é uma string não vazia — seu conteúdo não importa. Da mesma forma, "false" é uma string não vazia perfeitamente normal e converte para true. E um array vazio [] ou object vazio {} é truthy, mesmo que "pareça" vazio. Memorize a lista de valores falsy; se um valor não está nela, ele é truthy.
Um idioma comum para um boolean explícito é o duplo-NOT: !!valor. O primeiro ! converte para um boolean negado, o segundo o inverte, dando o mesmo resultado que Boolean(valor) em menos caracteres. Por exemplo, !!"hello" é true e !!0 é false.
Coerção Implícita
Até agora chamamos as funções de conversão nós mesmos. A maioria das conversões do mundo real, porém, é implícita — a linguagem coerce os valores para que uma operação funcione. O truque é saber qual tipo-alvo cada contexto espera.
Aritmética e a Peculiaridade do +
Todo operador aritmético coerce seus operandos para números — exceto +, que é sobrecarregado. Se qualquer operando de + for uma string, + se torna concatenação de string; caso contrário, soma números. Todo outro operador (-, *, /, %) sempre converte para números.
A linha 1 + 2 + '3' mostra por que a ordem importa: + é associativo à esquerda, então 1 + 2 executa primeiro como números (3), depois 3 + '3' encontra uma string e concatena para "33". Esta única regra — "+ com qualquer string concatena, todo o resto converte para número" — explica grande parte da confusão dos iniciantes.
Condições e Lógica
Em qualquer contexto boolean — if, while, ?:, e os operadores lógicos && / || — o valor controlador é processado pela conversão boolean usando a lista de valores falsy acima.
if ("0") {
// runs: "0" is a non-empty string, therefore truthy
}
if (0 || "fallback") {
// "fallback" is returned: 0 is falsy, so || moves to the next value
}Comparações
Os operadores de igualdade realizam sua própria coerção, e o operador == frouxo em particular tem regras sutis o suficiente para merecer seu próprio capítulo. A versão curta: prefira o estrito ===, que nunca coerce. O conjunto completo de surpresas (como [] == ![] ser true) é abordado em operadores de comparação.
Conversão de Object para Primitivo
Quando um object é usado onde um primitivo é esperado (concatenação, aritmética, uma mensagem de alerta), o JavaScript primeiro o converte para um primitivo. Ele faz isso chamando o método Symbol.toPrimitive do object, se existir; caso contrário, recorre a valueOf() e toString(), escolhendo a ordem com base em se um número ou uma string é "sugerido". É por isso que um object simples vira "[object Object]" e um array vira uma string unida por vírgulas — esses vêm do toString() padrão. Você pode personalizar o resultado definindo esses métodos em seus próprios objects, mas para o código do dia a dia é suficiente saber que a conversão existe e usar JSON.stringify() quando quiser um object legível.
Armadilhas Comuns
Um punhado de resultados de conversão é responsável pela maioria dos momentos de "espera, como assim?". Tenha em mente:
Percorrendo os mais estranhos:
+[]é0. A conversão numérica primeiro transforma o array em uma string (""), depois a string vazia converte para0.+{}éNaN. O object vira"[object Object]", que não é um número válido, então converte paraNaN."" + 1é"1". Porque+encontrou uma string, ele concatenou em vez de somar.[] + []é"". Cada array converte para uma string vazia, e"" + ""é"".
Esses não são bugs — eles seguem exatamente as regras acima. Só parecem estranhos porque duas conversões diferentes se encadeiam em uma única expressão.
Boas práticas: prefira a conversão explícita. Escrever Number(input), String(value) ou Boolean(flag) torna sua intenção óbvia para o próximo leitor e evita as surpresas da coerção implícita. Reserve a conversão implícita para casos inequivocamente claros e use o estrito === para que os valores nunca sejam silenciosamente alterados durante comparações.
Resumo
- O JavaScript converte valores para string, number ou boolean — explicitamente via
String(),Number(),Boolean(), ou implicitamente por coerção. - String: primitivos são renderizados como seu texto;
[1,2,3]vira"1,2,3",[]vira"", e um object simples vira"[object Object]". - Number:
nullé0,undefinedéNaN,""é0; strings são removidas de espaços em branco e depois analisadas estritamente. Use+valorcomo atalho, eparseInt/parseFloat(com um radix) para análise permissiva do início da string. - Boolean: apenas
false,0,-0,0n,"",null,undefinedeNaNsão falsy; todo o resto — incluindo"0","false",[]e{}— é truthy. +concatena quando qualquer lado é uma string; todo outro operador aritmético converte para número.- Em caso de dúvida, converta explicitamente e compare com
===.
Você usará essas regras constantemente ao trabalhar com números, strings e entrada do usuário armazenada em variáveis.