Regola
Non abusare elementi non documentati funzioni .
Le funzioni anonime funzioni senza documentazione
sono difficili da comprendere e riutilizzabili.
Linguaggi supportati: 45+Introduzione
Le funzioni anonime passate come callback o gestori di eventi nascondono il loro scopo dietro i dettagli di implementazione. Una funzione freccia di 20 righe in un .map() oppure .filter() costringe i lettori ad analizzare l'intera logica per comprendere quale trasformazione avvenga. Le funzioni con nomi descrittivi chiariscono immediatamente l'intento, e la logica complessa può essere compresa semplicemente leggendo il nome della funzione prima ancora di addentrarsi nell'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é è sbagliato: la funzione di filtro contiene una logica di business complessa (convalida dell'abbonamento, controlli di verifica) nascosta all'interno di una funzione anonima. Questa logica non può essere riutilizzata, testata in modo indipendente né compresa senza leggere ogni singola riga. Le tracce di stack mostrano le funzioni anonime in caso di errore nella logica di filtraggio.
✅ 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é è importante: La logica di business complessa viene suddivisa in funzioni verificabili. hasActiveSubscription() e isVerifiedUser() possono essere sottoposti a test unitari e riutilizzati. Le tracce di stack mostrano i nomi delle funzioni, rendendo più veloce il debug. La logica degli endpoint è chiara e autoesplicativa.
Conclusione
Utilizza funzioni con nome per qualsiasi logica che superi le 2-3 righe o che possa essere riutilizzata. Riserva le funzioni anonime alle operazioni banali in cui il nome della funzione risulterebbe più lungo dell'implementazione stessa. I nomi descrittivi delle funzioni fungono da documentazione inline.

