Regola
Non abusare di funzioni anonime
non documentate. Le funzioni anonime
di grandi dimensioni senza documentazione risultano
difficilida comprendere e riutilizzare. Linguaggi supportati: 45+Introduzione
Le funzioni anonime passate come callback o gestori di eventi celano il proprio scopo dietro ai dettagli di implementazione. Una arrow function di 20 righe in un .map() oppure .filter() costringe chi legge ad analizzare l'intera logica per comprendere quale trasformazione venga applicata. Le funzioni con nomi descrittivi documentano l'intento immediatamente, e la logica complessa può essere compresa leggendo il nome della funzione prima di approfondire l'implementazione.
Esempi di codice
❌ Non 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);
});Perché è errato: The filter function contains complex business logic (subscription validation, verification checks) buried in an anonymous function. This logic can't be reused, tested independently, or understood without reading every line. Stack traces show anonymous functions if filtering logic fails.
✅ 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);
});Perché questo è importante: La logica di business complessa viene estratta in funzioni testabili. hasActiveSubscription() e isVerifiedUser() può essere sottoposta a unit test e riutilizzata. Gli stack trace mostrano i nomi delle funzioni, velocizzando il debugging. La logica dell'endpoint risulta pulita e autoesplicativa.
Conclusione
Usa funzioni con nome per qualsiasi logica più lunga di 2-3 righe o per qualsiasi logica che potrebbe essere riutilizzata. Riserva le funzioni anonime a operazioni banali in cui il nome della funzione risulterebbe più lungo della sua implementazione. I nomi descrittivi delle funzioni fungono da documentazione inline.

