Conversão de tipos (coerção)
Esta aula aborda a conversão de tipos em JavaScript, distinguindo entre coerção implícita (automática) e explícita (intencional), e explica como converter entre string, number e boolean. Também são apresentadas pegadinhas clássicas que podem levar a bugs sutis.
Em JavaScript, a conversão de tipos (ou coerção) é o processo de transformar um valor de um tipo para outro. Isso pode ocorrer automaticamente (coerção implícita) ou ser feita intencionalmente pelo programador (coerção explícita). Entender como o JavaScript lida com tipos é fundamental para evitar comportamentos inesperados e escrever código mais previsível.
Nesta aula, exploraremos as diferenças entre conversão implícita e explícita, os métodos para converter entre string, number e boolean, e algumas pegadinhas clássicas que todo desenvolvedor JavaScript deve conhecer.
Conversão implícita vs explícita
A conversão implícita ocorre quando o JavaScript automaticamente converte um tipo para outro em determinadas operações. Por exemplo, ao usar o operador + com uma string e um número, o número é convertido em string para concatenação. Já a conversão explícita é feita pelo programador usando funções como String(), Number(), Boolean() ou operadores unários como +.
É importante saber quando a coerção implícita pode causar resultados inesperados. Por exemplo, null == 0 retorna false, mas null <= 0 retorna true devido a regras específicas. Prefira sempre conversões explícitas para tornar o código mais legível e evitar bugs.
// Conversão implícita
console.log('5' - 3); // 2 (string convertida para número)
console.log('5' + 3); // '53' (número convertido para string, concatenação)
// Conversão explícita
console.log(Number('5')); // 5
console.log(String(123)); // '123'
console.log(Boolean(0)); // falseString/Number/Boolean
Para converter explicitamente para string, usamos String(valor) ou o método toString() (exceto para null e undefined). Para número, Number(valor), parseInt() ou parseFloat(). Para booleano, Boolean(valor) ou o operador dupla negação !!.
Valores que são convertidos para false em contexto booleano: false, 0, '' (string vazia), null, undefined, NaN. Todos os outros são true. Cuidado com strings como '0' ou 'false' que são true.
console.log(String(123)); // '123'
console.log((123).toString()); // '123'
console.log(Number('456')); // 456
console.log(parseInt('10px')); // 10
console.log(parseFloat('3.14em')); // 3.14
console.log(Boolean('')); // false
console.log(!!'texto'); // true
console.log(Boolean('false')); // true (string não vazia)Pegadinhas clássicas
Algumas comparações e operações podem surpreender. Por exemplo, [] == ![] retorna true, porque [] é truthy, então ![] é false, e a comparação abstrata converte ambos para número (0 == 0). Outra pegadinha: null == undefined é true, mas null === undefined é false.
Outro exemplo clássico é 0 == '0' (true) mas 0 == '' também é true, enquanto 0 == ' ' é true (espaço em branco convertido para 0). Além disso, NaN == NaN é false, pois NaN não é igual a nada, inclusive a si mesmo. Use Number.isNaN() para verificar.
console.log([] == ![]); // true
console.log(null == undefined); // true
console.log(0 == '0'); // true
console.log(0 == ''); // true
console.log(NaN == NaN); // false
console.log(Number.isNaN(NaN)); // trueBoas práticas
Sempre que possível, use conversão explícita para tornar o código mais legível. Evite confiar em coerção implícita em comparações; prefira === (igualdade estrita) a == (igualdade abstrata). Ao converter para número, considere usar Number() em vez de parseInt() se você espera um número puro, e parseInt() com radix para strings com prefixos.
Referências
- MDN: Operadores de comparação
- MDN: Number
- MDN: String
- MDN: Boolean
- MDN: Comparações de igualdade
- Especificação ECMAScript
Exercícios
Qual o resultado da expressão
'10' - 5? Explique.✓ Resposta: O resultado é5. O operador-força a conversão implícita da string'10'para o número10, e então realiza a subtração.Qual a diferença entre
==e===?✓ Resposta:==é igualdade abstrata, que realiza coerção de tipos antes de comparar.===é igualdade estrita, que não faz coerção; os tipos devem ser iguais para retornartrue.O que retorna
Boolean('false')? Por quê?✓ Resposta: Retornatrue. A string'false'não é vazia, portanto é considerada truthy. Apenas strings vazias ('') são convertidas parafalse.Explique por que
[] == ![]étrue.✓ Resposta:[]é truthy, então![]éfalse. Na comparação abstrata[] == false, ambos são convertidos para número:[]vira0(via ToNumber) efalsevira0, resultando em0 == 0que étrue.Como verificar se um valor é
NaNde forma confiável?✓ Resposta: UseNumber.isNaN(valor)ouObject.is(valor, NaN). Não usevalor == NaNpoisNaNnunca é igual a nada, inclusive a si mesmo.