15 funciones de JavaScript que los desarrolladores senior usan realmente en 2026

Guía práctica en español con 15 funciones modernas de JavaScript, ejemplos ejecutables y consejos desde la perspectiva de un desarrollador senior.
Conocer la sintaxis de JavaScript no significa escribir código que un equipo pueda mantener con seguridad. El código profesional es más claro y trata de forma explícita los errores, la cancelación, la forma de los datos y el rendimiento.
Esta guía explica 15 características modernas que los desarrolladores con experiencia usan en aplicaciones reales. La meta no es usar sintaxis ingeniosa en todas partes, sino reducir la ambigüedad.
1. Optional chaining y nullish coalescing
?. permite acceder a propiedades de forma segura cuando el valor es null o undefined. ?? usa un valor predeterminado solo cuando faltan esos valores.
function getCustomerLabel(order) {
const name = order.customer?.profile?.displayName ?? 'Guest';
const points = order.customer?.loyaltyPoints ?? 0;
return `${name} (${points} points)`;
}
Si 0, false o una cadena vacía son valores válidos, usa ?? en vez de ||. No uses ?. para ocultar un estado que tu aplicación debería garantizar.
2. Destructuring con valores predeterminados
Destructuring muestra la forma de datos que espera una función.
function createAccount({ email, role = 'member', notifications = true }) {
if (!email) throw new Error('email is required');
return { email, role, notifications };
}
También puedes renombrar campos de una API, por ejemplo created_at: createdAt. Si hay demasiados parámetros, quizá la función tenga demasiadas responsabilidades.
3. Async/await con límites de error claros
async y await hacen que el flujo asíncrono sea fácil de leer, pero el código profesional también decide dónde tratar el error.
async function loadDashboard(userId) {
const response = await fetch(`/api/users/${userId}/dashboard`);
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
return response.json();
}
No captures un error para devolver undefined sin una razón. Eso convierte un fallo claro en un problema confuso posterior.
4. Promise.all para trabajos independientes
Las peticiones independientes pueden ejecutarse en paralelo; los pasos dependientes deben esperar en orden.
const [profile, projects, alerts] = await Promise.all([
fetchProfile(userId), fetchProjects(userId), fetchAlerts(userId),
]);
Usa Promise.allSettled() cuando necesites conocer cada resultado aunque una tarea falle. Para miles de tareas, utiliza una cola o un límite de concurrencia.
5. AbortController para cancelar
AbortController cancela búsquedas antiguas o peticiones que ya no son necesarias.
const controller = new AbortController();
const response = await fetch('/api/products?q=rust', {
signal: controller.signal,
});
controller.abort();
Distingue una cancelación esperada de un error real para no llenar el monitoreo de falsos errores.
6. Spread sin mutaciones accidentales
const nextUser = {
...user,
preferences: { ...user.preferences, theme: 'dark' },
};
Spread crea una copia superficial. Para datos estructurados puedes usar structuredClone(), aunque no clona funciones ni nodos DOM.
7. Map y Set para el modelo correcto
Usa Set para valores únicos y Map para claves dinámicas.
const uniqueTags = [...new Set(['js', 'api', 'js'])];
const counts = new Map();
counts.set('javascript', (counts.get('javascript') ?? 0) + 1);
Esto evita también colisiones con propiedades heredadas de los objetos normales.
8. Métodos de arrays que expresan intención
map() transforma, filter() selecciona, find() obtiene la primera coincidencia, some() comprueba si existe alguna y every() comprueba todas.
const activeEmails = users
.filter((user) => user.isActive)
.map((user) => user.email);
No conviertas todos los bucles en reduce(). Para lógica de varios pasos o salidas tempranas, for...of suele ser más claro.
9. Agrupación legible con Object.groupBy
En entornos compatibles, Object.groupBy() evita reducers repetitivos.
const ticketsByStatus = Object.groupBy(tickets, (ticket) => ticket.status);
Comprueba las versiones de los navegadores y de Node.js antes de adoptar una función nueva.
10. Campos privados de clase
Los campos que empiezan con # están protegidos por el lenguaje, no solo por una convención de nombres.
class RateLimiter {
#requests = 0;
constructor(limit) { this.limit = limit; }
tryConsume() {
if (this.#requests >= this.limit) return false;
this.#requests += 1; return true;
}
}
La privacidad protege invariantes, pero las clases deben seguir teniendo una responsabilidad clara.
11. Módulos e importación dinámica
import y export hacen explícitas las dependencias. import() carga código solo cuando hace falta.
async function openChart(data) {
const { renderChart } = await import('./chart.js');
return renderChart(data);
}
Es útil para gráficos, editores y pantallas administrativas que no todos los usuarios necesitan al iniciar la aplicación.
12. Intl para formatos locales
Usa Intl para fechas, números, monedas y listas en lugar de concatenar texto manualmente.
const price = new Intl.NumberFormat('es-ES', {
style: 'currency', currency: 'EUR',
}).format(1299.5);
Así reduces errores de idioma, formato y moneda.
13. URL y URLSearchParams
Concatenar strings puede romper URLs que contienen espacios, & o caracteres Unicode.
const url = new URL('/api/articles', window.location.origin);
url.searchParams.set('language', 'es');
url.searchParams.set('query', 'async JavaScript');
fetch(url);
14. Errores personalizados con contexto
Las clases de error permiten distinguir validación, permisos, red y errores del dominio.
class ValidationError extends Error {
constructor(message, details = {}) {
super(message); this.name = 'ValidationError'; this.details = details;
}
}
Nunca incluyas contraseñas, tokens o datos personales en errores y registros.
15. Closures para estado controlado
Una closure conserva su estado sin exponerlo globalmente.
function createIdGenerator(prefix = 'item') {
let current = 0;
return () => `${prefix}-${++current}`;
}
Son útiles para fábricas, memoización y callbacks. No captures objetos grandes innecesariamente en listeners de larga duración.
Ejemplo práctico de nivel senior
async function findUsers({ query, page = 1, signal } = {}) {
const normalizedQuery = query?.trim();
if (!normalizedQuery) throw new ValidationError('La búsqueda es obligatoria');
const url = new URL('/api/users', window.location.origin);
url.searchParams.set('q', normalizedQuery);
url.searchParams.set('page', String(page));
const response = await fetch(url, { signal });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const payload = await response.json();
return { users: payload.data ?? [], total: payload.meta?.total ?? 0 };
}
La parte profesional está en las decisiones: validar pronto, codificar la URL, cancelar, rechazar respuestas HTTP fallidas y devolver un resultado predecible.
Errores comunes que debes evitar
- Ocultar estados inválidos con
?.. - Convertir cada bucle en una cadena densa de métodos.
- Ejecutar peticiones dependientes dentro de
Promise.all(). - Crear tareas simultáneas sin límite.
- Pensar que spread crea una copia profunda.
- Capturar errores sin tratarlos o volver a lanzarlos.
- Usar funciones nuevas sin comprobar el entorno soportado.
- Añadir abstracciones antes de tener un problema repetido real.
Conclusión
El JavaScript de nivel senior no consiste en mostrar cuántas funciones conoces. Consiste en hacer evidente el comportamiento, conservar los valores válidos, elegir la estructura correcta y tratar los fallos de forma deliberada. Empieza por las funciones que eliminen más ambigüedad de tu código actual.
Lecturas recomendadas
Artículos destacados
Detección de objetos con YOLO: Guía práctica completa para desarrolladores
Guía integral para desarrollar con YOLO: conceptos, datos, entrenamiento, evaluación, tiempo real, API de producción, rendimiento, seguridad y entrevistas.
¿Qué es una estampida de caché y cómo evitarla en Laravel?
Una estampida de caché ocurre cuando muchas solicitudes pierden la misma clave caducada y regeneran los datos a la vez. Esta guía explica cómo prevenirla en Laravel con bloqueos atómicos, stale-while-revalidate, TTL jitter y respuestas de respaldo.

Por qué un CLAUDE.md sencillo mejora a los agentes de programación con IA
La configuración más eficaz puede ser un archivo breve que enseñe al agente cómo trabajar, no solo qué debe construir. Los agentes de programación con IA resultan impresionantes en una demostración. El repositorio es pequeño, el objetivo es evidente y una suposición equivocada cu
Comentarios
0 comentariosTodavía no hay comentarios aprobados. Las respuestas nuevas pueden esperar moderación.