
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.
?. 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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);
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.
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.
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.
?..Promise.all().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.
Todavía no hay comentarios aprobados. Las respuestas nuevas pueden esperar moderación.