Em JavaScript, os valores podem ser de tipos diferentes. Mudar o tipo de uma variável pode ser feito por meio de uma conversão de tipo explícita. Além disso, o JavaScript também realiza coerção de tipo (conversão de tipo implícita) quando o contexto exige.
O JavaScript não tem uma construção para converter para um tipo (diferente) como muitas outras linguagens, mas alguns recursos internos podem ser usados no lugar.
O mais notável é que os objetos globais Boolean, Number e String podem ser usados como funções para converter um valor para o tipo correspondente.
Com Boolean(value) você pode converter qualquer valor para um boolean.
Como isso funciona?
Existe um conjunto fixo de valores, os chamados valores falsy, que convertem para false.
O mais importante é que false, 0, string vazia, null, undefined e NaN são falsy.
O artigo da MDN sobre "Falsy" mostra a lista completa.
Para todos os outros valores, Boolean retorna true.
Esses valores são chamados de truthy.
Boolean(-1);
// => true
Boolean(0);
// => false
Boolean(' ');
// => true
Boolean('');
// => false
Repare que, por causa das regras descritas, '0', 'false', [] e {} são truthy em JavaScript.
Number(value) pode ser usado para converter um valor para um número.
Espaços em branco no início e no fim de uma string são ignorados, e uma string vazia é convertida para 0.
Se você tentar converter um valor não primitivo ou uma string que não representa um número, nenhum erro será lançado.
Em vez disso, o resultado é NaN (Not-A-Number).
Number(' -12.34 ');
// => -12.34
Number('1,2');
// => NaN
Number('1 2');
// => NaN
Number('');
// => 0
Number('10e3');
// => 10000
Number({ key: '123' });
// => NaN
Abaixo você pode ver o que Number retorna para outros valores primitivos.
Number(true);
// => 1
Number(false);
// => 0
Number(null);
// => 0
Number(undefined);
// => NaN
Repare que, ao contrário do último exemplo, Number() chamado sem nenhum argumento é definido para retornar 0.
O JavaScript também fornece as funções parseInt e parseFloat.
Elas aplicam regras mais frouxas quanto a quais strings podem ser convertidas para um número.
Por isso, prefira Number como função de conversão, para evitar resultados inesperados.
parseInt('123a45');
// => 123
Number('123a45');
// => NaN
Com String(value) você pode converter um valor para uma string.
Para valores primitivos, o resultado é o que você esperaria.
String(12.34);
// => '12.34'
String(false);
// => 'false'
String(null);
// => 'null'
String(undefined);
// => 'undefined'
Para arrays, a função String aplica a conversão para string a cada elemento e junta os resultados com uma vírgula.
Você também pode aplicar o método join por conta própria, por exemplo, para personalizar o separador.
No entanto, nesses casos null e undefined são convertidos para uma string vazia.
String([42, null, true, 'abc']);
// => '42,,true,abc'
Para objetos, por padrão String retorna um texto pouco útil.
String({ key: 'value' });
// => '[object Object]'
Você pode personalizar o comportamento da conversão, por exemplo, fornecendo um método toString.
A seção "Conversão de objeto para primitivo" do javascript.info explica os detalhes.
Outra forma comum de obter uma representação melhor em string para objetos e arrays é usar a codificação JSON.
Você pode converter para uma string com JSON.stringify e de volta para um objeto ou array com JSON.parse.
const obj = {
name: 'Gilda Guerra',
address: {
city: 'Goiânia',
},
};
JSON.stringify(obj);
// => '{"name":"Gilda Guerra","address":{"city":"Goiânia"}}'
Em certos contextos, o JavaScript converte automaticamente um valor para outro tipo de dado antes de avaliar alguma instrução. Essa conversão implícita é chamada de coerção de tipo.
Quando um valor é usado em um contexto booleano, o JavaScript aplica as mesmas regras da função Boolean para converter o valor implicitamente.
Quando a condição de uma condicional não é um boolean, aplica-se a coerção para determinar se a condição é satisfeita ou não.
O mesmo vale para o primeiro operando do operador ternário ?.
const num = 0;
if (num) {
// this block is NOT executed because 0 is falsy
}
const name = 'Jin';
name ? 'name was provided' : 'no name provided';
// => 'name was provided'
O operando do operador lógico de negação ! também é convertido para boolean antes de a operação de negação ser aplicada.
const name = '';
!name;
// => true
Um resultado do comportamento descrito é que !!value tem o mesmo efeito que Boolean(value).
Ainda assim, use Boolean pela legibilidade.
O JavaScript também aplica coerção aos operandos dos operadores lógicos AND (&&) e OR (||).
Mas lembre-se de que o resultado da expressão não é necessariamente um boolean.
Ele retorna um dos operandos originais (veja MDN sobre operadores lógicos).
null || 'hello';
// => 'hello'
Se o operador de adição + for usado com valores primitivos e um dos operandos for uma string, o outro também será convertido para string.
A lógica de conversão é a mesma da função String.
Depois, as duas strings são concatenadas.
let name;
'hello ' + name;
// => 'hello undefined'
A mesma conversão implícita acontece com valores que não são strings e que são embutidos em template strings.
const degrees = 23;
`It is ${degrees} °C`;
// => 'Is is 23 °C.';
Muitos operadores convertem os operandos para números (se necessário) de acordo com a lógica da função Number explicada acima.
+ (se nenhuma string estiver envolvida), -, *, /, %, **
+, -
>, >=, <, <=
|, &, ^, ~
Consulte a lista de operadores da MDN para mais detalhes sobre qualquer um desses operadores.
Quando um operando pode ser uma string, é melhor sempre converter explicitamente com a função Number para evitar erros.
'1' + '2';
// => '12'
// addition operator in string context as explained above
Number('1') + Number('2');
// => 3
Às vezes você verá o operador unário de adição sendo usado para converter uma string em um número.
Isso não é recomendado, porque é bem mais difícil de ler do que a chamada explícita a Number.
const value = '42';
+value;
// => 42
Number(value);
// => 42
Usar os operadores de igualdade e desigualdade flexíveis ==/!= também costuma envolver uma conversão implícita para número.
No entanto, a lógica exata desses operadores é bem complicada (veja MDN sobre igualdade flexível).
Os resultados são difíceis de prever e às vezes não são o que você esperaria.
Use os operadores de igualdade/desigualdade estritos ===/!== no lugar deles para evitar essas conversões implícitas.