Start · Sprachen · JavaScript · Referenz · Set.prototype.forEach()

Set.prototype.forEach()

Methode

Führt eine Callback-Funktion einmal für jeden Wert eines <code>Set</code> aus, in der Reihenfolge, in der die Werte eingefügt wurden.

seit JavaScript ES2015 (Baseline: alle Browser, Node.js 0.12+) Kategorie: method-property

Signatur

Set.prototype.forEach(callbackFn, thisArg)

Beschreibung

Die Methode forEach() ruft die übergebene Funktion callbackFn einmal für jeden Wert auf, der sich gerade im Set befindet. Die Reihenfolge entspricht der Einfügereihenfolge. Werte, die schon gelöscht wurden, werden nicht besucht. Werte, die undefined sind, aber im Set stehen, werden dagegen ganz normal verarbeitet.

Der Callback bekommt drei Argumente: den Wert, den „Schlüssel“ und das Set selbst. Weil ein Set keine Schlüssel hat, sind die ersten beiden Argumente immer derselbe Wert. Das dient nur der Einheitlichkeit mit Map.prototype.forEach() und Array.prototype.forEach(), sodass man denselben Callback für verschiedene Sammlungen verwenden kann.

Über thisArg legt man fest, welchen this-Wert der Callback bekommt. Das gilt nur für normale Funktionen (function). Pfeilfunktionen übernehmen this immer aus dem umgebenden Gültigkeitsbereich und ignorieren thisArg.

Ändert man das Set während des Durchlaufs, gilt Folgendes: Werte, die vor ihrem Besuch gelöscht werden, werden übersprungen. Werte, die während des Durchlaufs neu hinzukommen, werden noch besucht. Ein Wert, der schon besucht, dann gelöscht und wieder hinzugefügt wurde, wird ein zweites Mal besucht. forEach() gibt immer undefined zurück und lässt sich deshalb nicht mit weiteren Methodenaufrufen verketten.

Parameter

Name Typ Default Beschreibung
$callbackFn Pflicht (value: any, key: any, set: Set) => void Funktion, die für jeden Wert aufgerufen wird. Sie bekommt value (den aktuellen Wert), key (derselbe Wert wie value) und set (das durchlaufene Set). Ihr Rückgabewert wird ignoriert.
$thisArg any undefined Wert, der beim Aufruf von callbackFn als this verwendet wird. Wirkt nicht bei Pfeilfunktionen.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. forEach() ist nur für Nebeneffekte gedacht, zum Beispiel Ausgaben oder Änderungen an anderen Objekten.

Beispiele

Alle Werte eines Sets ausgeben

const tags = new Set(['javascript', 'web', 'api']);

tags.forEach((value, key, set) => {
  console.log(`${value} === ${key}: ${value === key}, Größe: ${set.size}`);
});
javascript === javascript: true, Größe: 3 web === web: true, Größe: 3 api === api: true, Größe: 3

Eindeutige Benutzer-IDs in DOM-Listeneinträge umwandeln

const userIds = new Set([42, 7, 42, 13, 7]); // Duplikate werden entfernt
const list = document.createElement('ul');

userIds.forEach((id) => {
  const li = document.createElement('li');
  li.textContent = `Benutzer #${id}`;
  list.append(li);
});

document.body.append(list);
console.log(list.children.length);
3

thisArg mit einer normalen Funktion nutzen

const stats = {
  total: 0,
  add(value) {
    this.total += value;
  }
};

const prices = new Set([9.99, 4.5, 20]);

// Normale Funktion: this ist stats (über thisArg)
prices.forEach(function (price) {
  this.add(price);
}, stats);

console.log(stats.total.toFixed(2));
34.49

Verhalten beim Ändern während des Durchlaufs

const queue = new Set(['a', 'b', 'c']);

queue.forEach((item) => {
  console.log(item);
  if (item === 'a') {
    queue.delete('b'); // wird übersprungen, weil noch nicht besucht
    queue.add('d');    // wird noch besucht
  }
});
a c d

// Wichtig · Fallstricke

  • Kein Abbruch möglich: break und return beenden nur den aktuellen Callback-Aufruf, nicht den ganzen Durchlauf. Wer früh aufhören will, verwendet for...of. Die Alternative, eine Ausnahme zu werfen, ist unschön.
  • Nicht async-fähig: forEach() wartet nicht auf Promises. async-Callbacks laufen deshalb parallel, und ihre Fehler werden nicht abgefangen. Für Aufrufe nacheinander nimmt man for...of mit await, für parallele Aufrufe Promise.all([...set].map(fn)).
  • Endlosschleife möglich: Fügt der Callback bei jedem Durchlauf neue Werte hinzu, oder löscht er den aktuellen Wert und fügt ihn wieder hinzu, endet der Durchlauf nie.
  • Zweites Argument: key ist kein Index, sondern derselbe Wert wie value. Einen Index gibt es bei Sets nicht. Bei Bedarf zählt man selbst mit oder verwendet [...set].forEach((v, i) => …).
  • Pfeilfunktionen ignorieren thisArg.
  • Wird die Methode auf einem Objekt aufgerufen, das kein Set ist, wirft sie einen TypeError. Ist callbackFn keine Funktion, gibt es ebenfalls einen TypeError.
  • Die Methode wird seit ES2015 von allen modernen Browsern und von Node.js unterstützt.