Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

Map

Baseline Widely available *

This feature is well established and works across many devices and browser versions. It’s been available across browsers since ⁨Juli 2015⁩.

* Some parts of this feature may have varying levels of support.

Das Map-Objekt speichert Schlüssel-Werte-Paare und merkt sich die ursprüngliche Einfügereihenfolge der Schlüssel. Jeder Wert (sowohl Objekte als auch primitive Werte) kann entweder als Schlüssel oder als Wert verwendet werden.

Probieren Sie es aus

const map = new Map();

map.set("a", 1);
map.set("b", 2);
map.set("c", 3);

console.log(map.get("a"));
// Expected output: 1

map.set("a", 97);

console.log(map.get("a"));
// Expected output: 97

console.log(map.size);
// Expected output: 3

map.delete("b");

console.log(map.size);
// Expected output: 2

Beschreibung

Map-Objekte sind Sammlungen von Schlüssel-Werte-Paaren. Ein Schlüssel in der Map darf nur einmal auftreten; er ist in der Sammlung der Map einzigartig. Ein Map-Objekt wird durch Schlüssel-Werte-Paare iteriert — eine for...of-Schleife gibt ein Array mit 2 Mitgliedern [key, value] für jede Iteration zurück. Die Iteration erfolgt in der Einfügereihenfolge, die der Reihenfolge entspricht, in der jedes Schlüssel-Wert-Paar zuerst mit der set()-Methode in die Map eingefügt wurde (das heißt, es war kein Schlüssel mit demselben Wert bereits in der Map, als set() aufgerufen wurde).

Die Spezifikation erfordert, dass Maps so implementiert werden, "dass sie im Durchschnitt Zugriffszeiten bieten, die sublinear zur Anzahl der Elemente in der Sammlung sind". Daher könnte sie intern als Hash-Tabelle (mit O(1) Suche), Suchbaum (mit O(log(N)) Suche) oder einer anderen Datenstruktur dargestellt sein, solange die Komplexität besser als O(N) ist.

Schlüsselgleichheit

Die Wertgleichheit basiert auf dem SameValueZero-Algorithmus. (Früher wurde SameValue verwendet, der 0 und -0 als unterschiedlich behandelte. Überprüfen Sie die Browser-Kompatibilität.) Das bedeutet, dass NaN als gleich zu NaN betrachtet wird (obwohl NaN !== NaN) und alle anderen Werte als gleich betrachtet werden gemäß den Semantiken des ===-Operators. Auch für objektbezogene Schlüssel basiert die Gleichheit auf der Objektidentität, sie werden nach Referenz und nicht nach Wert verglichen. Siehe Using the Map object für Beispiele.

Objekte vs. Maps

Object ist ähnlich wie Map — beide ermöglichen das Festlegen von Schlüsseln auf Werte, das Abrufen dieser Werte, das Löschen von Schlüsseln und das Erkennen, ob etwas unter einem Schlüssel gespeichert ist. Aus diesem Grund (und weil es keine eingebauten Alternativen gab) wurde Object historisch als Map verwendet.

Es gibt jedoch wichtige Unterschiede, die Map in einigen Fällen vorzuziehen machen:

Map Object
Zufällige Schlüssel Eine Map enthält von Haus aus keine Schlüssel. Sie enthält nur das, was explizit in sie eingefügt wurde.

Ein Object hat ein Prototyp, sodass es Standardschlüssel enthält, die mit Ihren eigenen Schlüsseln kollidieren könnten, wenn Sie nicht vorsichtig sind.

Hinweis: Dies kann umgangen werden, indem Object.create(null) verwendet wird, aber dies wird selten gemacht.

Sicherheit Eine Map ist sicher bei der Verwendung mit benutzerdefinierten Schlüsseln und Werten.

Das Festlegen von benutzerdefinierten Schlüssel-Wert-Paaren auf einem Object kann einem Angreifer ermöglichen, den Prototyp des Objekts zu überschreiben, was zu Objekt-Injektionsangriffen führen kann. Wie bei dem Problem mit den zufälligen Schlüsseln kann dies auch durch die Verwendung eines null-Prototyp-Objekts gemildert werden.

Schlüsseltypen Die Schlüssel einer Map können jeden Wert haben (einschließlich Funktionen, Objekten oder beliebigen primitiven Werten). Die Schlüssel eines Object müssen entweder ein String oder ein Symbol sein.
Schlüsselreihenfolge

