Em JavaScript, os valores podem ser de tipos diferentes. Podes alterar o tipo de uma variável através de uma conversão de tipos explícita. Além disso, o JavaScript também realiza coerção de tipos (conversão de tipos implícita) quando o contexto o exige.
O JavaScript não tem um construto para converter para um tipo (diferente), como acontece em muitas outras linguagens, mas podes usar alguns auxiliares incorporados em alternativa.
Em particular, os objetos globais Boolean, Number e String podem ser usados como funções para converter um valor para o tipo correspondente.
Com Boolean(value) podes converter qualquer valor para Boolean.
Como é que isso funciona?
Existe um conjunto fixo de valores, os chamados valores falsy, que são convertidos para false.
Os mais importantes são false, 0, a string vazia, null, undefined e NaN, que são todos falsy.
O artigo da MDN sobre "Falsy" mostra a lista completa.
Para todos os outros valores, Boolean devolve true.
Esses valores chamam-se truthy.
Boolean(-1);
// => true
Boolean(0);
// => false
Boolean(' ');
// => true
Boolean('');
// => false
Repara que, por causa das regras descritas, '0', 'false', [] e {} são truthy em JavaScript.
Number(value) pode ser usado para converter um valor num número.
Os espaços em branco no início e no fim de uma string são ignorados e uma string vazia é convertida em 0.
Se tentares converter um valor não primitivo ou uma string que não representa um número, não será lançado nenhum erro.
Em vez disso, o resultado é NaN (não é um número).
Number(' -12.34 ');
// => -12.34
Number('1,2');
// => NaN
Number('1 2');
// => NaN
Number('');
// => 0
Number('10e3');
// => 10000
Number({ key: '123' });
// => NaN
Abaixo podes ver o que Number devolve para outros valores primitivos.
Number(true);
// => 1
Number(false);
// => 0
Number(null);
// => 0
Number(undefined);
// => NaN
Repara que, ao contrário do último exemplo, Number() chamado sem qualquer argumento está definido para devolver 0.
O JavaScript também fornece as funções parseInt e parseFloat.
Eles aplicam regras mais permissivas quanto às strings que podem ser convertidas num número.
Por isso, deves preferir Number como função de conversão, para evitares resultados inesperados.
parseInt('123a45');
// => 123
Number('123a45');
// => NaN
Com String(value) podes converter um valor numa string.
Para valores primitivos, o resultado é o que esperarias.
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.
Também podes aplicar o próprio método join, por exemplo para personalizar o separador.
No entanto, nestes casos null e undefined são convertidos numa string vazia.
String([42, null, true, 'abc']);
// => '42,,true,abc'
Para objetos, por predefinição o String devolve um texto pouco útil.
String({ key: 'value' });
// => '[object Object]'
Podes personalizar o comportamento da conversão, por exemplo fornecendo um método toString.
A secção "Conversão de objetos para valores primitivos" no javascript.info explica os detalhes.
Outra forma comum de obter uma melhor representação em string de objetos e arrays é usar a codificação JSON.
Podes converter para 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 dados antes de avaliar uma instrução. Esta conversão implícita chama-se coerção de tipos.
Quando um valor é usado num contexto booleano, o JavaScript aplica as mesmas regras da função Boolean para converter implicitamente o valor.
Quando a condição de uma condicional não é um Boolean, é aplicada coerção para determinar se a condição é satisfeita ou não.
O mesmo se aplica ao 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 NOT ! também sofre coerção para Boolean antes de a operação NOT ser aplicada.
const name = '';
!name;
// => true
Uma consequência do comportamento descrito é que !!value tem o mesmo efeito que Boolean(value).
Ainda assim, deves usar Boolean por questões de legibilidade.
O JavaScript também aplica coerção aos operandos dos operadores lógicos AND (&&) e OR (||).
Mas tem em atenção que o resultado da expressão não é necessariamente um Boolean.
Ele devolve um dos operandos originais (vê a 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 sofre coerção para string.
A lógica de conversão é a mesma que quando usas a função String.
Depois, as duas strings são concatenadas.
let name;
'hello ' + name;
// => 'hello undefined'
A mesma conversão implícita acontece para valores que não são strings e que estão incorporados em template strings.
const degrees = 23;
`It is ${degrees} °C`;
// => 'Is is 23 °C.';
Muitos operadores convertem os operandos em números (se necessário) de acordo com a lógica da função Number explicada acima.
+ (se não estiver envolvida nenhuma string), -, *, /, %, **
+, -
>, >=, <, <=
|, &, ^, ~
Consulta a lista de operadores da MDN para mais detalhes sobre qualquer um destes operadores.
Quando um operando pode ser uma string, o melhor é converter sempre 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 vais ver o operador unário de mais a ser usado para converter uma string num número.
Não é recomendável, porque é muito 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 não estritos ==/!= também envolve muitas vezes uma conversão implícita num número.
No entanto, a lógica exata destes operadores é bastante complicada (vê a MDN sobre igualdade não estrita).
Os resultados são difíceis de prever e às vezes não são o que esperarias.
Usa antes os operadores de igualdade/desigualdade estrita ===/!== para evitares estas conversões implícitas.