Ir al contenido principal

Conversión entre tipos

Introducción

En JavaScript, la conversión entre tipos de datos es una operación muy común y fundamental para el desarrollo de aplicaciones. Debido a que JavaScript es un lenguaje de tipado dinámico, a menudo necesitamos convertir valores de un tipo a otro para realizar operaciones específicas o para garantizar el comportamiento esperado de nuestro código. Por ejemplo, podríamos necesitar convertir el texto de un campo de formulario (que siempre es de tipo string) a un número para realizar cálculos, o quizás convertir un número a string para mostrarlo con formato específico.

En este artículo, exploraremos los diferentes métodos y técnicas para convertir valores entre los distintos tipos de datos en JavaScript, entenderemos cuándo ocurren las conversiones automáticas y cómo podemos controlar estos procesos para evitar errores comunes.

Conversión implícita vs. explícita

En JavaScript existen dos formas principales de convertir entre tipos de datos:

Conversión implícita (coerción)

La conversión implícita ocurre cuando JavaScript convierte automáticamente un valor de un tipo a otro sin que nosotros lo solicitemos explícitamente. Esto suele ocurrir en operaciones entre valores de diferentes tipos.

// Coerción de number a string en una concatenación
let edad = 25;
let mensaje = "Tengo " + edad + " años"; // edad se convierte implícitamente a string
console.log(mensaje); // "Tengo 25 años"

// Coerción de string a number en una resta
let precioTexto = "100";
let descuento = 20;
let precioFinal = precioTexto - descuento; // precioTexto se convierte implícitamente a number
console.log(precioFinal); // 80

La conversión implícita puede ser útil, pero también puede generar comportamientos inesperados si no se comprende bien cómo funciona:

// Comportamiento inesperado en suma
let cantidad = "10";
let unidades = 5;
let total = cantidad + unidades; // Aquí, unidades se convierte a string
console.log(total); // "105" (concatenación de strings, no suma)

Conversión explícita

La conversión explícita ocurre cuando utilizamos funciones o métodos específicos para convertir intencionalmente un valor de un tipo a otro.

// Conversión explícita de string a number
let precioTexto = "100";
let precioNumero = Number(precioTexto);
console.log(precioNumero); // 100 (ahora es un number)

// Conversión explícita de number a string
let cantidad = 42;
let cantidadTexto = String(cantidad);
console.log(cantidadTexto); // "42" (ahora es un string)

La conversión explícita es preferible en muchos casos porque hace que nuestras intenciones sean claras y evita ambigüedades.

Conversión a string

Existen varias formas de convertir valores a strings:

Método toString()

La mayoría de los valores en JavaScript tienen un método toString() que los convierte a su representación en string:

let numero = 123;
let textoNumero = numero.toString();
console.log(textoNumero); // "123"
console.log(typeof textoNumero); // "string"

let booleano = true;
let textoBooleano = booleano.toString();
console.log(textoBooleano); // "true"

El método toString() para números acepta un parámetro opcional que indica la base numérica:

let num = 15;
console.log(num.toString()); // "15" (decimal por defecto)
console.log(num.toString(2)); // "1111" (binario)
console.log(num.toString(16)); // "f" (hexadecimal)

Sin embargo, hay que tener cuidado con null y undefined, ya que no tienen el método toString():

// Esto generaría un error
// let nulo = null;
// let textoNulo = nulo.toString(); // Error: Cannot read property 'toString' of null

Función String()

La función global String() es más segura porque también funciona con null y undefined:

let nulo = null;
let indefinido = undefined;

console.log(String(nulo)); // "null"
console.log(String(indefinido)); // "undefined"

let numero = 42;
console.log(String(numero)); // "42"

Concatenación con string vacío

Una forma rápida (aunque menos explícita) es concatenar cualquier valor con un string vacío:

let numero = 123;
let texto = numero + "";
console.log(texto); // "123"
console.log(typeof texto); // "string"

Conversión a número

Para convertir valores a números, también disponemos de varias opciones:

Función Number()

La función global Number() intenta convertir un valor a un número:

let texto = "42";
let numero = Number(texto);
console.log(numero); // 42
console.log(typeof numero); // "number"

// Conversión de booleanos
console.log(Number(true)); // 1
console.log(Number(false)); // 0

// Valores que no son números válidos
console.log(Number("Hola")); // NaN (Not a Number)
console.log(Number("42px")); // NaN

// Valores especiales
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN

Funciones parseInt() y parseFloat()

Estas funciones son más específicas y ofrecen un mejor control para convertir strings a números:

  • parseInt(): Convierte a números enteros
  • parseFloat(): Convierte a números con decimales
// Uso básico
console.log(parseInt("42")); // 42
console.log(parseFloat("3.14")); // 3.14

// parseInt con números en diferentes bases
console.log(parseInt("1111", 2)); // 15 (binario a decimal)
console.log(parseInt("FF", 16)); // 255 (hexadecimal a decimal)

// Manejo de caracteres no numéricos
console.log(parseInt("42px")); // 42 (se detiene al encontrar un carácter no numérico)
console.log(parseFloat("3.14 metros")); // 3.14

// Comportamiento con decimales
console.log(parseInt("42.9")); // 42 (trunca los decimales)
console.log(parseFloat("42.9")); // 42.9

La función parseInt() es particularmente útil cuando trabajamos con CSS o cuando necesitamos extraer valores numéricos de una cadena que contiene unidades.

Operador unario +

El operador + colocado antes de un valor intenta convertirlo a número:

let texto = "42";
let numero = +texto;
console.log(numero); // 42
console.log(typeof numero); // "number"

