Start · Sprachen · JavaScript · Referenz · Map.prototype.getOrInsertComputed()

Map.prototype.getOrInsertComputed()

Methode

Gibt den Wert zu <code>key</code> zurück. Fehlt der Schlüssel, wird <code>callbackFn(key)</code> aufgerufen, das Ergebnis eingefügt und zurückgegeben.

seit JavaScript ES2026 (TC39-Proposal „Upsert“), in Browsern noch Kategorie: method-property

Signatur

Map.prototype.getOrInsertComputed(key, callbackFn)

Beschreibung

getOrInsertComputed() fasst das bekannte Muster „nachsehen, ob ein Schlüssel existiert, sonst einen Standardwert anlegen“ in einem Aufruf zusammen. Existiert key bereits in der Map, gibt die Methode den gespeicherten Wert unverändert zurück. Existiert er nicht, ruft sie callbackFn mit dem Schlüssel auf, speichert den Rückgabewert unter diesem Schlüssel und gibt ihn zurück.

Im Unterschied zu Map.prototype.getOrInsert(key, value) wird der Standardwert erst bei Bedarf berechnet. Das ist wichtig, wenn das Erzeugen teuer ist (z. B. eine aufwendige Berechnung oder ein neues Objekt), wenn es Nebenwirkungen hat oder wenn der Wert vom Schlüssel abhängt. Typische Einsatzfälle sind Caches und Memoisierung, das Gruppieren von Daten in Arrays oder Sets und Registries, die Einträge beim ersten Zugriff anlegen.

Gegenüber dem klassischen Muster if (!map.has(k)) map.set(k, init()); return map.get(k); ist die Methode kürzer und durchsucht die Map nicht mehrfach. Außerdem funktioniert sie auch dann richtig, wenn der gespeicherte Wert undefined ist. Das Muster map.get(k) ?? … scheitert dagegen genau daran.

Parameter

Name Typ Default Beschreibung
$key Pflicht any Der gesuchte Schlüssel. Wie bei allen Map-Methoden wird er nach SameValueZero verglichen; -0 wird als +0 gespeichert.
$callbackFn Pflicht (key: any) => any Funktion, die nur bei fehlendem Schlüssel aufgerufen wird. Sie erhält key als einziges Argument. Ihr Rückgabewert wird eingefügt und zurückgegeben.

Rückgabewert

Typ
any
Beschreibung
Den bereits vorhandenen Wert zu key oder, falls der Schlüssel fehlte, den neu berechneten und eingefügten Rückgabewert von callbackFn.

Beispiele

Daten nach Kategorie gruppieren

const produkte = [
  { name: 'Apfel', kategorie: 'Obst' },
  { name: 'Karotte', kategorie: 'Gemüse' },
  { name: 'Birne', kategorie: 'Obst' }
];

const gruppen = new Map();
for (const p of produkte) {
  // Das Array wird nur beim ersten Auftreten der Kategorie angelegt
  gruppen.getOrInsertComputed(p.kategorie, () => []).push(p.name);
}

console.log(gruppen);
Map(2) { 'Obst' => [ 'Apfel', 'Birne' ], 'Gemüse' => [ 'Karotte' ] }

Memoisierung einer teuren Berechnung

const cache = new Map();

const fib = (n) => cache.getOrInsertComputed(n, (k) => {
  console.log(`berechne ${k}`);
  return k < 2 ? k : fib(k - 1) + fib(k - 2);
});

console.log(fib(5));
console.log(fib(5)); // kommt jetzt direkt aus dem Cache
berechne 5 berechne 4 berechne 3 berechne 2 berechne 1 berechne 0 5 5

Vergleich mit getOrInsert: Wert nur bei Bedarf berechnen

const sitzungen = new Map([['anna', { id: 1 }]]);

const erstelleSitzung = (user) => {
  console.log(`Neue Sitzung für ${user}`);
  return { id: Math.floor(Math.random() * 1000) };
};

// Vorhandener Schlüssel: der Callback wird NICHT aufgerufen
console.log(sitzungen.getOrInsertComputed('anna', erstelleSitzung));

// Fehlender Schlüssel: der Callback läuft genau einmal
const s = sitzungen.getOrInsertComputed('ben', erstelleSitzung);
console.log(sitzungen.has('ben'), sitzungen.get('ben') === s);
{ id: 1 } Neue Sitzung für ben true true

// Wichtig · Fallstricke

  • Kompatibilität: Die Methode ist neu (TC39-Proposal „Upsert“) und wird noch nicht in allen Browsern und Node.js-Versionen unterstützt. Deshalb vorher prüfen, etwa mit typeof Map.prototype.getOrInsertComputed === 'function', oder ein Polyfill wie core-js einsetzen.
  • Ist callbackFn keine Funktion, wird ein TypeError ausgelöst. Das passiert auch dann, wenn der Schlüssel bereits existiert.
  • Löst callbackFn eine Ausnahme aus, wird nichts eingefügt, und die Ausnahme wird weitergereicht.
  • Verändert der Callback die Map selbst, etwa weil er denselben Schlüssel setzt, wird dieser Eintrag anschließend mit dem Rückgabewert des Callbacks überschrieben. Rekursive Aufrufe wie im Memoisierungsbeispiel funktionieren, sollten aber mit Bedacht eingesetzt werden.
  • Ein Callback, der undefined zurückgibt, fügt trotzdem einen Eintrag ein. has(key) liefert danach also true.
  • Für einfache, günstige Standardwerte wie 0 reicht getOrInsert(). Für neue Objekte oder Arrays ist getOrInsertComputed() sinnvoller, weil nicht bei jedem Aufruf unnötig ein Objekt erzeugt wird.
  • Eine gleichnamige Methode gibt es auch auf WeakMap. Dort muss der Schlüssel ein Objekt oder ein nicht registriertes Symbol sein.