Regel
Vermeiden Sie den übermäßigen Gebrauch von undokumentierten anonymen Funktionen.
Große anonyme Funktionen ohne Dokumentation
sind schwer zu verstehen und wiederzuverwenden.
Unterstützte Sprachen: 45+Einleitung
Anonyme Funktionen, die als Callbacks oder Event-Handler übergeben werden, verbergen ihren Zweck hinter Implementierungsdetails. Eine 20-zeilige Arrow-Funktion in einem .map() oder .filter() zwingt Lesende dazu, die gesamte Logik zu analysieren, um zu verstehen, welche Transformation stattfindet. Benannte Funktionen mit aussagekräftigen Namen dokumentieren die Absicht sofort, und komplexe Logik kann durch das Lesen des Funktionsnamens verstanden werden, bevor man sich in die Implementierung vertieft.
Code-Beispiele
❌ Nicht konform:
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);
});Warum es falsch ist: Die Filterfunktion enthält komplexe Geschäftslogik (Abonnementvalidierung, Verifizierungsprüfungen), die in einer anonymen Funktion verborgen ist. Diese Logik kann nicht wiederverwendet, unabhängig getestet oder ohne das Lesen jeder Zeile verstanden werden. Stack-Traces zeigen anonyme Funktionen an, wenn die Filterlogik fehlschlägt.
✅ Konform:
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);
});Warum dies wichtig ist: Komplexe Geschäftslogik wird in testbare Funktionen extrahiert. hasActiveSubscription() und isVerifiedUser() kann Unit-getestet und wiederverwendet werden. Stack-Traces zeigen Funktionsnamen an, was das Debugging beschleunigt. Die Endpunktlogik ist sauber und selbstdokumentierend.
Fazit
Verwenden Sie benannte Funktionen für Logik, die länger als 2-3 Zeilen ist oder wiederverwendet werden könnte. Reservieren Sie anonyme Funktionen für triviale Operationen, bei denen der Funktionsname länger wäre als die Implementierung. Aussagekräftige Funktionsnamen dienen als Inline-Dokumentation.
.avif)