Die Schlüssel in Map sind in einer einfachen Weise geordnet: Ein Map-Objekt iteriert Einträge, Schlüssel und Werte in der Reihenfolge der Einfügung.

Obwohl die Schlüssel eines gewöhnlichen Object jetzt geordnet sind, war dies nicht immer der Fall und die Reihenfolge ist komplex. Daher sollte man sich nicht auf die Reihenfolge der Eigenschaften verlassen.

Die Reihenfolge wurde erstmals für eigene Eigenschaften nur in ECMAScript 2015 definiert; ECMAScript 2020 definiert die Reihenfolge auch für geerbte Eigenschaften. Beachten Sie jedoch, dass kein einzelner Mechanismus alle Eigenschaften eines Objekts durchläuft; die verschiedenen Mechanismen umfassen jeweils unterschiedliche Teilmengen von Eigenschaften. (for-in beinhaltet nur aufzählbare, stringbezogene Eigenschaften; Object.keys beinhaltet nur eigene, aufzählbare, stringbezogene Eigenschaften; Object.getOwnPropertyNames beinhaltet eigene, stringbezogene Eigenschaften, selbst wenn sie nicht aufzählbar sind; Object.getOwnPropertySymbols macht dasselbe nur für Symbol-Bezeichnungen, usw.)

Größe

Die Anzahl der Elemente in einer Map kann leicht über die size-Eigenschaft abgerufen werden. Die Bestimmung der Anzahl der Elemente in einem Object ist umständlicher und weniger effizient. Eine gängige Methode, dies zu tun, ist über die length des Arrays, das von Object.keys() zurückgegeben wird.
Iteration Eine Map ist ein iterable, sodass sie direkt durchlaufen werden kann.

Object implementiert kein Iterationsprotokoll, und Objekte sind daher nicht direkt mit der JavaScript for...of Anweisung durchlaufbar (standardmäßig).

Hinweis:

  • Ein Objekt kann das Iterationsprotokoll implementieren, oder Sie können ein iterable für ein Objekt erhalten, indem Sie Object.keys oder Object.entries verwenden.
  • Die for...in Anweisung erlaubt es, über die aufzählbaren Eigenschaften eines Objekts zu iterieren.
Leistung

Liefert bessere Ergebnisse in Szenarien mit häufigen Hinzufügungen und Entfernungen von Schlüssel-Wert-Paaren.

Nicht für häufige Hinzufügungen und Entfernungen von Schlüssel-Wert-Paaren optimiert.

Serialisierung und Parsing

Keine native Unterstützung für Serialisierung oder Parsing.

(Aber Sie können Ihre eigene Unterstützung für Serialisierung und Parsing von Map aufbauen, indem Sie JSON.stringify() mit seinem replacer-Argument verwenden, und JSON.parse() mit seinem reviver-Argument. Siehe die Stack Overflow Frage How do you JSON.stringify an ES6 Map?).

Native Unterstützung für die Serialisierung von Object zu JSON, mittels JSON.stringify().

Native Unterstützung für das Parsing von JSON zu Object, mittels JSON.parse().

Objekt-Eigenschaften setzen

Das Setzen von Objekteigenschaften funktioniert auch für Map-Objekte und kann zu erheblicher Verwirrung führen.

Es scheint also in dieser Weise zu funktionieren:

js
const wrongMap = new Map();
wrongMap["bla"] = "blaa";
wrongMap["bla2"] = "blaaa2";

console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }

Aber diese Art des Setzens einer Eigenschaft interagiert nicht mit der Datenstruktur der Map. Es verwendet die Funktion des generischen Objekts. Der Wert von 'bla' wird für Anfragen nicht in der Map gespeichert. Andere Datenoperationen schlagen fehl:

js
wrongMap.has("bla"); // false
wrongMap.delete("bla"); // false
console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }

Die korrekte Verwendung für die Speicherung von Daten in der Map erfolgt über die set(key, value) Methode.

js
const contacts = new Map();
contacts.set("Jessie", { phone: "213-555-1234", address: "123 N 1st Ave" });
contacts.has("Jessie"); // true
contacts.get("Hilary"); // undefined
contacts.set("Hilary", { phone: "617-555-4321", address: "321 S 2nd St" });
contacts.get("Jessie"); // {phone: "213-555-1234", address: "123 N 1st Ave"}
contacts.delete("Raymond"); // false
contacts.delete("Jessie"); // true
console.log(contacts.size); // 1

