Signatur
Beschreibung
Map-Objekte sind Sammlungen von Schlüssel-Wert-Paaren. Ein Schlüssel in der Map darf nur einmal vorkommen; er ist innerhalb der Sammlung der Map eindeutig. Ein Map-Objekt wird über Schlüssel-Wert-Paare iteriert — eine for...of-Schleife liefert bei jeder Iteration ein zweigliedriges Array [key, value]. Die Iteration erfolgt in Einfügereihenfolge, welche der Reihenfolge entspricht, in der jedes Schlüssel-Wert-Paar erstmals über die Methode set() in die Map eingefügt wurde (also als noch kein Schlüssel mit demselben Wert in der Map vorhanden war, als set() aufgerufen wurde).
Die Spezifikation verlangt, 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)-Lookup), als Suchbaum (mit O(log(N))-Lookup) oder als jede andere Datenstruktur dargestellt werden, solange die Komplexität besser als O(N) ist.
Schlüsselgleichheit
Die Wertgleichheit basiert auf dem SameValueZero-Algorithmus. (Früher wurde SameValue verwendet, wodurch 0 und -0 als unterschiedlich behandelt wurden. Siehe Browser-Kompatibilität.) Das bedeutet, dass NaN als gleich mit NaN betrachtet wird (obwohl NaN !== NaN gilt) und alle anderen Werte gemäß der Semantik des ===-Operators als gleich gelten. Für Objekt-Schlüssel basiert die Gleichheit außerdem auf der Objektidentität. Sie werden per Referenz verglichen, nicht per Wert.
Objects vs. Maps
Object ist der Map ähnlich — beide erlauben es, Schlüsseln Werte zuzuweisen, 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 manchen Fällen vorzuziehen machen:
- Unbeabsichtigte Schlüssel: Eine
Mapenthält standardmäßig keine Schlüssel. Sie enthält nur, was explizit hineingesteckt wird. EinObjecthat einen prototype, weshalb es Standard-Schlüssel enthält, die mit eigenen Schlüsseln kollidieren können. - Sicherheit: Eine
Mapkann sicher mit vom Benutzer bereitgestellten Schlüsseln und Werten verwendet werden. Das Setzen benutzerdefinierter Schlüssel-Wert-Paare auf einemObjectkann es einem Angreifer erlauben, den prototype des Objekts zu überschreiben, was zu Object-Injection- oder Prototype-Pollution-Angriffen führen kann. - Schlüsseltypen: Die Schlüssel einer
Mapkönnen beliebige Werte sein (einschließlich Funktionen, Objekte oder beliebige Primitive). Die Schlüssel einesObjectmüssen entweder einStringoder einSymbolsein. - Schlüsselreihenfolge: Die Schlüssel in einer
Mapsind auf klare Weise geordnet: EinMap-Objekt iteriert Einträge, Schlüssel und Werte in Einfügereihenfolge. Die Reihenfolge in einem gewöhnlichenObjectist zwar mittlerweile definiert, war es aber nicht immer und ist komplex. - Größe: Die Anzahl der Elemente in einer
Maplässt sich einfach über die Eigenschaftsizeabrufen. Bei einemObjectist dies umständlicher und weniger effizient. - Iteration: Eine
Mapist ein iterable und kann direkt iteriert werden.Objectimplementiert kein iteration protocol, weshalb Objekte standardmäßig nicht direkt mit derfor...of-Anweisung iteriert werden können. - Performance:
Mapist in Szenarien mit häufigem Hinzufügen und Entfernen von Schlüssel-Wert-Paaren leistungsfähiger.Objectist dafür nicht optimiert. - Serialisierung und Parsing:
Maphat keine native Unterstützung für Serialisierung oder Parsing.Objectunterstützt nativ die Serialisierung nach JSON viaJSON.stringify()und das Parsen aus JSON viaJSON.parse().
Setzen von Objekt-Eigenschaften
Das Setzen von Object-Eigenschaften funktioniert auch bei Map-Objekten und kann zu erheblicher Verwirrung führen. Diese Art, eine Eigenschaft zu setzen, interagiert jedoch nicht mit der Map-Datenstruktur, sondern nutzt das Feature des generischen Objekts. Die korrekte Verwendung zum Speichern von Daten in der Map erfolgt über die Methode set(key, value).
Map-ähnliche Browser-APIs
Browser-Map-ähnliche Objekte (oder „maplike objects") sind Web-API-Schnittstellen, die sich in vielerlei Hinsicht wie eine Map verhalten. Genau wie bei Map können Einträge in derselben Reihenfolge iteriert werden, in der sie dem Objekt hinzugefügt wurden. Map-ähnliche Objekte und Map haben zudem Eigenschaften und Methoden mit demselben Namen und Verhalten. Anders als Map erlauben sie jedoch nur bestimmte, vordefinierte Typen für die Schlüssel und Werte jedes Eintrags.
Map-ähnliche Objekte sind entweder read-only oder read-writable (siehe das Schlüsselwort readonly in der IDL).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $iterable | Iterable<[K, V]>|null|undefined | undefined | Ein iterierbares Objekt, dessen Elemente [Schlüssel, Wert]-Paare sind (z. B. ein Array von Arrays). Wird null, undefined oder nichts übergeben, startet die Map leer. |
Rückgabewert
Map-Instanz, optional bereits mit den angegebenen Schlüssel-Wert-Paaren befüllt.Beispiele
Verwendung des Map-Objekts
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
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"
Map mit for...of 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
Map mit forEach() 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
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)
Maps zusammenführen
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 mit Arrays zusammenführen
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
// Wichtig · Fallstricke
Map.