Regla
No abuse sin documentar anónimas .
Las anónimo sin sin documentación
son difíciles de comprender y reutilizar.
Idiomas admitidos: 45+Introducción
Las funciones anónimas pasadas como callbacks o manejadores de eventos ocultan su propósito detrás de detalles de implementación. Una función flecha de 20 líneas en un .map() o .filter() obliga a los lectores a analizar toda la lógica para entender qué transformación ocurre. Las funciones con nombre y nombres descriptivos documentan la intención de inmediato, y la lógica compleja se puede entender leyendo el nombre de la función antes de profundizar en la implementación.
Ejemplos de código
❌ No conforme:
app.get('/users', async (req, res) => {
const users = await db.users.find({});
const processed = users.filter(u => {
const hasActiveSubscription = u.subscriptions?.some(s =>
s.status === 'active' && new Date(s.expiresAt) > new Date()
);
const isVerified = u.emailVerified && u.phoneVerified;
return hasActiveSubscription && isVerified && !u.deleted;
}).map(u => ({
id: u.id,
name: `${u.firstName} ${u.lastName}`,
email: u.email,
memberSince: new Date(u.created).getFullYear(),
tier: u.subscriptions[0]?.tier || 'free'
})).sort((a, b) => a.name.localeCompare(b.name));
res.json(processed);
});Por qué está mal: La función de filtro contiene lógica de negocio compleja (validación de suscripciones, comprobaciones de verificación) oculta en una función anónima. Esta lógica no puede ser reutilizada, probada de forma independiente o comprendida sin leer cada línea. Los stack traces muestran funciones anónimas si la lógica de filtrado falla.
✅ Conforme:
function hasActiveSubscription(user) {
return user.subscriptions?.some(subscription =>
subscription.status === 'active' &&
new Date(subscription.expiresAt) > new Date()
);
}
function isVerifiedUser(user) {
return user.emailVerified && user.phoneVerified && !user.deleted;
}
function isEligibleUser(user) {
return hasActiveSubscription(user) && isVerifiedUser(user);
}
function formatUserResponse(user) {
return {
id: user.id,
name: `${user.firstName} ${user.lastName}`,
email: user.email,
memberSince: new Date(user.created).getFullYear(),
tier: user.subscriptions[0]?.tier || 'free'
};
}
function sortByName(a, b) {
return a.name.localeCompare(b.name);
}
app.get('/users', async (req, res) => {
const users = await db.users.find({});
const processed = users
.filter(isEligibleUser)
.map(formatUserResponse)
.sort(sortByName);
res.json(processed);
});¿Por qué esto importa? La lógica de negocio compleja se extrae en funciones testeables. hasActiveSubscription() y isVerifiedUser() se puede probar unitariamente y reutilizar. Las trazas de pila muestran los nombres de las funciones, lo que acelera la depuración. La lógica del endpoint es limpia y auto-documentada.
Conclusión
Utilice funciones con nombre para cualquier lógica de más de 2-3 líneas o cualquier lógica que pueda ser reutilizada. Reserve las funciones anónimas para operaciones triviales donde el nombre de la función sería más largo que la implementación. Los nombres de funciones descriptivos sirven como documentación en línea.
.avif)
