Wer in JavaScript mit Listen arbeitet, kommt an drei Methoden kaum vorbei: map, filter und reduce. Sie ersetzen einen Großteil der klassischen for-Schleifen, machen den Code kürzer und vor allem leichter lesbar – denn ihr Name verrät sofort, was passiert. Statt manuell durch ein Array zu laufen und Werte in ein neues Array zu schieben, beschreibst du nur noch was geschehen soll, nicht wie. In diesem Ratgeber gehe ich die drei Methoden einzeln durch, zeige typische Beispiele, erkläre wie man sie verkettet und wann eine gewöhnliche Schleife trotzdem die bessere Wahl bleibt.
Was diese Methoden gemeinsam haben
Alle drei sind sogenannte Iterationsmethoden auf dem Array-Prototyp. Du übergibst ihnen eine Funktion (den Callback), die für jedes Element des Arrays aufgerufen wird. Das Callback bekommt in der Regel drei Argumente: das aktuelle Element, dessen Index und das gesamte Array. Entscheidend für sauberen Code ist eine Eigenschaft, die alle drei teilen: Sie verändern das ursprüngliche Array nicht. Stattdessen erzeugen sie einen neuen Wert. Diese Unveränderlichkeit (Immutabilität) ist einer der größten Vorteile gegenüber Schleifen, die oft am Original herumschrauben und dadurch schwerer nachvollziehbar werden.
map: jedes Element transformieren
map wendet eine Funktion auf jedes Element an und gibt ein neues Array zurück, das genauso viele Elemente hat wie das Original. Eins rein, eins raus – nur eben verändert. Damit eignet sich die Methode immer dann, wenn du eine Liste in eine andere Liste gleicher Länge umwandeln willst.
const preise = [10, 20, 30];
const mitSteuer = preise.map(p => p * 1.19);
// [11.9, 23.8, 35.699999...]
Ein häufiger Anwendungsfall ist das Herausziehen einer Eigenschaft aus einer Liste von Objekten, etwa um nur die Namen aus einer Nutzerliste zu erhalten:
const namen = nutzer.map(u => u.name);
Wichtig: Wenn du den Rückgabewert gar nicht brauchst und nur etwas pro Element tun möchtest (zum Beispiel etwas ausgeben), ist map die falsche Wahl. Dafür gibt es forEach. map nutzt du nur, wenn du das Ergebnis-Array wirklich weiterverwendest.
filter: nur passende Elemente behalten
filter prüft jedes Element gegen eine Bedingung und gibt ein neues Array zurück, das nur die Elemente enthält, für die das Callback true liefert. Die Länge des Ergebnisses ist also kleiner oder gleich der des Originals – aber nie größer.
const zahlen = [4, 7, 12, 3, 20];
const grosse = zahlen.filter(n => n > 5);
// [7, 12, 20]
Auch hier ist die Arbeit mit Objekten typisch, etwa wenn du nur aktive Nutzer behalten willst:
const aktive = nutzer.filter(u => u.aktiv);
Eine elegante Nebenanwendung: Mit filter(Boolean) entfernst du in einem Rutsch alle "falsy" Werte wie null, undefined, leere Strings oder 0 aus einer Liste – praktisch zum Aufräumen unsauberer Daten.
reduce: ein Array zu einem Wert verdichten
reduce ist die flexibelste, aber auch die abstrakteste der drei. Sie läuft durch das Array und verdichtet alle Elemente Schritt für Schritt zu einem einzigen Endwert. Dieser "Wert" kann eine Zahl sein, aber genauso gut ein String, ein Objekt oder sogar wieder ein Array.
Das Callback bekommt einen Akkumulator (das Zwischenergebnis) und das aktuelle Element. Als zweites Argument übergibst du den Startwert – diesen solltest du fast immer explizit setzen, um Überraschungen bei leeren Arrays zu vermeiden.
const zahlen = [1, 2, 3, 4];
const summe = zahlen.reduce((acc, n) => acc + n, 0);
// 10
Mit einem Objekt als Startwert lässt sich zum Beispiel zählen, wie oft jeder Eintrag vorkommt:
const obst = ["apfel", "birne", "apfel"];
const anzahl = obst.reduce((acc, o) => {
acc[o] = (acc[o] || 0) + 1;
return acc;
}, {});
// { apfel: 2, birne: 1 }
Weil reduce so mächtig ist, kann man damit theoretisch auch map und filter nachbauen. In der Praxis lohnt sich das aber selten: Der Code wird dadurch meist schwerer lesbar als die spezialisierte Methode.
Methoden verketten
Da map und filter jeweils ein neues Array zurückgeben, kannst du sie direkt aneinanderhängen. Das ist der Punkt, an dem diese Methoden richtig glänzen, weil sich eine ganze Datenverarbeitung als gut lesbare Kette schreiben lässt:
const ergebnis = produkte
.filter(p => p.verfuegbar)
.map(p => p.preis)
.reduce((acc, preis) => acc + preis, 0);
Diese Kette liest sich fast wie ein Satz: nimm die verfügbaren Produkte, hol dir deren Preise, addiere sie auf. Achte bei langen Ketten aber auf die Reihenfolge: Wenn du erst filterst und dann transformierst, arbeitet map mit weniger Elementen – das ist bei großen Datenmengen effizienter, als die umgekehrte Reihenfolge.
Die drei Methoden im Überblick
| Methode | Rückgabewert | Verändert Original? | Typischer Einsatzzweck |
|---|---|---|---|
map |
Neues Array, gleiche Länge | Nein | Jedes Element umwandeln (z. B. Preise mit Steuer) |
filter |
Neues Array, kürzer oder gleich | Nein | Elemente nach Bedingung auswählen |
reduce |
Ein einzelner Wert (beliebiger Typ) | Nein | Liste zu Summe, Objekt oder String verdichten |
forEach |
undefined |
Nein (außer im Callback) | Nebeneffekte ohne Rückgabe (z. B. Ausgabe) |
for-Schleife |
Kein direkter Rückgabewert | Je nach Code | Abbruch, Performance-Hotpaths, komplexe Logik |
Wann die klassische for-Schleife besser ist
So elegant die Array-Methoden sind – sie sind nicht immer die richtige Wahl. In diesen Fällen greife ich lieber zur normalen Schleife:
- Vorzeitiger Abbruch:
map,filterundreducelaufen immer komplett durch. Willst du beim ersten Treffer aufhören, ist einefor-Schleife mitbreakklarer (oderfindbzw.somefür einfache Fälle). - Performance-kritische Schleifen: Bei sehr großen Datenmengen oder Hotpaths kann eine einfache Schleife messbar schneller sein, weil kein Callback pro Element aufgerufen wird. Im Alltag ist der Unterschied aber meist vernachlässigbar – optimiere erst, wenn du ein echtes Problem gemessen hast.
- Komplexe, verschachtelte Logik: Wenn ein Schritt mehrere Variablen gleichzeitig fortschreiben muss, wird eine erzwungene
reduce-Lösung schnell unübersichtlich. Lesbarkeit schlägt Kürze. - Asynchrone Verarbeitung: Kombinierst du diese Methoden mit
await, gibt es Stolperfallen. Einefor…of-Schleife mitawaitim Rumpf verhält sich oft vorhersehbarer.
Praktische Tipps für sauberen Code
- Setze bei
reduceimmer einen Startwert, sonst kann ein leeres Array einen Fehler werfen. - Gib im Callback eines
reduceodermapmit Objekt-Logik nie das Zurückgeben des Akkumulators bzw. Werts zu vergessen. - Halte Callbacks kurz. Wird die Logik länger, lagere sie in eine benannte Funktion aus – das macht die Kette wieder lesbar.
- Verwende
mapnicht für reine Nebeneffekte. Dafür istforEachgedacht.
Wenn du mit Zahlen, Texten oder Formaten experimentierst, findest du auf kotsch.tech eine ganze Sammlung kleiner Helfer in den Webtools. Weitere Beiträge rund um Programmierung und Web findest du in unseren News, und einen Überblick über alles gibt es auf der Startseite.
Häufige Fragen
Verändern map, filter und reduce das ursprüngliche Array?
Nein. Alle drei geben einen neuen Wert zurück und lassen das Original unangetastet. Das ist gerade einer ihrer größten Vorteile gegenüber Schleifen, die oft direkt am Ausgangs-Array arbeiten. Nur wenn du innerhalb des Callbacks selbst Objekte des Arrays veränderst, wirkt sich das auf das Original aus.
Wann nehme ich map und wann forEach?
Nutze map, wenn du ein neues, transformiertes Array brauchst und es weiterverwendest. Geht es dir nur um einen Nebeneffekt pro Element – etwa eine Ausgabe oder das Schreiben in eine andere Struktur –, ist forEach die ehrlichere Wahl, weil es signalisiert, dass kein Rückgabewert entsteht.
Warum sollte ich bei reduce einen Startwert angeben?
Ohne Startwert nimmt reduce das erste Element als Anfangswert und beginnt beim zweiten. Bei einem leeren Array gibt es dann nichts zu starten und es wird ein Fehler geworfen. Mit einem expliziten Startwert (etwa 0 oder {}) ist das Verhalten immer eindeutig und auch bei leeren Listen sicher.
Kann ich die Methoden beliebig verketten?
Ja, solange jede Methode in der Kette wieder ein Array zurückgibt. map und filter tun das immer, deshalb lassen sie sich frei kombinieren. reduce steht meist am Ende, weil es einen einzelnen Wert liefert. Achte auf eine sinnvolle Reihenfolge: erst filtern, dann transformieren spart Arbeit.
Sind diese Methoden langsamer als eine for-Schleife?
Theoretisch ja, weil pro Element ein Callback aufgerufen wird. In der Praxis ist der Unterschied bei normalen Datenmengen so klein, dass er keine Rolle spielt. Bei sehr großen Listen oder echten Performance-Engpässen kann eine klassische Schleife sich lohnen – aber optimiere erst, wenn du das Problem tatsächlich gemessen hast.
Gibt es ähnliche Methoden, die ich kennen sollte?
Ja. find liefert das erste passende Element, some und every prüfen Bedingungen und geben einen Wahrheitswert zurück, flatMap kombiniert Transformieren und Verflachen. Wenn du map, filter und reduce verstanden hast, fallen dir diese verwandten Methoden leicht.