Wann sollte man Map anstelle einfacher JS-Objekte verwenden?

Wann sollte man Map anstelle einfacher JS-Objekte verwenden?

1. Map akzeptiert jeden Schlüsseltyp

Wie bereits erwähnt, konvertiert JS den Schlüssel eines Objekts implizit in eine Zeichenfolge, wenn es sich nicht um eine Zeichenfolge oder ein Symbol handelt.

Glücklicherweise ist der Kartenschlüsseltyp kein Problem

const numbersMap = neue Map();

numbersMap.set(1, 'eins');
numbersMap.set(2, 'zwei');

[...numbersMap.keys()]; // => [1, 2]

1 und 2 sind die Schlüssel in NumbersMap und der Typ dieser Schlüssel (Nummer) bleibt gleich.

Sie können in einem MPA jeden beliebigen Schlüsseltyp verwenden: Zahlen, Boolesche Werte, Zeichenfolgen und Symbole.

const booleansMap = neue Map();

booleansMap.set(true, "Ja");
booleansMap.set(false, "Nö");

[...booleansMap.keys()]; // => [wahr, falsch]

booleansMap verwendet Boolesche Werte als Schlüssel, kein Problem. Im Gegensatz dazu funktionieren Boolesche Schlüssel nicht in einfachen Objekten.

Lassen Sie uns die Vorstellungskraft durchbrechen: Kann das gesamte Objekt als Schlüssel der Karte verwendet werden? Die Antwort lautet: ja.

Objekte als Schlüssel

Angenommen, Sie müssen einige mit einem Objekt verknüpfte Daten speichern, ohne diese Daten dem Objekt selbst zuzuordnen. Dies ist mit einfachen Objekten nicht möglich.

Eine Problemumgehung besteht darin, ein Array von Objekt-Wert-Tupeln zu verwenden:

const foo = { Name: "foo" };
const bar = { Name: "Bar" };

const kindOfMap = [
  [foo, 'Foo-bezogene Daten'],
  [bar, 'Barbezogene Daten']
]

kindOfMap ist ein Array, das Paare von Objekten und zugehörigen Werten enthält.

Das größte Problem bei diesem Ansatz besteht darin, dass die Komplexität des Zugriffs auf Werte nach Schlüssel O(n) beträgt und wir das gesamte Array durchlaufen müssen, um den gewünschten Wert nach Schlüssel zu erhalten.

Funktion getByKey(artOfMap, Schlüssel) {
  für (const [k, v] von kindOfMap) {
    wenn (Schlüssel === k) {
      zurückgeben v;
    }
  }
  Rückgabe undefiniert;
}

getByKey(kindOfMap, foo); // => 'Foo-bezogene Daten'

WeakMap (eine spezialisierte Version von Map) erledigt das oben genannte ohne diesen ganzen Aufwand: Es akzeptiert nur Objekte als Schlüssel.

Der Hauptunterschied zwischen Map und Weakmap besteht darin, dass Weakmap die Speicherbereinigung der Schlüsselobjekte zulässt und so Speicherlecks verhindert.

Es ist sehr einfach, den obigen Code mit WeakMap umzugestalten:

const foo = { Name: "foo" };
const bar = { Name: "Bar" };

const mapOfObjects = neue WeakMap();

mapOfObjects.set(foo, 'Foo-bezogene Daten');
mapOfObjects.set(bar, 'Barbezogene Daten');

mapOfObjects.get(foo); // => 'Foo-bezogene Daten'

Im Gegensatz zu Map akzeptiert WeakMap nur Objekte als Schlüssel und hat weniger Methoden.

2. Map hat keine Einschränkungen hinsichtlich der Schlüsselnamen

Jedes Objekt in JS erbt Eigenschaften vom Prototypobjekt, und das gilt auch für normale Objekte.

Wenn Sie von einem Prototyp geerbte Eigenschaften überschreiben, können Sie Code beschädigen, der von diesen Prototypeigenschaften abhängt:

Funktion isPlainObject(Wert) {
  Rückgabewert.toString() === '[Objekt Objekt]';
}

const Schauspieler = {
  Name: 'Harrison Ford',
  toString: 'Schauspieler: Harrison Ford'
};

// Funktioniert nicht!
isPlainObject(actor); // TypeError: value.toString ist keine Funktion

Eine für einen Objektteilnehmer definierte toString-Eigenschaft überschreibt die vom Prototyp geerbte toString()-Methode. Dies unterbricht isObject(), da es auf der toString()-Methode basiert.

Überprüfen Sie die Liste der Eigenschaften und Methoden, die normale Objekte von ihren Prototypen erben, und vermeiden Sie die Definition benutzerdefinierter Eigenschaften mit diesen Methodennamen.

Angenommen, Sie haben eine Benutzeroberfläche zum Verwalten einiger benutzerdefinierter Felder. Benutzer können benutzerdefinierte Felder hinzufügen, indem sie einen Namen und einen Wert angeben:

Es kann praktisch sein, den Status Ihrer benutzerdefinierten Felder in einem einfachen Objekt zu speichern:

const BenutzerCustomFields = {
  'Farbe': 'blau',
  'Größe': 'mittel',
  'toString': 'Eine blaue Box'
};

Der Benutzer wählt möglicherweise jedoch einen benutzerdefinierten Feldnamen, z. B. „toString“ (wie im Beispiel), einen Konstruktor usw., wodurch unser Objekt beschädigt werden könnte.

Verwenden Sie keine Benutzereingabewerte als Schlüssel für einfache Objekte.

