Karten gegen Objekte in ES6, Wann verwenden?


83

Ref: MDN-Karten

Verwenden Sie Karten über Objekten, wenn Schlüssel bis zur Laufzeit unbekannt sind und wenn alle Schlüssel vom gleichen Typ und alle Werte vom gleichen Typ sind.

Verwenden Sie Objekte, wenn es eine Logik gibt, die einzelne Elemente bearbeitet.

Frage:

Was ist ein anwendbares Beispiel für die Verwendung von Karten über Objekten? insbesondere "Wann wären Schlüssel bis zur Laufzeit unbekannt?"

var myMap = new Map();

var keyObj = {},
    keyFunc = function () { return 'hey'},
    keyString = "a string";

// 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.get(keyFunc));

Ja, das habe ich bemerkt. Da setze ich eine Funktion als Wert. @ JonathanLonowski können Sie sich vorstellen, wann ich das tun sollte, obwohl: (es ist schwierig, an Anwendungsfälle zu denken.
Matthew Harwood

7
Sie können es verwenden, wenn Sie ein DOM-Element angegeben haben, mit dem Sie einige Daten mithilfe eines Objekts verknüpfen möchten. Anstatt beispielsweise die ID des Elements als Schlüssel in einem Objekt zu verwenden, können Sie das Element selbst als Schlüssel in einer Map verwenden, sodass es Ihnen egal ist, ob das Element eine ID (oder eine andere eindeutige Kennung außer einer Objektreferenz) hat ) oder nicht.
RobG

1
@RobG nur eine kleine Ergänzung: In diesem Fall ist es eine WeakMap, die auch hilfreich sein könnte.
Zerkms

1
Ich denke, dies legt nahe, Objekte als / für Datensätze und Maps für jede andere Art von Mapping zu verwenden. Mit Datensätzen meine ich eine Datenstruktur mit einem festen Satz von Feldern, wie zum Beispiel ein Benutzerobjekt, das die Felder hat nameund idzum Beispiel.
Felix Kling

1
Als ich diese MDN-Seite las, war die Aufzählungsliste der Anwendungsfälle viel hilfreicher als der von Ihnen zitierte Absatz. Sicherlich in Bezug auf die in Ihrem Titel gestellte Frage.
CodingIntrigue

Antworten:


51

Was ist ein anwendbares Beispiel für die Verwendung von Karten über Objekten?

Ich denke, Sie haben bereits ein gutes Beispiel gegeben: Sie müssen zumindest Maps verwenden, wenn Sie Objekte (einschließlich Funktionsobjekte) als Schlüssel verwenden.

insbesondere "Wann wären Schlüssel bis zur Laufzeit unbekannt?"

Wann immer sie zur Kompilierungszeit nicht bekannt sind. Kurz gesagt, sollten Sie immer ein verwenden , Mapwenn Sie einen benötigen Schlüssel-Wert - Sammlung . Ein guter Indikator dafür, dass Sie eine Sammlung benötigen, ist das dynamische Hinzufügen und Entfernen von Werten zur Sammlung, insbesondere wenn Sie diese Werte vorher nicht kennen (z. B. werden sie aus einer Datenbank gelesen, vom Benutzer eingegeben usw.).

Im Gegensatz dazu sollten Sie Objekte verwenden, wenn Sie wissen, welche und wie viele Eigenschaften das Objekt beim Schreiben des Codes hat - wenn ihre Form statisch ist. Wie @Felix es ausgedrückt hat: wenn Sie einen Datensatz benötigen . Ein guter Indikator für die Notwendigkeit ist, wenn die Felder unterschiedliche Typen haben und Sie niemals die Klammernotation verwenden müssen (oder eine begrenzte Anzahl von Eigenschaftsnamen darin erwarten müssen).


1
Oder aus einem anderen Blickwinkel: Wenn Sie die Eigenschaften Ihres Objekts auf Datenebene (z. B. for..of) anstelle der Programmebene (z . B. for..in) durchlaufen müssen, verwenden Sie a Map. Weitere Informationen zu diesen Bedingungen finden Sie in dieser Antwort .

