Map
Baseline
Weitgehend verfügbar
*
Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit Juli 2015 browserübergreifend verfügbar.
* Einige Teile dieser Funktion werden möglicherweise unterschiedlich gut unterstützt.
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 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-Wert-Paaren. Ein Schlüssel darf in einer Map nur einmal vorkommen; er ist innerhalb der Sammlung eindeutig. Über ein Map-Objekt wird anhand seiner Schlüssel-Wert-Paare iteriert: Eine for...of-Schleife liefert bei jedem Durchlauf ein Array mit zwei Elementen, [key, value]. Die Iteration erfolgt in Einfügereihenfolge. Diese entspricht der Reihenfolge, in der die einzelnen Schlüssel-Wert-Paare erstmals mit der Methode set() in die Map eingefügt wurden (das heißt, beim Aufruf von set() war noch kein gleicher Schlüssel in der Map vorhanden).
Die Spezifikation verlangt, dass Maps so implementiert werden, dass sie „im Durchschnitt Zugriffszeiten bieten, die sublinear zur Anzahl der Elemente in der Sammlung sind“. Intern könnte eine Map daher als Hashtabelle (mit einer Suchkomplexität von O(1)), als Suchbaum (mit einer Suchkomplexität von O(log(N))) oder mit einer anderen Datenstruktur umgesetzt sein, solange die Komplexität besser als O(N) ist.
Gleichheit von Schlüsseln
Die Gleichheit von Werten basiert auf dem Algorithmus SameValueZero. (Früher wurde SameValue verwendet, das 0 und -0 als unterschiedlich behandelt. Beachten Sie die Browser-Kompatibilität.) Das bedeutet, dass NaN als gleich NaN gilt (obwohl NaN !== NaN) und alle anderen Werte gemäß der Semantik des Operators === als gleich betrachtet werden. Bei Objekten als Schlüsseln basiert die Gleichheit außerdem auf der Objektidentität. Sie werden anhand ihrer Referenz verglichen, nicht anhand ihres Werts. Beispiele finden Sie unter Das Map-Objekt verwenden.
Objects im Vergleich zu Maps
Object ähnelt Map: Bei beiden können Sie Schlüsseln Werte zuweisen, diese Werte abrufen, Schlüssel löschen und prüfen, ob unter einem Schlüssel etwas gespeichert ist. Aus diesem Grund (und weil es keine integrierten Alternativen gab) wurde Object lange Zeit als Map verwendet.
Es gibt jedoch wichtige Unterschiede, aufgrund derer Map in manchen Fällen vorzuziehen ist:
| Map | Object | |
|---|---|---|
| Unbeabsichtigte Schlüssel |
Eine Map enthält standardmäßig keine Schlüssel. Sie enthält
nur Einträge, die ausdrücklich hinzugefügt wurden.
|
Ein
Hinweis: Dies lässt sich durch
|
| Sicherheit |
Eine Map kann sicher mit Schlüsseln und Werten verwendet
werden, die von Benutzern bereitgestellt werden.
|
Werden von Benutzern bereitgestellte Schlüssel-Wert-Paare einem
|
| Schlüsseltypen |
Die Schlüssel einer Map können beliebige Werte sein
(einschließlich Funktionen, Objekten und primitiven Werten).
|
Die Schlüssel eines Object müssen entweder vom Typ
String oder Symbol sein.
|
| Reihenfolge der Schlüssel |
Die Schlüssel einer |
Zwar haben die Schlüssel eines gewöhnlichen
Die Reihenfolge wurde in ECMAScript 2015 zunächst nur für eigene
Eigenschaften definiert; ECMAScript 2020 definiert sie auch für
geerbte Eigenschaften. Beachten Sie jedoch, dass kein einzelner
Mechanismus über alle Eigenschaften eines Objekts
iteriert. Die verschiedenen Mechanismen berücksichtigen jeweils
unterschiedliche Teilmengen von Eigenschaften.
( |
Größe |
Die Anzahl der Einträge in einer Map lässt sich einfach
über ihre Eigenschaft size abrufen.
|
Die Anzahl der Einträge in einem Object zu ermitteln,
ist umständlicher und weniger effizient. Eine gängige Möglichkeit
besteht darin, die Eigenschaft length
des von Object.keys() zurückgegebenen Arrays abzurufen.
|
| Iteration |
Eine Map ist
iterierbar und kann daher direkt durchlaufen werden.
|
Hinweis:
|
| Leistung |
Bietet eine bessere Leistung, wenn häufig Schlüssel-Wert-Paare hinzugefügt und entfernt werden. |
Ist nicht für das häufige Hinzufügen und Entfernen von Schlüssel-Wert-Paaren optimiert. |
| Serialisierung und Parsing |
Keine native Unterstützung für Serialisierung oder Parsing.
(Sie können jedoch selbst Unterstützung für die Serialisierung
und das Parsing von |
Native Unterstützung für die Serialisierung von
Native Unterstützung für das Parsing von JSON zu |
Objekteigenschaften setzen
Sie können auch bei Map-Objekten Objekteigenschaften setzen. Das kann zu erheblicher Verwirrung führen.
Daher scheint der folgende Ansatz zunächst zu funktionieren:
const wrongMap = new Map();
wrongMap["bla"] = "blaa";
wrongMap["bla2"] = "blaaa2";
console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }
Diese Art, eine Eigenschaft zu setzen, wirkt sich jedoch nicht auf die Datenstruktur der Map aus. Stattdessen wird eine Eigenschaft des allgemeinen Objekts gesetzt. Der Wert von 'bla' wird nicht so in der Map gespeichert, dass er über deren Methoden abgefragt werden kann. Andere Operationen mit den Daten schlagen fehl:
wrongMap.has("bla"); // false
wrongMap.delete("bla"); // false
console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }
Um Daten korrekt in der Map zu speichern, verwenden Sie die Methode set(key, value).
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
Map-ähnliche Browserobjekte (auch „maplike objects“) sind Web-API-Schnittstellen, die sich in vielerlei Hinsicht wie eine Map verhalten.
Wie bei Map kann über ihre Einträge in der Reihenfolge iteriert werden, in der sie dem Objekt hinzugefügt wurden.
Map-ähnliche Objekte und Map haben außerdem Eigenschaften und Methoden mit denselben Namen und demselben Verhalten.
Anders als Map erlauben sie für die Schlüssel und Werte der einzelnen Einträge jedoch nur bestimmte, vordefinierte Typen.
Die zulässigen Typen werden in der IDL-Definition der Spezifikation festgelegt.
Beispielsweise ist RTCStatsReport ein Map-ähnliches Objekt, dessen Schlüssel Strings und dessen Werte Objekte sein müssen.
Dies ist in der folgenden IDL-Definition der Spezifikation festgelegt:
interface RTCStatsReport {
readonly maplike<DOMString, object>;
};
Map-ähnliche Objekte sind entweder schreibgeschützt oder beschreibbar (siehe das Schlüsselwort readonly in der IDL oben).
- Schreibgeschützte Map-ähnliche Objekte haben die Eigenschaft
sizeund die Methodenentries(),forEach(),get(),has(),keys(),values()und[Symbol.iterator](). - Beschreibbare Map-ähnliche Objekte haben zusätzlich die Methoden
clear(),delete()undset().
Die Methoden und Eigenschaften verhalten sich wie die entsprechenden Bestandteile von Map, mit Ausnahme der Einschränkungen für die Typen der Schlüssel und Werte.
Die folgenden Browserobjekte sind Beispiele für schreibgeschützte Map-ähnliche Objekte:
Konstruktor
Map()-
Erstellt ein neues
Map-Objekt.
Statische Eigenschaften
Map[Symbol.species]-
Die Konstruktorfunktion, mit der abgeleitete Objekte erstellt werden.
Statische Methoden
Map.groupBy()-
Gruppiert die Elemente eines übergebenen iterierbaren Objekts anhand der Werte, die eine bereitgestellte Callback-Funktion zurückgibt. Die zurückgegebene
Mapverwendet die eindeutigen Rückgabewerte dieser Funktion als Schlüssel. Über diese Schlüssel lassen sich die Arrays mit den Elementen der jeweiligen Gruppen abrufen.
Instanzeigenschaften
Diese Eigenschaften sind auf Map.prototype definiert und werden von allen Map-Instanzen gemeinsam genutzt.
Map.prototype.constructor-
Die Konstruktorfunktion, mit der das Instanzobjekt erstellt wurde. Bei
Map-Instanzen ist der Anfangswert der KonstruktorMap. Map.prototype.size-
Gibt die Anzahl der Schlüssel-Wert-Paare im
Map-Objekt zurück. Map.prototype[Symbol.toStringTag]-
Der Anfangswert der Eigenschaft
[Symbol.toStringTag]ist der String"Map". Diese Eigenschaft wird vonObject.prototype.toString()verwendet.
Instanzmethoden
Map.prototype.clear()-
Entfernt alle Schlüssel-Wert-Paare aus dem
Map-Objekt. Map.prototype.delete()-
Entfernt den Eintrag mit dem angegebenen Schlüssel aus dieser
Map. Map.prototype.entries()-
Gibt ein neues Iterator-Objekt zurück, das für jeden Eintrag im
Map-Objekt ein Array mit zwei Elementen,[key, value], in Einfügereihenfolge enthält. Map.prototype.forEach()-
Ruft
callbackFnfür jedes Schlüssel-Wert-Paar imMap-Objekt einmal in Einfügereihenfolge auf. WennforEachein ParameterthisArgübergeben wird, dient dieser bei jedem Callback-Aufruf alsthis-Wert. Map.prototype.get()-
Gibt den Wert zurück, der dem Schlüssel in dieser
Mapzugeordnet ist, oderundefined, wenn kein solcher Eintrag vorhanden ist. Map.prototype.getOrInsert()-
Gibt den Wert zurück, der dem angegebenen Schlüssel in dieser
Mapzugeordnet ist. Ist der Schlüssel nicht vorhanden, wird ein neuer Eintrag mit dem Schlüssel und einem angegebenen Standardwert eingefügt; anschließend wird der eingefügte Wert zurückgegeben. Map.prototype.getOrInsertComputed()-
Gibt den Wert zurück, der dem angegebenen Schlüssel in dieser
Mapzugeordnet ist. Ist der Schlüssel nicht vorhanden, wird ein neuer Eintrag mit dem Schlüssel und einem Standardwert eingefügt, den eine angegebene Callback-Funktion berechnet; anschließend wird der eingefügte Wert zurückgegeben. Map.prototype.has()-
Gibt einen booleschen Wert zurück, der angibt, ob in dieser
Mapein Eintrag mit dem angegebenen Schlüssel vorhanden ist. Map.prototype.keys()-
Gibt ein neues Iterator-Objekt zurück, das die Schlüssel aller Einträge im
Map-Objekt in Einfügereihenfolge enthält. Map.prototype.set()-
Fügt dieser
Mapeinen neuen Eintrag mit einem angegebenen Schlüssel und Wert hinzu oder aktualisiert einen vorhandenen Eintrag, wenn der Schlüssel bereits existiert. Map.prototype.values()-
Gibt ein neues Iterator-Objekt zurück, das die Werte aller Einträge im
Map-Objekt in Einfügereihenfolge enthält. Map.prototype[Symbol.iterator]()-
Gibt ein neues Iterator-Objekt zurück, das für jeden Eintrag im
Map-Objekt ein Array mit zwei Elementen,[key, value], in Einfügereihenfolge enthält.
Beispiele
>Das Map-Objekt verwenden
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 !== () => {}
NaN als Map-Schlüssel verwenden
NaN kann ebenfalls als Schlüssel verwendet werden. Obwohl jedes NaN ungleich sich selbst ist (NaN !== NaN ist wahr), funktioniert das folgende Beispiel, weil NaN-Werte nicht voneinander unterscheidbar sind:
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"
Mit for...of über eine Map iterieren
Mit einer for...of-Schleife können Sie über Maps iterieren:
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
Mit forEach() über eine Map iterieren
Mit der Methode forEach() können Sie über Maps iterieren:
myMap.forEach((value, key) => {
console.log(`${key} = ${value}`);
});
// 0 = zero
// 1 = one
Beziehung zu Array-Objekten
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"]
Maps klonen und zusammenführen
Wie Arrays können auch Maps geklont werden:
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 wird nur eine flache Kopie der Map erstellt.
Maps können zusammengeführt werden, wobei die Eindeutigkeit der Schlüssel erhalten bleibt:
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:
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
| Spezifikation |
|---|
| ECMAScript® 2027 Language Specification> # sec-map-objects> |