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)); // false

String/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)); // true

Boas 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

Exercícios

  1. 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úmero 10, e então realiza a subtração.
  2. 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 retornar true.
  3. O que retorna Boolean('false')? Por quê?

    ✓ Resposta: Retorna true. A string 'false' não é vazia, portanto é considerada truthy. Apenas strings vazias ('') são convertidas para false.
  4. Explique por que [] == ![] é true.

    ✓ Resposta: [] é truthy, então ![] é false. Na comparação abstrata [] == false, ambos são convertidos para número: [] vira 0 (via ToNumber) e false vira 0, resultando em 0 == 0 que é true.
  5. Como verificar se um valor é NaN de forma confiável?

    ✓ Resposta: Use Number.isNaN(valor) ou Object.is(valor, NaN). Não use valor == NaN pois NaN nunca é igual a nada, inclusive a si mesmo.