JS: Conversión de tipos

En programación, la conversión de tipos de datos es el proceso mediante el cual se transforma el tipo de dato de un valor a otro. Por ejemplo, se puede convertir un número a una cadena de texto, o un texto a un valor booleano.

Debido a que JavaScript es un lenguaje de tipado dinámico (débilmente tipado), los valores de las variables, las constantes y las funciones no tienen un tipo fijo. Los tipos de datos pueden cambiar durante la ejecución del programa.

En JavaScript, hay dos tipos de conversión de tipos de datos:

Estas conversiones son esenciales para realizar operaciones y comparaciones de forma efectiva. Es fundamental entender este proceso, ya que la conversión implícita (o coerción) puede ocurrir de manera automática, siendo una fuente habitual de errores de lógica. En cambio, la conversión explícita se realiza de forma intencional, usando funciones y métodos incorporados en el propio lenguaje.

Conversión implícita

La conversión implícita, también llamada «coerción» ocurre cuando JavaScript convierte tipos de datos de forma automática. Este proceso sucede cuando se realiza una operación, como puede ser un cálculo aritmético o una comparación, y el motor necesita un tipo de dato diferente para poder evaluarla.

Por ejemplo, si usamos el operador de adición (+) cuyos operandos son un número (tipo number) y una cadena de texto (tipo string), el motor convertirá el número a cadena y realizará una concatenación. En cambio, si el operador es el de sustracción (-) y la cadena contiene un número válido, la cadena se convertirá a tipo number para efectuar la operación aritmética de forma correcta.

Vamos a verlos con más detalle.

Conversión implícita a cadena de texto

La coerción a cadena de texto ocurre cuando JavaScript necesita un valor de tipo string. Esto sucede, por ejemplo, al usar el operador de adición (+) cuando uno de los dos operandos es una cadena de texto y el otro no.

Las reglas de la coerción a cadena de texto son muy simples: todos los tipos de datos pueden ser convertidos a una representación textual usando su valor. Por ejemplo, true se convierte en 'true' y null en 'null'.

Por ejemplo:

'10' + 5000;  // '105000'
'10' + false; // '10false'
'10' + null;  // '10null'

En estos ejemplos, JavaScript convierte a cadena de texto (tipo string) los operandos «5000», «false» y «null» para realizar la concatenación.

Conversión implícita a número

La coerción a número se produce de forma automática cuando un valor de un tipo no numérico debe convertirse a number, porque así lo requiere la operación que se está realizando. Esto sucede con la mayoría de los operadores aritméticos (-, *, /, %) y de comparación relacional (<, >, <=, >=).

Existe una excepción importante: el operador de adición (+) no realiza la conversión implícita número cuando uno de los operandos es una cadena de texto. En tal caso, JS realiza una concatenación.

Estas son las reglas de la coerción a número:

Valor Conversión
Cadenas de texto con números (‘123’) Números
Cadenas de texto sin números (‘abc’) NaN
Cadenas vacías o con espacios (‘’) 0
El valor booleano true 1
El valor booleano false 0
La ausencia de valor (null) 0
Valor no asignado (undefined) NaN

Veamos algunos ejemplos para entenderlo mejor:

'10' / 5;     // 2 (10 / 5)
'10' - '5';   // 5 (10 - 5)
'10' - true;  // 9 (10 - 1)
'10' * false; // 0 (10 * 0)
'tp' / 50;    // NaN (NaN / 50)

En este ejemplo, las cadenas de texto ‘10’ y ‘5’ se convierten a números. Los valores booleanos true y false se convierten en 1 y 0, respectivamente. La cadena de texto ‘tp’ no contiene números, por tanto no puede realizar una operación y como resultado devuelve NaN (Not a Number).

Conversión de ‘null’ a número

El tipo de dato null (ausencia de valor) se convierte de forma automática a 0 cuando se usa como operando en un contexto que requiere un número.

Por ejemplo:

10 * null; // 0 (10 * 0)
10 - null; // 10 (10 - 0)
10 + null; // 10 (10 + 0)

Conversión de ‘undefined’ a número

El tipo de dato undefined (valor no asignado) siempre se convierte a NaN (Not a Number) cuando se usa con operadores aritméticos. De hecho, cualquier operación aritmética que incluya NaN será NaN.

10 * undefined; // NaN (10 * NaN)
10 - undefined; // NaN (10 - NaN)
10 + undefined; // NaN (10 + NaN)

Conversión implícita a booleano

La coerción a booleano se produce cuando un valor es evaluado en un contexto lógico, lo que requiere que el valor se interprete como verdadero o falso. Esto ocurre al aplicar el operador lógico NOT (!) de negación o al evaluar una estructura condicional, como puede ser un if o un while.

Los valores se convierten de forma automática a true o false dependiendo de su valor de verdad, conocido como la regla truthy o falsy.

