Map

Baseline Widely available *

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

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

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

Probieren Sie es aus

const map1 = new Map();

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

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

map1.set("a", 97);

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

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

map1.delete("b");

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

Beschreibung

Map-Objekte sind Sammlungen von Schlüssel-Wert-Paaren. Ein Schlüssel in der Map kann nur einmal vorkommen; er ist einzigartig in der Sammlung der Map. Ein Map-Objekt wird durch Schlüssel-Wert-Paare iteriert — eine for...of Schleife gibt in jeder Iteration ein 2-Elemente-Array mit [key, value] zurück. Die Iteration erfolgt in Einfügereihenfolge, die der Reihenfolge entspricht, in der jedes Schlüssel-Wert-Paar zuerst durch die set()-Methode in die Map eingefügt wurde (das heißt, es gab keinen 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 Hashtabelle (mit O(1)-Nachschau), als Suchbaum (mit O(log(N))-Nachschau) oder als jede andere Datenstruktur dargestellt werden, solange die Komplexität besser als O(N) ist.

Schlüssgleichheit

Die Wertgleichheit basiert auf dem SameValueZero-Algorithmus. (Früher wurde SameValue verwendet, das 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 gemäß der Semantik des === Operators als gleich betrachtet werden.

Objekte vs. Maps

Object ist ähnlich wie Map—beide ermöglichen es Ihnen, Schlüssel auf Werte zu setzen, diese Werte abzurufen, Schlüssel zu löschen und zu 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
Unbeabsichtigte Schlüssel Eine Map enthält standardmäßig keine Schlüssel. Sie enthält nur das, was explizit hineingesetzt wird.

Ein Object hat ein Prototyp, sodass es standardmäßige Schlü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, um mit benutzerdefinierten Schlüsseln und Werten verwendet zu werden.

Das Setzen von benutzerdefinierten Schlüssel-Wert-Paaren in einem Object kann einem Angreifer erlauben, die Prototypen des Objekts zu überschreiben, was zu Objektinjektionsangriffen führen kann. Wie bei der Problematik unbeabsichtigter Schlüssel kann dies auch durch die Verwendung eines null-Prototyp-Objekts gemildert werden.

Schlüsseltypen Eine Map kann als Schlüssel jeden Wert verwenden (einschließlich Funktionen, Objekte oder jegliche primitive Daten). Die Schlüssel eines Object müssen entweder ein String oder ein Symbol sein.
Schlüsselreihenfolge

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

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

Die Ordnung wurde zuerst für eigene Eigenschaften nur in ECMAScript 2015 definiert; ECMAScript 2020 definiert die Ordnung auch für geerbte Eigenschaften. Beachten Sie jedoch, dass kein einziger Mechanismus alle Eigenschaften eines Objekts iteriert; die verschiedenen Mechanismen umfassen jeweils unterschiedliche Untergruppen von Eigenschaften. (for-in schließt nur aufzählbare, string-beschriftete Eigenschaften ein; Object.keys schließt nur eigene, aufzählbare, string-beschriftete Eigenschaften ein; Object.getOwnPropertyNames umfasst eigene, string-beschriftete Eigenschaften, auch wenn nicht aufzählbar; Object.getOwnPropertySymbols macht dasselbe nur für Symbol-beschriftete Eigenschaften, etc.)

Größe

Die Anzahl der Elemente in einer Map kann einfach über ihre size-Eigenschaft abgerufen werden. Die Anzahl der Elemente in einem Object zu bestimmen ist umständlicher und weniger effizient. Eine übliche Methode ist, die length des Arrays zu verwenden, das von Object.keys() zurückgegeben wird.
Iteration Eine Map ist ein iterierbars Objekt, sodass sie direkt iteriert werden kann.

Object implementiert kein Iterationsprotokoll, daher sind Objekte nicht direkt iterierbar mit der JavaScriptfor...of-Anweisung (standardmäßig).

Hinweis:

  • Ein Objekt kann das Iterationsprotokoll implementieren, oder Sie können ein iterierbares Objekt für ein Objekt über Object.keys oder Object.entries erhalten.
  • Die for...in-Anweisung ermöglicht es Ihnen, über die enumerierbaren Eigenschaften eines Objekts zu iterieren.
Leistung

Leistet besser in Szenarien, die häufige Hinzufügungen und Löschungen von Schlüssel-Wert-Paaren beinhalten.

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

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 für Map erstellen, indem Sie JSON.stringify() mit seinem replacer-Argument und JSON.parse() mit seinem reviver-Argument verwenden. Siehe die Stack Overflow-Frage Wie serialisiert man eine ES6 Map mit JSON.stringify?).

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

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

Einstellen von Objekteigenschaften

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

Daher scheint dies auf eine Weise zu funktionieren:

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

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

Aber diese Methode des Setzens einer Eigenschaft interagiert nicht mit der Map-Datenstruktur. Sie nutzt die Funktion des generischen Objekts. Der Wert von 'bla' wird nicht in der Map für Abfragen gespeichert. Andere Operationen mit den Daten schlagen fehl:

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

Die korrekte Verwendung zum Speichern 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-artige Objekte (oder "mapartige Objekte") sind Web API-Schnittstellen, die sich in vielerlei Hinsicht wie eine Map verhalten.

Genau wie bei 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 teilen. Im Gegensatz zu Map erlauben sie jedoch nur bestimmte vorgegebene Typen für die Schlüssel und Werte jedes Eintrags.

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

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

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

Die Methoden und Eigenschaften verhalten sich genauso wie die entsprechenden Entitäten in Map, außer mit der Einschränkung bezüglich der Typen der Schlüssel und Werte.

Die folgenden sind Beispiele für schreibgeschützte Map-ähnliche Browser-Objekte:

Konstruktor

Map()

Erzeugt ein neues Map-Objekt.

Statische Eigenschaften

Map[Symbol.species]

Die Konstrukturfunktion, die zum Erstellen von abgeleiteten Objekten verwendet wird.

Statische Methoden

Map.groupBy()

Gruppiert die Elemente eines gegebenen Iterables mit den Werten, die von einer bereitgestellten Callback-Funktion zurückgegeben werden. Die endgültige zurückgegebene Map verwendet die einzigartigen Werte der Testfunktion als Schlüssel, die verwendet werden können, um das Array der Elemente in jeder Gruppe abzurufen.

Instanzeigenschaften

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

Map.prototype.constructor

Die Konstrukturfunktion, 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()

Gibt true zurück, wenn ein Element im Map-Objekt existierte und entfernt wurde, oder false, wenn das Element nicht existiert. map.has(key) wird anschließend false zurückgeben.

Map.prototype.entries()

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

Map.prototype.forEach()

Ruft callbackFn einmal für jedes 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 Rückruf verwendet.

Map.prototype.get()

Gibt den Wert zurück, der dem übergebenen Schlüssel zugeordnet ist, oder undefined, wenn keiner vorhanden ist.

Map.prototype.has()

Gibt einen booleschen Wert zurück, der anzeigt, ob ein Wert dem übergebenen Schlüssel im Map-Objekt zugeordnet wurde 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()

Setzt den Wert für den übergebenen Schlüssel im Map-Objekt. Gibt das Map-Objekt zurück.

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 zweigliedriges Array von [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. Auch wenn jedes NaN nicht gleich sich selbst ist (NaN !== NaN ist wahr), funktioniert das folgende Beispiel, weil NaNs nicht unterscheidbar 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 über 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 über 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 erhalten bleibt:

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