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

CSS3-Bézierkurven-Beispiel: Erstellen von Link-Hover-Animationseffekten

Wir verwenden animierte CSS3-Übergänge, um einen ...

Regeln für die Verwendung gemeinsamer MySQL-Indizes

Ein gemeinsamer Index wird auch als zusammengeset...

Detaillierte Erklärung des TIMESTAMPDIFF-Falls in MySQL

1. Syntax TIMESTAMPDIFF(Einheit, Beginn, Ende); G...

So verwenden Sie Typescript zum Kapseln von lokalem Speicher

Inhaltsverzeichnis Vorwort Szenarien für die Verw...

Shell-Skript Nginx-Automatisierungsskript

Dieses Skript kann die Vorgänge zum Starten, Stop...

Detaillierte Einführung in die gespeicherten MySQL-Funktionen

Inhaltsverzeichnis 1. Erstellen Sie eine gespeich...

Mysql-Datumsformatierung und komplexe Datumsbereichsabfrage

Inhaltsverzeichnis Vorwort Anwendungsszenarios fü...

Fallstudie zu JavaScript Anti-Shake

Prinzip Das Prinzip von Anti-Shake ist: Du kannst...

Detaillierte Erklärung zum Anpassen des Stils von CSS-Bildlaufleisten

Dieser Artikel stellt den CSS-Bildlaufleistensele...

Detaillierte Erklärung der Linux-RPM- und Yum-Befehle und -Verwendung

RPM-Paketverwaltung Ein Verpackungs- und Installa...

Tipps zur Verwendung von Bildlaufleisten in HTML

Als wir heute das Pressemitteilungssystem von Niu ...

Vue hält den Benutzer angemeldet (verschiedene Token-Speichermethoden)

Inhaltsverzeichnis So setzen Sie Cookies Nachteil...