Por tanto, la regla principal para la conversión automática de valores booleanos es la siguiente: los valores falsy como false, 0, '' (cadena vacía), null, undefined y NaN se convierten a false (falso). Por el contrario, el resto son truthy, en consecuencia se convierten a true (verdaderos).

Por ejemplo:

!true;  // false
!false; // true
!0;     // true (0 es falsy)
!1;     // false (1 es truthy)
!'';    // true (cadena vacía es falsy)
!'ABC'; // false (string es truthy)
!null;  // true (null es falsy)
!NaN;   // true (NaN es falsy)
!{};    // false (un objeto vacío es truthy)
![];    // false (un array vacío es truthy)

Como se puede ver, la negación de los valores falsy devuelve true, mientras que la negación de los valores truthy devuelve false.

Conversión explícita

La conversión explícita se realiza de forma intencional por parte del programador, ya sea mediante funciones o métodos integrados en el lenguaje: Number(), String() o Boolean(). Este tipo de conversión ofrece un mayor control sobre el resultado y, en general, es una buena práctica utilizarla.

Conversión explícita a cadena de texto

Para convertir cualquier tipo de dato a una cadena de texto, existen dos formas principales: usar el constructor String() o el método toString(). Según el contexto, nos interesará más una forma o la otra.

El constructor String() es la opción más segura cuando el tipo de dato es incierto (null o undefined), ya que no produce error en estos casos. Basta con indicar como parámetro el dato que queremos convertir a cadena de texto.

String(10);   // '10'
String(null); // 'null'
String(true); // 'true'

El método toString(), en cambio, se invoca de forma directa sobre el valor o la variable. Por ejemplo: miNumero.toString(). Sin embargo, no puede usarse con null y undefined, porque no tienen métodos asociados.

(10).toString();   // '10'
(null).toString(); // Error

Una ventaja de usar el método toString() es que permite especificar como parámetro la base numérica en la que se representará el número. Por ejemplo, se puede convertir un número de base decimal (o base 10) en una cadena de texto que muestre su valor en base binaria (o base 2); de esta manera:

(10).toString(2); // '1010'

Conversión explícita a número

Para convertir valores a tipo numérico (number) de forma intencional se pueden usar varias opciones: el constructor Number(), las funciones parseInt() y parseFloat(), o bien el operador «unario más» (+N).

El constructor Number() se usa indicando como parámetro el valor que se desea convertir a tipo number. Puede recibir cadenas de texto que contengan números, valores booleanos o el valor null. En cambio, si el valor es una cadena sin números o el valor undefined, devolverá NaN (Not a Number).

Number('10');  // 10
Number(true);  // 1
Number(false); // 0
Number(null);  // 0
Number('ABC'); // NaN

En lugar Number(), también puede usarse el operador «unario más» (+N) como prefijo. Funciona de forma equivalente, pero es más breve:

+'10';  // 10
+true;  // 1
+false; // 0
+null;  // 0

La función parseInt() convierte cadenas de texto a números enteros. Si el texto del parámetro indicado contiene un número con decimales, solo se conserva la parte entera. Además, acepta un segundo parámetro opcional para indicar la base numérica del primer parámetro (por defecto, base 10).

parseInt('10.95'); // 10
parseInt(10.9543); // 10
parseInt('ABCD');  // NaN
parseInt(false);   // NaN
parseInt(1010, 2); // 10

Por otro lado, parseFloat() permite convertir cadenas de texto a números de coma flotante (con decimales). Admite un solo parámetro, que si no es una cadena de texto, primero se convierte a texto antes de ser analizado.

parseFloat(3.14);     // 3.14
parseFloat("3.14");   // 3.14
parseFloat(" 3.14 "); // 3.14
parseFloat("FF2");    // NaN

Conversión explícita a booleano

Para convertir cualquier tipo de dato a un valor booleano (verdadero o falso) de forma voluntaria se utiliza el constructor Boolean(). Este proceso convierte los valores en función de si son considerados falsy o truthy. De forma alternativa también puede usarse la doble negación (!!).

Los valores falsy —que se convierten en false— son los siete siguientes: 0, '' (cadena vacía), null, undefined, NaN y false. Todos los demás valores se consideran truthy y, por lo tanto, se convierten en true.

Boolean(100);  // true
Boolean(0);    // false (0 es falsy)
Boolean("");   // false (cadena vacía es falsy)
Boolean(null); // false (null es falsy)
Boolean("Hi"); // true

En lugar Boolean(), también puede usarse el doble operador de negación (!!). El primer ! niega el valor de forma implícita, pero el segundo fuerza una nueva inversión, devolviendo el valor original ya convertido.

!!'ABC'; // true (string es truthy)
!!0;     // false
!!null;  // false
!!{};    // true
← Artículo anterior