Baseline Widely available *
Der 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 sowohl als Schlüssel als auch als Wert verwendet werden.
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-Werte-Paaren. Ein Schlüssel in der Map
kann nur einmal vorkommen; er ist in der Sammlung der Map
einzigartig. Ein Map
-Objekt wird durch Schlüssel-Werte-Paare iteriert â eine for...of
-Schleife gibt ein 2-Element-Array von [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 erstmals mit der Methode set()
in die Map eingefügt wurde (das heiÃt, es gab keinen Schlüssel mit demselben Wert 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)-Nachschlagen), Suchbaum (mit O(log(N))-Nachschlagen) oder einer anderen Datenstruktur dargestellt werden, solange die Komplexität besser als O(N) ist.
SchlüsselkriteriumDie 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 dasselbe angesehen wird wie NaN
(auch wenn NaN !== NaN
) und alle anderen Werte gemäà der Semantik des ===
-Operators als gleich betrachtet werden.
Object
ist ähnlich wie Map
âbeide ermöglichen es, 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.
Jedoch gibt es wichtige Unterschiede, die Map
in einigen Fällen bevorzugen:
Map
enthält standardmäÃig keine Schlüssel. Sie enthält nur, was explizit hineingesteckt 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 das wird selten gemacht.
Map
ist sicher für die Verwendung mit benutzerdefinierten Schlüsseln und Werten.
Das Setzen von benutzerdefinierten Schlüssel-Wert-Paaren in einem Object
kann es einem Angreifer ermöglichen, das Prototyp des Objekts zu überschreiben, was zu Objekt-Injektionsangriffen führen kann. Ãhnlich wie bei zufälligen Schlüsseln kann dies durch die Verwendung eines Objekts mit null
-Prototyp gemildert werden.
Map
's Schlüssel können beliebige Werte sein (einschlieÃlich Funktionen, Objekte oder beliebige Primitive). Die Schlüssel eines Objects
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ügeoperation.
Obwohl die Schlüssel eines gewöhnlichen Objects
jetzt geordnet sind, war das nicht immer der Fall, und die Ordnung ist komplex. Deshalb ist es am besten, sich nicht auf die Eigenschaftsreihenfolge zu verlassen.
Die Ordnung wurde erstmals für eigene Eigenschaften 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
umfasst nur aufzählbare, string-geschlüsselte Eigenschaften; Object.keys
umfasst nur eigene, aufzählbare, string-geschlüsselte Eigenschaften; Object.getOwnPropertyNames
umfasst eigene, string-geschlüsselte Eigenschaften, auch wenn sie nicht aufzählbar sind; Object.getOwnPropertySymbols
macht dasselbe nur für Symbol
-geschlüsselte Eigenschaften, etc.)
GröÃe
Die Anzahl der Einträge in einerMap
wird leicht über die size
-Eigenschaft abgerufen. Die Bestimmung der Anzahl der Elemente in einem Object
ist umständlicher und weniger effizient. Ein häufiger Weg, dies zu tun, ist über die length
des Arrays, das von Object.keys()
zurückgegeben wird. Iteration Eine Map
ist ein iterables Objekt, daher kann es direkt iteriert werden.
Object
implementiert kein Iterationsprotokoll, und daher sind Objekte nicht direkt iterierbar mit der JavaScript for...of-Anweisung (standardmäÃig).
Hinweis:
Object.keys
oder Object.entries
verwenden.Performs better in scenarios involving frequent additions and removals of key-value pairs.
Nicht optimiert für häufige Hinzufügungen und Entfernungen von Schlüssel-Wert-Paaren.
Serialisierung und ParsenKeine native Unterstützung für Serialisierung oder Parsen.
(Aber Sie können Ihre eigene Serialisierungs- und Parsen-Unterstützung für Map
erstellen, indem Sie JSON.stringify()
mit seinem replacer-Argument verwenden und JSON.parse()
mit seinem reviver-Argument. Siehe die Stack Overflow-Frage Wie machen Sie eine JSON.stringify von einer ES6 Map?).
Native Unterstützung für Serialisierung von Object
zu JSON, unter Verwendung von JSON.stringify()
.
Native Unterstützung für das Parsen von JSON zu Object
, unter Verwendung von JSON.parse()
.
Die Festlegung von Objekt-Eigenschaften funktioniert auch für Map-Objekte und kann zu erheblicher Verwirrung führen.
Daher scheint dies auf folgende Weise zu funktionieren:
const wrongMap = new Map();
wrongMap["bla"] = "blaa";
wrongMap["bla2"] = "blaaa2";
console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }
Aber diese Art, eine Eigenschaft zu setzen, interagiert nicht mit der Map-Datenstruktur. Es verwendet die Funktion des generischen Objekts. Der Wert von 'bla' wird nicht in der Map für Abfragen gespeichert. Andere Operationen auf den Daten schlagen fehl:
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 ist 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
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 Verhalten teilen. Anders als Map
erlauben sie jedoch nur bestimmte vordefinierte Typen für die Schlüssel und Werte jedes Eintrags.
Die erlaubten Typen sind in der IDL-Definition der Spezifikation festgelegt. Zum Beispiel ist RTCStatsReport
ein Map
-ähnliches Objekt, das Strings für Schlüssel und Objekte für Werte verwenden muss. Dies ist in der unten stehenden IDL-Spezifikation definiert:
interface RTCStatsReport {
readonly maplike<DOMString, object>;
};
Map
-ähnliche Objekte sind entweder schreibgeschützt oder schreiblesbar (siehe das Schlüsselwort readonly
in der oben stehenden IDL).
Map
-ähnliche Objekte haben die Eigenschaft size
und die Methoden: entries()
, forEach()
, get()
, has()
, keys()
, values()
, und Symbol.iterator()
.Map
-ähnliche Objekte haben zusätzlich die Methoden: clear()
, delete()
, und set()
.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.
Die folgenden sind Beispiele für schreibgeschützte Map
-ähnliche Browser-Objekte:
Map()
Erstellt ein neues Map
-Objekt.
Map[Symbol.species]
Die Konstruktionsfunktion, die zum Erstellen abgeleiteter Objekte verwendet wird.
Map.groupBy()
Gruppiert die Elemente eines gegebenen Iterables unter Verwendung der Werte, die von einer bereitgestellten Rückruffunktion zurückgegeben werden. Die endgültige zurückgegebene Map
verwendet die eindeutigen Werte der Testfunktion als Schlüssel, die verwendet werden können, um das Array von Elementen in jeder Gruppe zu erhalten.
Diese Eigenschaften sind auf Map.prototype
definiert und werden von allen Map
-Instanzen geteilt.
Map.prototype.constructor
Die Konstruktionsfunktion, die das Instanzobjekt erstellt hat. Für Map
-Instanzen ist der Anfangswert der Map
-Konstruktor.
Map.prototype.size
Gibt die Anzahl der Schlüssel/Werte-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.
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 danach false
zurückgeben.
Map.prototype.entries()
Gibt ein neues Iterator-Objekt zurück, das ein zwei-Element-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 vorhandene Schlüssel-Wert-Paar im Map
-Objekt auf, in Einfügereihenfolge. Wenn ein thisArg
-Parameter an forEach
übergeben wird, wird dieser 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 ein boolesches Ergebnis zurück, das anzeigt, ob ein Wert mit dem übergebenen Schlüssel im Map
-Objekt verknüpft 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()
Legt den Wert für den übergebenen Schlüssel im Map
-Objekt fest. 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 zwei-Element-Array von [key, value]
für jedes Element im Map
-Objekt in Einfügereihenfolge enthält.
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 ebenfalls als Schlüssel verwendet werden. Auch wenn jedes NaN
nicht gleich sich selbst ist (NaN !== NaN
ist wahr), funktioniert das folgende Beispiel, weil NaN
s ununterscheidbar voneinander 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"
Iterieren einer Map mit for...of
Maps können mit einer for...of
-Schleife iteriert werden:
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 einer Map mit forEach()
Maps können mit der forEach()
-Methode iteriert werden:
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"]
Klonen und Zusammenführen von Maps
Genau wie Array
s können Map
s 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 handelt sich nur um eine flache Kopie der Map
.
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 Browser-Kompatibilität Siehe auch
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4