JavaScript/Objekte/Map/set

Aus SELFHTML-Wiki
< JavaScript‎ | Objekte‎ | Map
Wechseln zu: Navigation, Suche

Die Methode set dient dazu, einer Map Einträge hinzuzufügen oder bestehende Einträge zu überschreiben.

Syntax

set(key, value);
Parameter
key
Der Schlüssel für den Eintrag, der geschrieben werden soll.
value
Der zu speichernde Wert

Beide Parameter sind optional. Werden sie weggelassen, verwendet die set-Methode den Wert undefined.

Rückgabewert
Das Map-Objekt, auf dem set aufgerufen wurde.

Beschreibung

Nachdem eine Map erzeugt wurde, können weitere Einträge nur noch einzeln hinzugefügt werden. Für diesen Zweck gibt es die Methode set. Sie prüft zunächst, ob es den angegebenen Schlüssel bereits in der Map gibt. Wenn ja, wird sein Wert überschrieben. Wenn nicht, wird der Map ein neuer Schlüssel hinzugefügt und der Wert darunter gespeichert.

Beispiel
const map = new Map( );

map.set('self', 'html');
map.set('wiki', 'text');
map.set('forum', 'dialog');
map.set('self', 'die energie des verstehens');

console.log(map.has('self')); // true
console.log(Array.from(map.keys())); // ['self', 'wiki', 'forum']

In diesem Beispiel wird eine leere Map erzeugt, auf der danach viermal die Methode set aufgerufen wird, wobei jeweils ein String für Schlüssel und Wert als Argument übergeben wird. Der Schlüssel 'self' wird zweimal geschrieben, so dass 'html' durch 'die energie des verstehens' ersetzt wird.

Schließlich wird mit der Methode has überprüft, ob der Eintrag 'self' auch wirklich hinzugefügt wurde und das Ergebnis dieses Methodenaufrufs in die Konsole geschrieben.

Beachten Sie: Die Reihenfolge, in der eine Map ihre Werte speichert, ist exakt definiert. Wird ein Wert unter einem neuen Schlüssel gespeichert, so wird der Schlüssel immer als letztes in der Map gespeichert. Schreiben Sie einen Wert zu einem existierenden Schlüssel, so wird der alte Wert überschrieben, der Schlüssel behält aber seine Position. Die Liste der vorhandenen Schlüssel fragen Sie mit der Methode keys ab.

Um das zu zeigen, ruft das Beispiel zum Abschluss die Schlüsselliste ab und gibt sie ebenfalls aus. Der Schlüssel 'self' ist vorne geblieben. Allerdings liefert die keys-Methode kein Array, sondern einen sogenannten Iterator für die gespeicherten Schlüssel, der von console.log nicht aufgelistet wird. Array.from durchläuft den Iterator und erstellt ein Array aus den Schlüsseln.

Verkettung von Aufrufen

Da der Rückgabewert der Methode set immer eine Referenz auf die Map ist, auf der die Methode aufgerufen wurde, ist es möglich mehrere Aufruf hintereinander auszuführen, ohne die jeweilige Map erneut referenzieren zu müssen. Die Aufrufe der Methode set können also verkettet werden.

Mehrfachaufruf von set
const map = new Map( ).set('self', 'html').set('wiki', 'text').set('forum', 'dialog').set('self', 'energie');

console.log(Array.from(map.keys())); // ['self', 'wiki', 'forum']

Wie vorhin wird eine leere Map erzeugt, aber die set-Aufrufe erfolgen nicht einzeln auf dem Objekt, das in der Variablen map steht, sondern werden direkt auf dem jeweils zurückgegebenen Map-Objekt des vorhigen Aufrufs durchgeführt. Erst am Ende wird der letzte Rückgabewert in der Variablen gespeichert.

Die Liste der erzeugten Schlüssel wird im Anschluss ausgegeben.

Die verkettete Schreibweise spart zwar Quellcode, hat aber keine Vorteile bei der Ausführungsgeschwindigkeit. Falls Sie eine Funktion erstellen, die eine Map erzeugt und mit Werten initialisiert, dann können Sie - wenn die Programmlogik das zulässt - eine solche Aufruffolge direkt hinter die return Anweisung schreiben und sich damit eine Variable sparen. Besonders lesbar ist das allerdings nicht, Sie sollten ein solches Konstrukt möglichst auf mehrere Zeilen verteilen:

Mehrfachaufruf von set - lesbarer
const map = new Map( )
            .set('self', 'html')
            .set('wiki', 'text')
            .set('forum', 'dialog');

console.log(Array.from(map.keys())); // ['self', 'wiki', 'forum']
Beachten Sie: Ruft man eine Konstruktorfunktion ohne Parameter auf, kann man die Klammern des Funktionsaufrufs eigentlich weglassen. Wenn Sie auf dem erzeugten Objekt aber direkt Methoden aufrufen wollen, führt das zu einem TypeError: Map.set is not a constructor:
Falsches Weglassen der Konstruktorfunktions-Klammern
const map = new Map.set('key', 'value');

Der Punkt-Operator („Methodenzugriffsoperator“) ist höher priorisiert ist als der new-Operator, deshalb wird zuerst Map.set ermittelt und erst darauf new anwendet. Map.set ist aber keine Konstruktorfunktion, sondern hat den Wert undefined (set ist eine Eigenschaft von Map.prototype).

Entweder fügen Sie hinter Map ein leeres Klammerpaar an, so wie es hier alle Beispiele tun, oder sie setzen new Map in Klammern:

So ist's richtig
const map1 = new Map().set('self', 'html');   // leere Argumentklammern - funktioniert
const map2 = (new Map).set('self', 'html');   // gibt new Vorrang vor . - funktioniert

Datentypen für Map-Einträge

Im Gegensatz zu anderen assoziativen Speichern ist ein Map-Objekt nicht auf Zeichenketten als Schlüssel angewiesen. Jeder JavaScript-Typ ist zulässig, sogar Objekte.

Typenvielfalt in einer Map
const map = new Map();
const keyObject = { name: "foo" };
map.set("42", "vier-zwei");
map.set(42, "zweiundvierzig")
map.set(keyObject, "bar");
map.set({ name: "self"}, "html");

console.log(map.get("42"), map.get(42), map.get(keyObject), map.get({ name: "self"}));
// vier-zwei zweiundvierzig bar undefined
//                                  ^----- Nanu?

Die Zeichenkette '42' und die Zahl 42, die vom ==-Operator als gleich registriert würden, haben unterschiedliche Typen und bilden deshalb unterschiedliche Schlüssel.

Dass der Zugriff auf { name: "self"; } das Ergebnis undefined hat, mag Sie vielleicht überraschen. Es hat doch mit keyObject gut funktioniert, warum nicht mit dem Objektliteral? JavaScript erzeugt für jede Verwendung eines Objektliterals ein neues Objekt, so dass hier der Schlüssel, unter dem "html" geschrieben wurde, nicht identisch ist mit dem, der nachher zum Lesen verwendet wird.


Weblinks