Map-ähnliche Browser-APIs

Browser Map-ähnliche Objekte (oder "mapähnliche Objekte") sind Web API Schnittstellen, die sich in vielerlei Hinsicht wie eine Map verhalten.

Genau wie Map können Einträge in der gleichen Reihenfolge iteriert werden, in der sie dem Objekt hinzugefügt wurden. Map-ähnliche Objekte und Map haben auch Eigenschaften und Methoden, die denselben Namen und dasselbe Verhalten aufweisen. Im Gegensatz zu Map erlauben sie jedoch nur bestimmte vordefinierte Typen für die Schlüssel und Werte jedes Eintrags.

Die erlaubten Typen werden in der Specification IDL-Definition festgelegt. Zum Beispiel ist RTCStatsReport ein Map-ähnliches Objekt, das Strings für Schlüssel und Objekte für Werte verwenden muss. Dies wird in der folgenden Specification IDL definiert:

webidl
interface RTCStatsReport {
  readonly maplike<DOMString, object>;
};

Map-ähnliche Objekte sind entweder schreibgeschützt oder les- und schreibbar (siehe das readonly Schlüsselwort im obigen IDL).

Die Methoden und Eigenschaften haben dasselbe Verhalten wie die entsprechenden Entitäten in Map, abgesehen von der Einschränkung der Typen der Schlüssel und Werte.

Folgende sind Beispiele für schreibgeschützte Map-ähnliche Browserobjekte:

Konstruktor

Map()

Erzeugt ein neues Map-Objekt.

Statische Eigenschaften

Map[Symbol.species]

Die Konstruktorfunktion, die verwendet wird, um abgeleitete Objekte zu erstellen.

Statische Methoden

Map.groupBy()

Gruppiert die Elemente eines gegebenen Iterables unter Verwendung der durch eine bereitgestellte Callback-Funktion zurückgegebenen Werte. Die endgültige zurückgegebene Map verwendet die einzigartigen Werte aus der Testfunktion als Schlüssel, die verwendet werden können, um das Array von Elementen in jeder Gruppe zu erhalten.

Instanzeigenschaften

Diese Eigenschaften sind auf Map.prototype definiert und werden von allen Map-Instanzen geteilt.

Map.prototype.constructor

Die Konstruktorfunktion, die das Instanzobjekt erstellt hat. Für Map-Instanzen ist der Anfangswert der Map-Konstruktor.

Map.prototype.size

Gibt die Anzahl der Schlüssel/Wert-Paare im Map-Objekt zurück.

Map.prototype[Symbol.toStringTag]

Der Anfangswert der [Symbol.toStringTag]-Eigenschaft ist der String "Map". Diese Eigenschaft wird in Object.prototype.toString() verwendet.

Instanzmethoden

Map.prototype.clear()

Entfernt alle Schlüssel-Wert-Paare aus dem Map-Objekt.

Map.prototype.delete()

Entfernt den durch den Schlüssel angegebenen Eintrag aus dieser Map.

Map.prototype.entries()

Gibt ein neues Iterator-Objekt zurück, das ein Array mit zwei Mitgliedern [key, value] für jedes Element im Map-Objekt in Einfügereihenfolge enthält.

Map.prototype.forEach()

Ruft callbackFn einmal für jedes vorhandene Schlüssel-Wert-Paar im Map-Objekt in Einfügereihenfolge auf. Wenn ein thisArg-Parameter an forEach übergeben wird, wird er als this-Wert für jeden Callback verwendet.

Map.prototype.get()

Gibt den Wert zurück, der dem Schlüssel in dieser Map entspricht, oder undefined, wenn keiner vorhanden ist.

Map.prototype.has()

Gibt einen Boolean-Wert zurück, der angibt, ob ein Eintrag mit dem angegebenen Schlüssel in dieser Map existiert oder nicht.

Map.prototype.keys()

Gibt ein neues Iterator-Objekt zurück, das die Schlüssel für jedes Element im Map-Objekt in Einfügereihenfolge enthält.

Map.prototype.set()

Fügt dieser Map einen neuen Eintrag mit einem angegebenen Schlüssel und Wert hinzu oder aktualisiert einen bestehenden Eintrag, wenn der Schlüssel bereits existiert.