Bei Map gibt es dieses Problem nicht, die Schlüsselwertnamen sind nicht eingeschränkt:

Funktion isMap(Wert) {
  Rückgabewert.toString() === '[Objektzuordnung]';
}

const actorMap = neue Map();

actorMap.set('Name', 'Harrison Ford');
actorMap.set('toString', 'Schauspieler: Harrison Ford');

// Funktioniert!
istMap(SchauspielerMap); // => wahr

Unabhängig davon, dass actorMap eine Eigenschaft namens toString hat, funktioniert die Methode toString() einwandfrei.

3. Karte ist iterierbar

Um über die Eigenschaften eines normalen Objekts zu iterieren, müssen Sie andere statische Hilfsfunktionen verwenden, wie etwa Object.keys() oder Object.entries():

const FarbenHex = {
  'weiß': '#FFFFFF',
  'schwarz': '#000000'
};

für (const [Farbe, Hex] von Object.entries(colorsHex)) {
  Konsole.log(Farbe, Hex);
}
// 'weiß' '#FFFFFF'
// 'schwarz' '#000000'

Object.entries(colorsHex) gibt ein Array von Schlüssel-Wert-Paaren zurück, die aus dem Objekt extrahiert wurden.

Die Karte selbst ist jedoch iterierbar:

const colorsHexMap = neue Map();

colorsHexMap.set('weiß', '#FFFFFF');
colorsHexMap.set('schwarz', '#000000');

für (const [Farbe, Hex] von colorsHexMap) {
  Konsole.log(Farbe, Hex);
}
// 'weiß' '#FFFFFF'
// 'schwarz' '#000000'

colorsHexMap ist iterierbar. Sie können es überall verwenden, wo ein Iterable akzeptiert wird: for()-Schleifen, Spread-Operatoren [...map] .

Map bietet Methoden, die Iterables zurückgeben: map.keys() zum Durchlaufen von Schlüsseln, map.values() zum Durchlaufen von Werten

4. Kartengröße

Ein weiteres Problem bei einfachen Objekten besteht darin, dass man nicht sofort erkennen kann, wie viele Eigenschaften sie enthalten.

const Prüfungen = {
  'John Smith': '10 Punkte',
  'Jane Doe': '8 Punkte',
};

Objekt.Schlüssel(Prüfungen).Länge; // => 2

Um den Umfang der Prüfungen zu ermitteln, müssen alle Schlüssel durchgegangen werden, um deren Anzahl zu ermitteln.

Die Karte verfügt über ein Größenattribut, das die Anzahl der Attribute angibt.

const examsMap = neue Map([
  ['John Smith', '10 Punkte'],
  ['Jane Doe', '8 Punkte'],
]);
  
examsMap.size; // => 2

Die Anzahl der Attribute in einer Karte zu bestimmen ist noch einfacher: examsMap.size.

Oben finden Sie Einzelheiten dazu, wann Map anstelle gewöhnlicher JS-Objekte verwendet werden soll. Weitere Informationen zu JS-Objekten finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • js-Objekt, um einen Daten-Paging-Effekt zu erzielen
  • Detaillierte Erläuterung der Reihenfolge der JS-Objektdurchquerung
  • Beispiele und Vergleich von 3 Methoden zur Deduplizierung von JS-Objekt-Arrays
  • Kopieren von JS-Objekten (Deep Copy und Shallow Copy)
  • Beispielcode zum Konvertieren von Camel Case in Unterstreichung im Attributnamen eines JS-Objekts
  • Detailliertes Beispiel der Lesegeschwindigkeit von JS-Objekten

<<:  mysql5.7.21.zip Installations-Tutorial

>>:  Grafisches Tutorial zur Installation und Konfiguration von MySQL 5.7.21 winx64

Artikel empfehlen

Detaillierte Erklärung zur Anzeige der aktuellen Anzahl an MySQL-Verbindungen

1. Zeigen Sie die detaillierten Informationen all...

Was sind MySQL-Dirty-Pages?

Inhaltsverzeichnis Schmutzige Seiten (Speichersei...

Der Unterschied zwischen GB2312, GBK und UTF-8 in der Webseitenkodierung

Zunächst müssen wir verstehen, dass GB2312, GBK u...

Implementierungsschritte zum Erstellen eines lokalen Webservers auf Centos8

1 Übersicht System CentOS8, verwenden Sie httpd, ...

Detaillierte Erklärung der Beziehung zwischen React und Redux

Inhaltsverzeichnis 1. Die Beziehung zwischen Redu...

element-ui Markieren Sie die Koordinatenpunkte nach dem Hochladen des Bildes

Was ist Element-UI element-ui ist eine auf Vue.js...

So installieren Sie suPHP für PHP5 auf CentOS 7 (Peng Ge)

Standardmäßig wird PHP unter CentOS 7 als Apache ...

Implementierung von 2D- und 3D-Transformationen in CSS3

CSS3 implementiert 2D-Ebenentransformation und vi...

MySQL-Lösung für zeitgesteuerte Backups (mithilfe von Linux crontab)

Vorwort Obwohl manche Liebe auf dieser Welt ihren...

SQL implementiert LeetCode (180. Fortlaufende Zahlen)

[LeetCode] 180. Aufeinanderfolgende Zahlen Schrei...

Lösung für das Problem mit verstümmelten chinesischen MySQL-Zeichen

1. Die chinesischen verstümmelten Zeichen erschei...

Natives JS zum Erzielen digitaler Tisch-Spezialeffekte

Dieser Artikel beschreibt einen Digitaluhreffekt,...