console.log(+"3.14"); // 3.14
console.log(+true); // 1
console.log(+false); // 0
console.log(+"abc"); // NaN

Este método es conciso pero puede reducir la legibilidad del código, especialmente para principiantes.

Conversión a booleano

Convertir valores a booleanos es esencial para las estructuras de control como condicionales y bucles.

Función Boolean()

La función global Boolean() convierte cualquier valor a su equivalente booleano:

console.log(Boolean(1)); // true
console.log(Boolean(0)); // false
console.log(Boolean(-5)); // true (cualquier número distinto de 0 es true)

console.log(Boolean("")); // false (string vacío)
console.log(Boolean("Hola")); // true (cualquier string no vacío)

console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false

console.log(Boolean({})); // true (objetos siempre son true)
console.log(Boolean([])); // true (arrays también son objetos)

Operador lógico doble negación (!!)

Dos signos de negación consecutivos (!!) convierten cualquier valor a su equivalente booleano:

console.log(!!"Hola"); // true
console.log(!!0); // false
console.log(!!null); // false
console.log(!!{}); // true

Este operador funciona negando el valor (lo que lo convierte a booleano) y luego negando nuevamente para volver al valor booleano original.

Coerción en expresiones y operaciones

La coerción o conversión implícita ocurre en varias situaciones:

Operaciones aritméticas

// En la suma, los strings tienen prioridad
console.log(10 + "20"); // "1020" (number → string)

// En otras operaciones aritméticas, los numbers tienen prioridad
console.log("20" - 10); // 10 (string → number)
console.log("20" * 2); // 40 (string → number)
console.log("20" / 5); // 4 (string → number)

Operadores de comparación

// Comparación con ==
console.log(5 == "5"); // true (string → number)
console.log(true == 1); // true (boolean → number)
console.log(null == undefined); // true (caso especial)

// Comparación estricta con === (sin coerción)
console.log(5 === "5"); // false (tipos diferentes)
console.log(true === 1); // false (tipos diferentes)

Operaciones lógicas

// Los valores se convierten a booleanos en contextos de condición
let nombre = "Ana";
if (nombre) {
    console.log("El nombre existe"); // Se ejecuta porque nombre no está vacío
}

// Operador &&
console.log(5 && "texto"); // "texto" (devuelve el último valor evaluado)
console.log(0 && "texto"); // 0 (se detiene en el primer valor falsy)

// Operador ||
console.log("texto" || 0); // "texto" (primer valor truthy)
console.log("" || "valor predeterminado"); // "valor predeterminado" (segundo valor)

Casos problemáticos de conversión

Algunas conversiones pueden dar resultados inesperados si no se comprenden bien:

Concatenación vs. suma

let a = 5;
let b = "10";

console.log(a + b); // "510" (concatenación, no suma)
console.log(a + Number(b)); // 15 (suma)

Valores vacíos

console.log(Number("")); // 0 (string vacío → 0)
console.log(parseInt("")); // NaN (parseInt espera caracteres numéricos)

Objetos y arrays

console.log("10" + {}); // "10[object Object]"
console.log(10 + {}); // "10[object Object]"

console.log("10" + []); // "10"
console.log(10 + []); // "10"

console.log("10" + [1, 2]); // "101,2"

NaN (Not a Number)

El valor NaN merece atención especial:

console.log(Number("Hola")); // NaN

// Característica peculiar: NaN no es igual a sí mismo
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false

// Para comprobar si un valor es NaN, usamos isNaN() o Number.isNaN()
console.log(isNaN(NaN)); // true
console.log(isNaN("Hola")); // true (porque "Hola" se convierte a NaN)
console.log(Number.isNaN("Hola")); // false (más estricto, no hace coerción)
console.log(Number.isNaN(NaN)); // true

Buenas prácticas para evitar errores

Para evitar problemas con las conversiones de tipos, te recomendamos seguir estas prácticas:

  1. Usa conversiones explícitas:

    // En lugar de esto:
    let total = cantidad + "10";
    
    // Haz esto:
    let total = cantidad + Number("10");
    
  2. Utiliza comparación estricta (=== y !==):

    // Evita:
    if (valor == 42) { /* ... */ }
    
    // Prefiere:
    if (valor === 42) { /* ... */ }
    
  3. Valida entradas de usuario:

    function calcularTotal(precio) {
        precio = Number(precio);
        if (isNaN(precio)) {
            return "Por favor, introduce un número válido";
        }
        return precio * 1.21; // Precio con IVA
    }
    
  4. Sé explícito en tus intenciones:

    // En lugar de confiar en la coerción automática
    let edadEnTexto = edad + "";
    
    // Sé explícito
    let edadEnTexto = String(edad);
    
  5. Conoce los falsy values (valores que se consideran falsos en contextos booleanos):

    • false
    • 0 (cero)
    • "" (string vacío)
    • null
    • undefined
    • NaN

Resumen

La conversión entre tipos en JavaScript es un tema fundamental que debes dominar para escribir código robusto. Hemos visto cómo convertir valores entre diferentes tipos utilizando métodos explícitos como String(), Number() y Boolean(), así como los mecanismos de coerción implícita que JavaScript aplica en distintas operaciones.

Comprender estos conceptos te ayudará a evitar errores comunes y te permitirá tener un mayor control sobre el comportamiento de tu código. Recuerda que en la mayoría de los casos, es preferible utilizar conversiones explícitas para hacer que tus intenciones sean claras y reducir la posibilidad de comportamientos inesperados.

En el próximo artículo, exploraremos los operadores aritméticos en JavaScript y cómo se comportan con los diferentes tipos de datos que hemos aprendido hasta ahora.