Map.prototype.values()

Gibt ein neues Iterator-Objekt zurück, das die Werte für jedes Element im Map-Objekt in Einfügereihenfolge enthält.

Map.prototype[Symbol.iterator]()

Gibt ein neues Iterator-Objekt zurück, das ein Array mit zwei Mitgliedern [key, value] für jedes Element im Map-Objekt in Einfügereihenfolge enthält.

Beispiele

Verwendung des Map-Objekts

js
const myMap = new Map();

const keyString = "a string";
const keyObj = {};
const keyFunc = () => {};

// setting the values
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");

console.log(myMap.size); // 3

// getting the values
console.log(myMap.get(keyString)); // "value associated with 'a string'"
console.log(myMap.get(keyObj)); // "value associated with keyObj"
console.log(myMap.get(keyFunc)); // "value associated with keyFunc"

console.log(myMap.get("a string")); // "value associated with 'a string'", because keyString === 'a string'
console.log(myMap.get({})); // undefined, because keyObj !== {}
console.log(myMap.get(() => {})); // undefined, because keyFunc !== () => {}

Verwendung von NaN als Map-Schlüssel

NaN kann auch als Schlüssel verwendet werden. Obwohl jedes NaN nicht sich selbst gleich ist (NaN !== NaN ist wahr), funktioniert das folgende Beispiel, weil NaNs voneinander ununterscheidbar sind:

js
const myMap = new Map();
myMap.set(NaN, "not a number");

myMap.get(NaN);
// "not a number"

const otherNaN = Number("foo");
myMap.get(otherNaN);
// "not a number"

Iterieren der Map mit for...of

Maps können mit einer for...of-Schleife iteriert werden:

js
const myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");

for (const [key, value] of myMap) {
  console.log(`${key} = ${value}`);
}
// 0 = zero
// 1 = one

for (const key of myMap.keys()) {
  console.log(key);
}
// 0
// 1

for (const value of myMap.values()) {
  console.log(value);
}
// zero
// one

for (const [key, value] of myMap.entries()) {
  console.log(`${key} = ${value}`);
}
// 0 = zero
// 1 = one

Iterieren der Map mit forEach()

Maps können mit der forEach()-Methode iteriert werden:

js
myMap.forEach((value, key) => {
  console.log(`${key} = ${value}`);
});
// 0 = zero
// 1 = one

Beziehung zu Array-Objekten

js
const kvArray = [
  ["key1", "value1"],
  ["key2", "value2"],
];

// Use the regular Map constructor to transform a 2D key-value Array into a map
const myMap = new Map(kvArray);

console.log(myMap.get("key1")); // "value1"

// Use Array.from() to transform a map into a 2D key-value Array
console.log(Array.from(myMap)); // Will show you exactly the same Array as kvArray

// A succinct way to do the same, using the spread syntax
console.log([...myMap]);

// Or use the keys() or values() iterators, and convert them to an array
console.log(Array.from(myMap.keys())); // ["key1", "key2"]

Klonen und Zusammenführen von Maps

Genau wie Arrays können Maps geklont werden:

js
const original = new Map([[1, "one"]]);

const clone = new Map(original);

console.log(clone.get(1)); // one
console.log(original === clone); // false (useful for shallow comparison)

Hinweis: Beachten Sie, dass die Daten selbst nicht geklont werden. Mit anderen Worten, es handelt sich nur um eine flache Kopie der Map.

Maps können zusammengeführt werden, wobei die Einzigartigkeit der Schlüssel beibehalten wird:

js
const first = new Map([
  [1, "one"],
  [2, "two"],
  [3, "three"],
]);

const second = new Map([
  [1, "uno"],
  [2, "dos"],
]);

// Merge two maps. The last repeated key wins.
// Spread syntax essentially converts a Map to an Array
const merged = new Map([...first, ...second]);

console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three

Maps können auch mit Arrays zusammengeführt werden:

js
const first = new Map([
  [1, "one"],
  [2, "two"],
  [3, "three"],
]);

const second = new Map([
  [1, "uno"],
  [2, "dos"],
]);

// Merge maps with an array. The last repeated key wins.
const merged = new Map([...first, ...second, [1, "un"]]);

console.log(merged.get(1)); // un
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three

Spezifikationen

Specification
ECMAScript® 2026 Language Specification
# sec-map-objects

Browser-Kompatibilität

Siehe auch