621 Stimmen

Karte vs Objekt in JavaScript

Ich habe gerade diese Funktion entdeckt:

Karte: Kartenobjekte sind einfache Schlüssel-/Wert-Karten.

Das hat mich verwirrt. Reguläre JavaScript-Objekte sind Wörterbücher, also wie unterscheidet sich eine Karte von einem Wörterbuch? Konzeptionell sind sie identisch (laut einer anderen Frage auf Stack Overflow)

Auch die Dokumentation hilft nicht weiter:

Kartenobjekte sind Sammlungen von Schlüssel/Wert-Paaren, bei denen sowohl die Schlüssel als auch die Werte beliebige ECMAScript-Sprachwerte sein können. Ein bestimmter Schlüsselwert darf nur in einem Schlüssel/Wert-Paar innerhalb der Sammlung der Karte vorkommen. Unterschiedliche Schlüsselwerte werden mit einem Vergleichsalgorithmus diskriminiert, der beim Erstellen der Karte ausgewählt wird.

Ein Kartenobjekt kann seine Elemente in Einfügereihenfolge durchlaufen. Das Kartenobjekt muss mit Hilfe von Hash-Tabellen oder anderen Mechanismen implementiert sein, die im Durchschnitt Zugriffszeiten bieten, die sublinear zur Anzahl der Elemente in der Sammlung sind. Die in dieser Spezifikation von Kartenobjekten verwendeten Datenstrukturen sollen nur die erforderlichen beobachtbaren Semantiken von Kartenobjekten beschreiben. Sie sind nicht als praktisches Implementierungsmodell gedacht.

...klingt für mich immer noch wie ein Objekt, also habe ich offensichtlich etwas übersehen.

Warum erhält JavaScript also ein (gut unterstütztes) Karte-Objekt? Was kann es?

1voto

machineghost Punkte 30596

So viele Antworten hier, aber niemand sagt das Wichtigste in der Antwort, nämlich dass Sie in den meisten Fällen ...


AN EINEM OBJEKT FESTHALTEN!


Map ist besser wenn:

  • Sie nicht-string-Schlüssel verwenden möchten (das ist normalerweise nicht erforderlich, aber in einigen Fällen kann es hilfreich sein)
  • Ihnen die Schlüsselreihenfolge in mehreren Umgebungen wirklich wichtig ist (in den meisten Umgebungen wird die Schlüsselreihenfolge bei Objekten vom JS-Motor beibehalten, aber das ist in der Spezifikation nicht garantiert. Wenn Sie sicher sein müssen, dass die Schlüsselreihenfolge beibehalten wird, verwenden Sie eine Map)
  • Sie sehr große Datensätze haben (wir sprechen von weitaus mehr als 99,9% der JS-Front-Ends, die jemals in ihrer gesamten App verwendet werden ... aber in anderen Situationen, in denen mit riesigen Datenmengen gearbeitet wird, kann eine Map mehr Daten als ein Objekt speichern und potenziell schneller auf diese Daten zugreifen ... aber es handelt sich nur um eine vorzeitige Optimierung, es sei denn, Sie haben viel Daten)
  • Sie hauptsächlich Schleifen durchlaufen (normale alte Objekte haben bessere Schnittstellen für die meisten Dinge, aber um durch sie zu iterieren, müssen Sie sie in ein Array mit Object.keys konvertieren; Maps können direkt durchlaufen werden)

1voto

Dominic Punkte 55062

Ich habe eine Bench durchgeführt und festgestellt, dass Objekte selbst gegenüber einer Map mit numerischen Schlüsseln deutlich schneller sind.

// Erstellen einer Map mit 1000 Einträgen und einem Array von Schlüsseln (gemischt)
const indexes = new Array(1000).fill(0).map((_, i) => i)

const map = indexes.reduce((o, k) => {
    o[k] = k
    return o
}, {})

const es6Map = new Map(indexes.map(v => [v, v]))

indexes.sort(() => Math.random() - 0.5);

Dann Tests für den zufälligen Zugriff auf beide:

for (let i = 0; i < 1000; i++) {
    if (map[i] === 999) {
        console.log('gotcha')
    }
}

for (let i = 0; i < 1000; i++) {
    if (es6Map.get(i) === 999) {
        console.log('gotcha')
    }
}

Die Ergebnisse auf jsbench.me (Chrome 113 Mac M1 Max)

Objekt: 218K ops/s ± 3.84% Am schnellsten

Map: 95K ops/s ± 1.62% 56.39 % langsamer

0voto

Mit diesen beiden Tipps können Sie entscheiden, ob Sie eine Map oder ein Objekt verwenden möchten:

  • Verwenden Sie Maps anstelle von Objekten, wenn die Schlüssel zur Laufzeit unbekannt sind und wenn alle Schlüssel den gleichen Typ haben und alle Werte den gleichen Typ haben.

  • Verwenden Sie Maps, wenn primitive Werte als Schlüssel gespeichert werden müssen, da ein Objekt jeden Schlüssel als Zeichenfolge behandelt, unabhängig davon, ob es sich um einen numerischen Wert, einen booleschen Wert oder einen anderen primitiven Wert handelt.

  • Verwenden Sie Objekte, wenn Logik auf einzelnen Elementen operiert.

Quelle: _Schlüsselsammlungen_

-1voto

-1voto

THX-1138 Punkte 20552

TL;DR: Du kannst den Schlüssel `length' nicht verwenden, um einen Wert in einem Objekt zu speichern, aber in einer Map schon.

Der praktische Grund, warum ich nicht Objekte, sondern lieber Map verwende, ist die Tatsache, dass der Schlüssel eines Objekts für praktische Zwecke nicht nur ein String oder eine Nummer ist, sondern eher eine Untermenge von Strings oder einer Nummer. Insbesondere kann es zu Problemen führen, wenn ein Schlüssel mit dem Namen einer Prototyp-Eigenschaft oder einer bekannten Eigenschaft kollidiert. Zum Beispiel kann das Speichern eines Werts mit dem Schlüssel length dazu führen, dass der Code verwirrt wird, der das Vorhandensein des Schlüssels length verwendet, um festzustellen, ob das gegebene Objekt ein Array ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X