Los mejores trucos de JavaScript no son magia negra: son funciones modernas que te ahorran lÃneas de código y errores tontos. Aquà tienes 12, ordenados de más útil a más avanzado.
Cada uno viene con su problema real, el código listo para copiar y el motivo por el que te conviene usarlo. Todo con sintaxis ES2023+, la que ya funciona en Node y en cualquier navegador actual. Si escribes JavaScript a diario, alguno de estos atajos va a entrar en tu rutina hoy mismo.
Por qué estos trucos JavaScript te ahorran tiempo
El lenguaje ha cambiado mucho desde ES6. Muchas cosas que antes resolvÃas con tres lÃneas y una función auxiliar hoy son una sola expresión nativa. Menos código propio significa menos bugs, menos dependencias y menos tiempo revisando lo que ya resuelve el motor.
1. Optional chaining (?.): acceso seguro sin reventar
El problema: accedes a una propiedad anidada y si un nivel intermedio no existe, salta el clásico Cannot read properties of undefined. El operador ?. corta la cadena y devuelve undefined en lugar de tirar todo abajo.
const user = { perfil: { nombre: "Ana" } };
// Sin optional chaining: error si no existe direccion
const ciudad = user?.direccion?.ciudad; // undefined, sin error
// También funciona con métodos y con Ãndices
user.guardar?.(); // solo llama si guardar existe
const primero = lista?.[0];
Por qué te conviene: te libras de encadenar if y comprobaciones defensivas. Ideal para datos de una API que a veces vienen incompletos. CombÃnalo con el truco 2 y tienes acceso seguro con valor por defecto en una lÃnea. Detalle en MDN.
2. Nullish coalescing (??): el valor por defecto que sà respeta el 0
El problema: usas || para poner un valor por defecto y te muerde con el 0, el "" o el false, porque son «falsy». El operador ?? solo entra cuando el valor es null o undefined.
const cantidad = 0;
const stock = cantidad ?? 10; // 0 (correcto)
const stockMal = cantidad || 10; // 10 (bug silencioso)
Por qué te conviene: es de los bugs más difÃciles de cazar, porque a veces funciona y a veces no. Usa ?? siempre que un valor legÃtimo pueda ser 0 o cadena vacÃa. Referencia en MDN.
3. at(-1): el último elemento sin contar la longitud
El problema: para el último elemento de un array escribes lista[lista.length - 1]. Funciona, pero es ruido. El método at() acepta Ãndices negativos y lee desde el final.
const lista = ["a", "b", "c"];
const ultimo = lista.at(-1); // "c"
const penultimo = lista.at(-2); // "b"
// También en strings
"hola".at(-1); // "a"
Por qué te conviene: se lee de un vistazo y evita repetir el nombre de la variable. Pequeño, pero lo vas a usar constantemente. Ver Array.prototype.at() en MDN.
4. Set: elimina duplicados de un array en una lÃnea
El problema: quieres valores únicos de un array. Antes montabas un bucle con un objeto acumulador. Un Set solo guarda valores únicos, asà que conviértelo y vuélvelo a array.
const numeros = [1, 2, 2, 3, 3, 3];
const unicos = [...new Set(numeros)]; // [1, 2, 3]
// Cuenta elementos distintos sin duplicar lógica
const distintos = new Set(numeros).size; // 3
Por qué te conviene: es rápido, legible y funciona con strings, números y referencias. Para tags, categorÃas o IDs repetidos es mi opción por defecto. Más en MDN.
5. Operadores de asignación lógica (??=, ||=, &&=)
El problema: quieres asignar un valor solo si la variable está vacÃa. EscribÃas if (!config.timeout) config.timeout = 3000;. Los operadores de asignación lógica lo comprimen.
const config = { timeout: undefined };
config.timeout ??= 3000; // asigna solo si es null/undefined
config.retries ||= 3; // asigna si es "falsy"
config.debug &&= false; // asigna solo si ya es "truthy"
Por qué te conviene: configuras opciones por defecto sin lÃneas if sueltas. El ??= es el más seguro porque, igual que el truco 2, respeta el 0 y la cadena vacÃa.
6. Destructuring con defaults y renombrado
El problema: extraer varias propiedades de un objeto, darles nombre nuevo y un valor por defecto, todo a la vez. El destructuring lo hace en una sola expresión.
const usuario = { nombre: "Ana", rol: "admin" };
// Renombra rol a permiso y pon defaults
const { nombre = "Anónimo", rol: permiso = "lector" } = usuario;
// Salta posiciones de un array
const [primero, , tercero] = ["a", "b", "c"];
// Parámetros con objeto por defecto (evita error si no pasas nada)
function crear({ ancho = 100, alto = 100 } = {}) {
return { ancho, alto };
}
Por qué te conviene: firmas de funciones más limpias y menos variables intermedias. El truco del = {} al final evita que reviente cuando llamas a la función sin argumentos.
7. structuredClone: copia profunda de verdad
El problema: el spread {...obj} solo copia el primer nivel. El viejo truco JSON.parse(JSON.stringify(obj)) pierde Date, Map, Set y revienta con referencias circulares. structuredClone es la función nativa que clona en profundidad de forma correcta.
const original = {
fecha: new Date(),
tags: new Set(["js"]),
meta: { anidado: true }
};
const copia = structuredClone(original);
copia.meta.anidado = false;
original.meta.anidado; // true (no se ha tocado)
Por qué te conviene: es global en navegadores modernos y en Node 17+. Se acabó importar una librerÃa solo para clonar un objeto. Detalle en MDN.
8. Intl.NumberFormat: moneda y números bien formateados
El problema: mostrar precios con separadores de miles y sÃmbolo de moneda correcto por región. Nada de concatenar strings a mano. Intl.NumberFormat lo resuelve según el idioma.
const precio = 1234.5;
const mxn = new Intl.NumberFormat("es-MX", {
style: "currency",
currency: "MXN"
}).format(precio); // "$1,234.50"
const eur = new Intl.NumberFormat("es-ES", {
style: "currency",
currency: "EUR"
}).format(precio); // "1234,50 €"
Por qué te conviene: respeta comas, puntos y posición del sÃmbolo según el paÃs sin que tú controles cada caso. Sirve también para porcentajes y unidades. Ver MDN.
9. Intl.RelativeTimeFormat: «hace 2 dÃas» sin librerÃas
El problema: mostrar tiempos relativos tipo «hace 3 horas» o «en 2 dÃas». Antes tirabas de una dependencia entera. Intl.RelativeTimeFormat lo hace nativo y traducido.
const rtf = new Intl.RelativeTimeFormat("es", { numeric: "auto" });
rtf.format(-2, "day"); // "anteayer"
rtf.format(-3, "hour"); // "hace 3 horas"
rtf.format(1, "week"); // "la próxima semana"
Por qué te conviene: el parámetro numeric: "auto" te da expresiones naturales como «ayer» en vez de «hace 1 dÃa». Menos peso en el bundle y traducciones gratis. Más en MDN.
10. Object.groupBy: agrupa un array por clave
El problema: agrupar un array de objetos por una propiedad. El clásico reduce con acumulador funciona, pero es verboso. Object.groupBy (ES2024) lo hace en una llamada.
const productos = [
{ nombre: "Camiseta", tipo: "ropa" },
{ nombre: "Taza", tipo: "hogar" },
{ nombre: "Gorra", tipo: "ropa" }
];
const porTipo = Object.groupBy(productos, p => p.tipo);
// { ropa: [Camiseta, Gorra], hogar: [Taza] }
Por qué te conviene: el callback devuelve la clave y el método arma los grupos por ti. Es reciente, asà que compruébalo en tu entorno: necesita Node 21+ o navegadores actuales. Referencia en MDN.
11. Promise.allSettled: varias peticiones sin que una tumbe al resto
El problema: lanzas varias promesas con Promise.all y, si una falla, pierdes todos los resultados. Promise.allSettled espera a todas y te dice cuáles salieron bien y cuáles no.
const resultados = await Promise.allSettled([
fetch("/api/a"),
fetch("/api/b"),
fetch("/api/c")
]);
for (const r of resultados) {
if (r.status === "fulfilled") console.log("OK", r.value);
else console.warn("Falló", r.reason);
}
Por qué te conviene: perfecto cuando cargas datos de varias fuentes y quieres mostrar lo que sà llegó. Cada resultado trae su status, asà que gestionas los fallos uno a uno. Ver MDN.
12. Array.from: genera secuencias sin bucles
El problema: necesitas un array de números del 1 al 10, o una rejilla de N elementos. En lugar de un for, Array.from acepta una longitud y una función de mapeo.
// Números del 1 al 10
const rango = Array.from({ length: 10 }, (_, i) => i + 1);
// 5 objetos vacÃos con id
const filas = Array.from({ length: 5 }, (_, i) => ({ id: i }));
// Convierte un iterable (NodeList, string) en array real
const letras = Array.from("hola"); // ["h","o","l","a"]
Por qué te conviene: el segundo argumento es un map integrado, asà que generas y transformas en un paso. Genial para paginación, calendarios o datos de prueba. Si aún encadenas map, filter y reduce, este cierra la caja de herramientas.
Recursos para seguir practicando
Los trucos se fijan usándolos. Aquà tienes por dónde seguir dentro del blog:
- Ponlos en marcha con proyectos de JavaScript para practicar.
- Da el salto a arquitectura con los patrones de diseño en JavaScript.
- Si te toca el backend, empieza por Node.js y npm para principiantes.
- ¿Aún montas la base? Repasa cómo crear una página web con HTML.
Preguntas frecuentes sobre trucos de JavaScript
¿Estos trucos JavaScript funcionan en todos los navegadores?
La mayorÃa sÃ: optional chaining, nullish coalescing, Set o destructuring llevan años en todos los navegadores actuales. Los más recientes, como Object.groupBy, necesitan versiones nuevas. Ante la duda, compruébalo en MDN o en tu propio entorno antes de subirlo a producción.
¿Qué significa ES2023 y por qué importa?
ES2023 es una edición del estándar ECMAScript, la especificación en la que se basa JavaScript. Cada año añade funciones nuevas. Usar sintaxis moderna te da código más corto y menos dependencias externas, siempre que tu entorno la soporte.
¿Cuándo uso ?? en lugar de ||?
Usa ?? cuando un valor legÃtimo pueda ser 0, cadena vacÃa o false. El operador || los trata como vacÃos y mete el valor por defecto por error. El ?? solo actúa ante null o undefined.
¿structuredClone reemplaza a las librerÃas de clonado?
Para la mayorÃa de casos, sÃ. Clona objetos anidados, fechas, Map y Set sin dependencias. No copia funciones ni prototipos personalizados, asà que para clases con métodos propios sigue evaluando tu caso concreto.
Guárdate esta lista y ve incorporando un truco por semana. Si te ha venido bien, compártela con quien esté aprendiendo JavaScript. Que lo disfrutes!