Ich werde als Kommentar auch die Tatsache hinzufügen, dass Sie immer dann, wenn Sie nicht wissen, welche Art von Schlüssel Ihr Schlüssel sein wird und Sie keine Zeichenfolge als Schlüsseldatentypen erwarten, map stackoverflow.com/questions/32600157/…
Carmine Tambascia verwenden

26

Ich denke, dass mit ES2015 Mapnur noch zwei Gründe übrig bleiben, einfache Objekte zu verwenden:

  • Sie möchten die Eigenschaften eines Objekttyps überhaupt nicht durchlaufen
  • oder Sie tun dies, aber die Eigenschaftsreihenfolge spielt keine Rolle und Sie können das Programm beim Iterieren von der Datenebene unterscheiden

Wann ist die Immobilienbestellung unwichtig?

  • wenn Sie nur einen einzigen Wert und einige Funktionen haben, die explizit damit verknüpft werden sollten (wie Promise- das ist ein Proxy für einen zukünftigen Wert - und then/ catch)
  • Wenn Sie eine struktur- / datensatzähnliche Datenstruktur mit einem statischen Satz von Eigenschaften haben, die zur "Kompilierungszeit" bekannt sind (normalerweise sind Strukturen / Datensätze nicht iterierbar).

In allen anderen Fällen können Sie die Verwendung in Betracht ziehen Map, da die Eigenschaftsreihenfolge beibehalten und das Programm (alle dem MapObjekt zugewiesenen Eigenschaften ) von der Datenebene (alle Einträge in sich Mapselbst) getrennt wird.

Was sind die Nachteile von Map?

  • Sie verlieren die prägnante Objektliteral-Syntax
  • Sie benötigen benutzerdefinierte Ersetzer für JSON.stringyfy
  • Sie verlieren die Destrukturierung, was bei statischen Datenstrukturen ohnehin nützlicher ist

Diese Zeile beschäftigt mich sehr: "Es ist wahrscheinlich langsamer als reine, Hashmap-ähnliche Objekte." Ich dachte daran, alle meine Objekte aufgrund von Leistungsverbesserungen durch Karten zu ersetzen. Aber Sie sagen, es ist langsamer ...
Mesqueeb

1
Du hast recht. Mapist wahrscheinlich schneller, weil es nur auf einem Hash basiert, während Objectes etwas komplizierter ist. Vielen Dank!

11

Verwenden Sie Karten über Objekten, wenn Schlüssel bis zur Laufzeit unbekannt sind und wenn alle Schlüssel vom gleichen Typ und alle Werte vom gleichen Typ sind.

Ich habe keine Ahnung, warum jemand etwas so offensichtlich Falsches schreiben würde. Ich muss sagen, die Leute finden heutzutage immer mehr falsche und / oder fragwürdige Inhalte auf MDN.

Nichts in diesem Satz ist richtig. Der Hauptgrund für die Verwendung von Karten liegt darin, dass Sie Schlüssel mit Objektwerten möchten. Die Idee, dass die Werte vom gleichen Typ sein sollten, ist absurd - obwohl dies natürlich der Fall sein könnte. Die Idee, dass man Objekte nicht verwenden sollte, wenn Schlüssel bis zur Laufzeit unbekannt sind, ist ebenso absurd.


1
Ich verstehe nicht, was an dieser Idee so absurd ist? Wenn Sie Sammlungen benötigen, werden diese normalerweise streng typisiert (es kann natürlich Ausnahmen geben). Ich denke auch, dass es kein Mapguter Rat ist , keine Objekte mehr für Sammlungen zu verwenden (wenn verfügbar).
Bergi

Daß Sammlungen normalerweise streng typisiert sind, unterscheidet sich logischerweise von der Aussage, dass etwas streng typisiertes eine Sammlung sein sollte.

1
Ja, ich denke, es ist ein bisschen seltsam, aber die Idee ist in Ordnung. Ich denke, dass sie dachten, "Schlüssel sind bis zur Laufzeit unbekannt", macht bereits eine Sammlung. Irgendeine Idee für eine bessere Formulierung?
Bergi

