
Ein praxisnaher deutscher Leitfaden mit 15 modernen JavaScript-Funktionen, ausführbaren Beispielen und Tipps aus der Perspektive erfahrener Entwickler.
JavaScript-Syntax zu kennen bedeutet nicht automatisch, JavaScript zu schreiben, das ein Team sicher warten kann. Professioneller Code ist verständlich, vermeidet versteckte Zustände und behandelt Fehler, Abbruch, Datenform und Leistung bewusst.
Dieser Leitfaden erklärt 15 moderne Funktionen, die erfahrene Entwickler in echten Anwendungen verwenden. Entscheidend ist nicht möglichst kurze Syntax, sondern weniger Mehrdeutigkeit.
?. greift sicher auf Eigenschaften zu, wenn ein Wert null oder undefined ist. ?? verwendet einen Standardwert nur bei diesen fehlenden Werten.
function getCustomerLabel(order) {
const name = order.customer?.profile?.displayName ?? 'Guest';
const points = order.customer?.loyaltyPoints ?? 0;
return `${name} (${points} points)`;
}
Wenn 0, false oder ein leerer Text gültig sind, ist ?? besser als ||. Verwenden Sie ?. nicht, um einen Zustand zu verstecken, der in Ihrer Anwendung eigentlich garantiert sein sollte.
Destructuring zeigt direkt, welche Daten eine Funktion erwartet.
function createAccount({ email, role = 'member', notifications = true }) {
if (!email) throw new Error('email is required');
return { email, role, notifications };
}
API-Felder können beim Destructuring umbenannt werden, etwa created_at: createdAt. Zu viele Parameter sind oft ein Hinweis auf eine zu große Verantwortung.
async und await machen asynchronen Code linear lesbar. Gute Anwendungen entscheiden zusätzlich, wo Fehler behandelt werden.
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();
}
Fangen Sie einen Fehler nicht einfach ab, um undefined zurückzugeben. Das verschiebt ein klares Problem nur an eine schwerer verständliche Stelle.
Unabhängige Requests können parallel laufen; abhängige Schritte bleiben sequenziell.
const [profile, projects, alerts] = await Promise.all([
fetchProfile(userId), fetchProjects(userId), fetchAlerts(userId),
]);
Mit Promise.allSettled() erhalten Sie jedes Ergebnis, auch wenn eine Aufgabe fehlschlägt. Für große Mengen brauchen Sie eine Warteschlange oder ein concurrency limit.
Mit AbortController können veraltete Suchen oder Requests abgebrochen werden.
const controller = new AbortController();
const response = await fetch('/api/products?q=rust', {
signal: controller.signal,
});
controller.abort();
Erwartete Abbrüche sollten getrennt von echten Fehlern behandelt werden, damit Monitoring-Berichte sauber bleiben.
const nextUser = {
...user,
preferences: { ...user.preferences, theme: 'dark' },
};
Spread kopiert nur die erste Ebene. Für strukturierte Daten kann structuredClone() eine tiefe Kopie erzeugen; Funktionen und DOM-Knoten werden nicht kopiert.
Verwenden Sie Set für eindeutige Werte und Map für dynamische Schlüssel.
const uniqueTags = [...new Set(['js', 'api', 'js'])];
const counts = new Map();
counts.set('javascript', (counts.get('javascript') ?? 0) + 1);
Damit vermeiden Sie auch Kollisionen mit geerbten Eigenschaften normaler Objekte.
map() transformiert, filter() wählt aus, find() findet das erste Ergebnis, some() prüft ein beliebiges und every() alle Ergebnisse.
const activeEmails = users
.filter((user) => user.isActive)
.map((user) => user.email);
Nicht jede Schleife muss zu reduce() werden. Bei mehreren Schritten, frühem Abbruch oder asynchronem Code ist for...of oft klarer.
In unterstützten Laufzeiten ersetzt Object.groupBy() wiederholte Reducer:
const ticketsByStatus = Object.groupBy(tickets, (ticket) => ticket.status);
Prüfen Sie Browser- und Node.js-Versionen, bevor Sie neue Funktionen einsetzen.
Felder mit # werden von der Sprache geschützt, nicht nur durch eine Namenskonvention.
class RateLimiter {
#requests = 0;
constructor(limit) { this.limit = limit; }
tryConsume() {
if (this.#requests >= this.limit) return false;
this.#requests += 1; return true;
}
}
Private Felder schützen Invarianten, ersetzen aber keine sinnvolle Klassengrenze.
import und export machen Abhängigkeiten sichtbar. import() lädt selten benötigten Code erst bei Bedarf.
async function openChart(data) {
const { renderChart } = await import('./chart.js');
return renderChart(data);
}
Das eignet sich für Diagramme, Editoren und Verwaltungsseiten, die nicht beim ersten Laden benötigt werden.
Verwenden Sie Intl für Zahlen, Währungen, Datumsangaben und Listen.
const price = new Intl.NumberFormat('de-DE', {
style: 'currency', currency: 'EUR',
}).format(1299.5);
So vermeiden Sie Fehler durch manuell zusammengesetzte Datums- und Währungsangaben.
String-Konkatenation kann bei Leerzeichen, & und Unicode-Zeichen ungültige URLs erzeugen.
const url = new URL('/api/articles', window.location.origin);
url.searchParams.set('language', 'de');
url.searchParams.set('query', 'async JavaScript');
fetch(url);
Eigene Fehlerklassen unterscheiden Validierung, Berechtigungen, Netzwerk- und Domänenfehler.
class ValidationError extends Error {
constructor(message, details = {}) {
super(message); this.name = 'ValidationError'; this.details = details;
}
}
Passwörter, Tokens und persönliche Daten gehören niemals in Fehlermeldungen oder Logs.
Eine Closure behält Zugriff auf ihren Zustand, ohne ihn global zu veröffentlichen.
function createIdGenerator(prefix = 'item') {
let current = 0;
return () => `${prefix}-${++current}`;
}
Closures sind für Fabriken, Memoization und Callbacks nützlich. Fangen Sie in langlebigen Listenern keine unnötig großen Objekte ein.
async function findUsers({ query, page = 1, signal } = {}) {
const normalizedQuery = query?.trim();
if (!normalizedQuery) throw new ValidationError('Suche erforderlich');
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 };
}
Der professionelle Teil sind die Entscheidungen: früh validieren, URLs sicher bilden, Requests abbrechen, HTTP-Fehler ablehnen und ein vorhersehbares Ergebnis liefern.
?. einen ungültigen Zustand verschleiern.Promise.all() ausführen.Senior-JavaScript bedeutet nicht, möglichst viele Features vorzuzeigen. Es bedeutet, Verhalten verständlich zu machen, gültige Werte zu bewahren, Daten passend zu modellieren und Fehler bewusst zu behandeln. Beginnen Sie mit den Funktionen, die in Ihrem Code am meisten Mehrdeutigkeit entfernen.
Noch keine freigegebenen Kommentare sichtbar. Neue Antworten können moderiert werden.