Start · Sprachen · JavaScript · Referenz · Map.prototype[Symbol.iterator]()

Map.prototype[Symbol.iterator]()

Methode

Liefert einen Iterator über die <code>[schlüssel, wert]</code>-Paare einer Map in Einfügereihenfolge. So funktioniert eine Map mit <code>for...of</code>, Spread-Syntax und Destrukturierung.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Map.prototype[Symbol.iterator]()

Beschreibung

Die Methode [Symbol.iterator]() von Map-Instanzen setzt das Iterable-Protokoll um. Viele Sprachmittel erwarten ein iterierbares Objekt und rufen diese Methode deshalb automatisch auf. Dazu gehören die for...of-Schleife, die Spread-Syntax [...map], die Array-Destrukturierung, Array.from(), new Map(iterable), new Set(iterable), Promise.all() und yield*.

Ihr Startwert ist dieselbe Funktion wie Map.prototype.entries. Es gilt also Map.prototype[Symbol.iterator] === Map.prototype.entries. Jeder Schritt des Iterators liefert ein zweielementiges Array [key, value]. Die Reihenfolge entspricht der Reihenfolge, in der die Schlüssel eingefügt wurden.

Direkt aufrufen muss man die Methode nur selten. Das lohnt sich, wenn man den Iterator von Hand mit next() weiterschalten will, etwa um nur das erste Element zu lesen oder die Iteration schrittweise zu steuern. Der zurückgegebene Map-Iterator ist selbst iterierbar, denn sein [Symbol.iterator]() gibt ihn selbst zurück.

Der Iterator ist live. Einträge, die während der Iteration hinzukommen, werden noch besucht, gelöschte und noch nicht besuchte Einträge dagegen übersprungen.

Rückgabewert

Typ
MapIterator<[K, V]>
Beschreibung
Ein neues Map-Iterator-Objekt. Dasselbe liefert Map.prototype.entries(). Jeder Aufruf von next() gibt { value: [key, value], done: false } zurück, am Ende { value: undefined, done: true }.

Beispiele

Implizite Nutzung mit for...of und Destrukturierung

const preise = new Map([
  ['Apfel', 0.5],
  ['Birne', 0.8],
  ['Kiwi', 0.3]
]);

// for...of ruft preise[Symbol.iterator]() automatisch auf
for (const [frucht, preis] of preise) {
  console.log(`${frucht}: ${preis.toFixed(2)} €`);
}
Apfel: 0.50 € Birne: 0.80 € Kiwi: 0.30 €

Iterator manuell mit next() steuern

const status = new Map([
  [200, 'OK'],
  [404, 'Not Found']
]);

const it = status[Symbol.iterator]();
console.log(it.next());
console.log(it.next());
console.log(it.next());

// Identisch mit entries()
console.log(Map.prototype[Symbol.iterator] === Map.prototype.entries);
{ value: [ 200, 'OK' ], done: false } { value: [ 404, 'Not Found' ], done: false } { value: undefined, done: true } true

Spread-Syntax: Map sortieren, filtern und umwandeln

const punkte = new Map([
  ['Lena', 42],
  ['Tom', 17],
  ['Mia', 58]
]);

// Spread nutzt Symbol.iterator und liefert ein Array aus Paaren
const rangliste = new Map(
  [...punkte].sort(([, a], [, b]) => b - a)
);
console.log([...rangliste.keys()]);

// Umwandeln in ein normales Objekt, z. B. für JSON
const obj = Object.fromEntries(punkte);
console.log(JSON.stringify(obj));
[ 'Mia', 'Lena', 'Tom' ] {"Lena":42,"Tom":17,"Mia":58}

Ersten Eintrag einer Map lesen

const cache = new Map();
cache.set('a', 1).set('b', 2);

// Ältester Eintrag (Einfügereihenfolge), z. B. für einfache LRU-Caches
const [ersterKey, ersterWert] = cache[Symbol.iterator]().next().value;
console.log(ersterKey, ersterWert);

cache.delete(ersterKey);
console.log(cache.size);
a 1 1

// Wichtig · Fallstricke

  • Live-Iteration: Wenn man die Map während der Iteration verändert, wirkt sich das sofort aus. Neu eingefügte Einträge werden noch besucht. Das kann zu Endlosschleifen führen, wenn man innerhalb von for...of ständig neue Schlüssel hinzufügt.
  • Ausgeschöpfter Iterator: Ein Map-Iterator lässt sich nur einmal durchlaufen. Für einen zweiten Durchlauf ruft man map[Symbol.iterator]() erneut auf, oder man iteriert direkt über die Map.
  • Leeres Map-Objekt: Bei einer leeren Map ist map[Symbol.iterator]().next().value gleich undefined. Eine Destrukturierung wie const [k, v] = ...value wirft dann einen TypeError. Vorher map.size prüfen.
  • Überschreiben: Wer Map.prototype[Symbol.iterator] ersetzt, verändert das Verhalten von Spread, for...of und Array.from() für alle Maps. entries() bleibt davon unberührt. Das sollte man in Produktionscode vermeiden.
  • Falscher this-Wert: Ruft man die Methode mit einem this auf, das keine Map ist, zum Beispiel Map.prototype[Symbol.iterator].call({}), wird ein TypeError ausgelöst.
  • Kompatibilität: Wird von allen modernen Browsern und von Node.js unterstützt (Baseline seit 2015). Der Internet Explorer 11 kennt die Methode nicht, dort ist ein Polyfill nötig, etwa core-js.
  • Performance: [...map] erzeugt ein vollständiges Zwischen-Array. Bei sehr großen Maps ist direktes for...of speichersparender. Alternativ gibt es die Iterator-Helper wie map.entries().filter(...), die in neueren Umgebungen (ES2025) verfügbar sind.