1
Einverstanden. MDN hat eine sehr gute Dokumentation, aber sie sollten sich an die Dokumentation des API-Dokuments halten und nicht versuchen, Programmierhinweise zu geben.
AlexG

5

Einer der Unterschiede zwischen Mapund Objectist:

Mapkann einen komplexen Datentyp als Schlüssel verwenden. so was:

const fn = function() {}
const m = new Map([[document.body, 'stackoverflow'], [fn, 'redis']]);

m.get(document.body) // 'stackoverflow'
m.get(fn) //'redis'

Achtung: Bei komplexen Datentypen müssen Sie dieselbe Referenz wie der Schlüssel übergeben, wenn Sie den Wert erhalten möchten.

Objectakzeptiert es nur den einfachen Datentyp ( number, string) als Schlüssel.

const a = {};
a[document.body] = 'stackoverflow';

console.log(a) //{[object HTMLBodyElement]: "stackoverflow"}

2

Diese Frage ist ein Duplikat von aber bis es geschlossen ist, hier ist meine Antwort von dort drüben :

Zusätzlich zu den anderen Antworten habe ich festgestellt, dass Karten unhandlicher und ausführlicher zu handhaben sind als Objekte.

obj[key] += x
// vs.
map.set(map.get(key) + x)

Dies ist wichtig, da kürzerer Code schneller zu lesen, direkter auszudrücken und besser im Kopf des Programmierers bleibt .

Ein weiterer Aspekt: ​​Da set () die Karte und nicht den Wert zurückgibt, ist es unmöglich, Zuordnungen zu verketten.

foo = obj[key] = x;  // Does what you expect
foo = map.set(key, x)  // foo !== x; foo === map

Das Debuggen von Karten ist auch schmerzhafter. Unten können Sie nicht sehen, welche Schlüssel sich auf der Karte befinden. Sie müssten Code schreiben, um das zu tun.

Viel Glück bei der Bewertung eines Map Iterator

Objekte können von jeder IDE ausgewertet werden:

WebStorm bewertet ein Objekt


6
Dies beantwortet überhaupt nicht die Frage " Was ist ein anwendbares Beispiel für die Verwendung von Karten über Objekten? "
Bergi

6
Bitte posten Sie Ihre Antworten nicht. Und nein, die Frage ist kein Duplikat.
Bergi

1

Objects sind s insofern ähnlich Map, als Sie mit beiden Schlüssel auf Werte setzen, diese Werte abrufen, Schlüssel löschen und erkennen können, ob etwas an einem Schlüssel gespeichert ist. Aus diesem Grund (und weil es keine eingebauten Alternativen gab) wurden Objects als Maps historisch verwendet; Es gibt jedoch wichtige Unterschiede, die die Verwendung eines Mapin bestimmten Fällen vorzuziehen machen :

  • Die Schlüssel von a Objectsind Strings und Symbols, während sie ein beliebiger Wert für a sein können Map, einschließlich Funktionen, Objekte und beliebiger Grundelemente.
  • Die Schlüssel in Mapwerden sortiert, die zum Objekt hinzugefügten Schlüssel nicht. Wenn ein MapObjekt darüber iteriert, gibt es die Schlüssel in der Reihenfolge des Einfügens zurück.
  • Sie können die Größe eines Mapeinfach mit der sizeEigenschaft ermitteln, während die Anzahl der Eigenschaften in einem Objectmanuell ermittelt werden muss.
  • A Mapist iterierbar und kann daher direkt iteriert werden, wohingegen das Iterieren über a das ObjectErhalten seiner Schlüssel auf irgendeine Weise und das Iterieren über sie erfordert.
  • An Objecthat einen Prototyp, daher gibt es Standardschlüssel in der Karte, die mit Ihren Schlüsseln kollidieren können, wenn Sie nicht vorsichtig sind. Ab ES5 kann dies mit umgangen werdenmap = Object.create(null) , dies wird jedoch selten durchgeführt.
  • A Mapkann in Szenarien mit häufigem Hinzufügen und Entfernen von Schlüsselpaaren eine bessere Leistung erzielen.

MDN

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.