Em JavaScript, a conversão de tipos é um conceito fundamental que ocorre quando valores de um tipo são transformados em outro tipo. Isso pode acontecer automaticamente, chamado de coerção implícita, ou de forma intencional pelo programador, chamado de conversão explícita. Entender essas diferenças é crucial para evitar comportamentos inesperados e bugs difíceis de encontrar.

Nesta aula, vamos explorar os mecanismos de conversão para os tipos primitivos mais comuns: string, number e boolean. Veremos exemplos práticos de como o JavaScript realiza essas conversões, além de pegadinhas clássicas que podem enganar até programadores experientes. Ao final, você será capaz de prever o resultado de expressões envolvendo coerção e escrever código mais robusto.

Conversão implícita vs explícita

A conversão implícita (ou coerção) é realizada automaticamente pelo JavaScript em operações que envolvem tipos diferentes. 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 é quando o programador utiliza funções como String(), Number() ou Boolean() para forçar a transformação.

É importante saber que a coerção implícita pode levar a resultados surpreendentes. Por exemplo, '5' - 3 resulta em 2 (número), porque o operador - força a conversão da string para número. Já '5' + 3 resulta em '53' (string), porque o + com string prioriza concatenação.

Exemplo de código:

// Conversão implícita
let resultado1 = '5' - 3; // 2 (number)
let resultado2 = '5' + 3; // '53' (string)
let resultado3 = '5' * 2; // 10 (number)

// Conversão explícita
let num = Number('123'); // 123
let str = String(456); // '456'
let bool = Boolean(0); // false

String/Number/Boolean

Cada tipo primitivo tem regras específicas para conversão. Ao converter para string, valores são geralmente transformados em sua representação textual. Por exemplo, String(123) retorna '123', e String(true) retorna 'true'. A conversão para number é mais sutil: Number('123') retorna 123, mas Number('abc') retorna NaN. Valores como null viram 0, undefined vira NaN, e booleanos true e false viram 1 e 0, respectivamente.

Para boolean, a conversão segue a regra de valores truthy e falsy. São considerados falsy: false, 0, '' (string vazia), null, undefined e NaN. Todos os outros valores são truthy. Por exemplo, Boolean('hello') retorna true, enquanto Boolean(0) retorna false.

Exemplo de código:

// Conversão para string
console.log(String(123)); // '123'
console.log(String(true)); // 'true'
console.log(String(null)); // 'null'

// Conversão para número
console.log(Number('123')); // 123
console.log(Number('12.3')); // 12.3
console.log(Number('abc')); // NaN
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
console.log(Number(true)); // 1

// Conversão para booleano
console.log(Boolean(0)); // false
console.log(Boolean('')); // false
console.log(Boolean('hello')); // true
console.log(Boolean([])); // true (array vazio é objeto, truthy)

Pegadinhas clássicas

Algumas expressões em JavaScript são famosas por seus resultados inesperados devido à coerção. Por exemplo, a comparação com == (igualdade solta) realiza coerção de tipos, enquanto === (igualdade estrita) não. Isso leva a situações como 0 == '' ser true, porque ambos são convertidos para 0. Outra pegadinha é null == undefined ser true, mas null === undefined ser false.

Outro exemplo clássico é a soma de arrays: [] + [] resulta em string vazia '', pois ambos são convertidos para string vazia e concatenados. Já [] + {} resulta em '[object Object]', e {} + [] pode ser interpretado como bloco vazio mais array, resultando em 0 (devido à coerção).

Exemplo de código:

// Pegadinhas com ==
console.log(0 == ''); // true
console.log(0 == '0'); // true
console.log(false == 'false'); // false (string 'false' vira NaN)
console.log(null == undefined); // true
console.log([] == false); // true (array vazio vira 0, false vira 0)

// Pegadinhas com + e objetos
console.log([] + []); // ''
console.log([] + {}); // '[object Object]'
console.log({} + []); // 0 (interpretado como bloco + []) ou '[object Object]' no console?
// Na verdade, em muitos ambientes, {} é tratado como bloco, então {} + [] resulta em 0.
// Para evitar, use parênteses: ({} + []) retorna '[object Object]'

Boas práticas

Sempre que possível, use igualdade estrita (=== e !==) para evitar surpresas com coerção. Prefira conversão explícita com String(), Number() ou Boolean() em vez de depender da coerção implícita. Ao trabalhar com valores que podem ser null ou undefined, verifique explicitamente com === null ou === undefined.

Além disso, lembre-se de que NaN não é igual a si mesmo (NaN === NaN é false). Use isNaN() ou Number.isNaN() para verificar. Outra dica: ao converter strings para números, prefira Number() ou o operador unário + (ex: +'123') em vez de parseInt() ou parseFloat(), a menos que precise de parsing parcial.

Referências

Exercícios

  1. Qual é o resultado de '10' + 5? Explique com base na coerção implícita.

    ✓ Resposta: O resultado é a string '105'. O operador + com um operando string realiza concatenação, convertendo o número 5 em string e unindo as duas strings.
  2. Determine o valor de Number('') e Boolean(''). Justifique.

    ✓ Resposta: Number('') retorna 0 (string vazia é convertida para 0). Boolean('') retorna false (string vazia é falsy).
  3. Explique por que 0 == '0' é true em JavaScript, mas 0 === '0' é false.

    ✓ Resposta: O operador == realiza coerção de tipos: converte ambos para número (0 e 0), resultando em true. Já === compara sem coerção, e como os tipos são diferentes (number vs string), retorna false.
  4. Qual o resultado de true + false? Por quê?

    ✓ Resposta: O resultado é 1. O operador + converte booleanos para números: true vira 1, false vira 0, e a soma é 1.
  5. O que é retornado por typeof NaN e por que NaN === NaN é false?

    ✓ Resposta: typeof NaN retorna 'number', pois NaN é um valor numérico especial. NaN === NaN é false porque, por especificação, NaN não é igual a si mesmo (é o único valor em JavaScript que não é igual a si próprio).