JavaScript/Objekte/Map/size

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

Über die Eigenschaft size lässt sich die Anzahl der Einträge einer Map ermitteln.


Syntax

Map.prototype.size


Beschreibung

Ähnlich der Eigenschaft length von Arrays, welche die Zahl der in einem Array enthaltenen Elemente wiedergibt, kann über die Eigenschaft size in Erfahrung gebracht werden, wieviele Einträge in einer Map hinterlegt sind.


Beispiel
const ducks = new Map( ).set('Donald', 'Duck').set('Daisy', 'Duck');

console.log(ducks.size); // 2


In diesem Beispiel wird zunächst eine neue Map erzeugt. Danach werden dieser Map durch den Aufruf der Methode set zwei Einträge hinzugefügt. Schließlich wird der Wert der Eigenschaft size der Map in die Konsole geschrieben, bei dem es sich hier natürlich um die Zahl Zwei handelt.

Keine eigene Eigenschaft

Anders als bei der Eigenschaft length von Arrays, handelt es sich bei size nicht um eine eigene Eigenschaft der einzelnen Instanzen. Das heißt, die Eigenschaft size wird nicht auf den Mapobjekten selbst definiert. Eine Überprüfung mit der Methode hasOwnProperty wie im folgenden Beispiel ergibt entsprechend den Wert false.


Beispiel
const instance = new Map;

console.log(instance.hasOwnProperty('size')); // false


Statt also auf jeder einzelnen Map angelegt zu werden, wird die Eigenschaft size nur auf einem Objekt definiert, nämlich dem prototypischen Objekt des Konstruktors Map, und wann immer die Eigenschaft auf einer Mapinstanz angesprochen wird, wird sie entsprechend über die Prototypenkette referenziert.

Nur lesender Zugriff

Damit die auf Map.prototype definierte Eigenschaft size den richtigen Wert für die Anzahl der Einträge einer beliebigen Map zurückgeben kann, wenn sie über deren Prototypenkette referenziert wird, muss natürlich irgendwie ermittelt werden, um welche Map es sich handelt. Dies geschieht dadurch, dass size als Getter implementiert ist.


Beispiel
const prototype = {
  get size ( ) {
    return this.entries.length;
  }
};

const ducks = Object.create(prototype);
ducks.entries = ['Huey', 'Dewey', 'Louie'];

console.log(ducks.size); // 3


Etwas vereinfacht dargestellt, funktioniert die Eigenschaft size also wie in dem Beispiel oben. Das heißt, die jeweilige Mapinstanz wird innerhalb des Getters über die Kontextvariable this referenziert. Dabei ist nun zu beachten, dass – so wie in dem Beispiel oben – auf Map.prototype kein Setter für die Eigenschaft size definiert ist. Das heißt, die Eigenschaft kann nur gelesen, nicht jedoch geschrieben werden.


Beispiel
const empty = new Map;

empty.size = 12 // TypeError


Dementsprechend verursacht der Versuch, der Eigenschaft size einen Wert zuzuweisen unvermeidlich einen Typfehler, der unbehandelt das Programm terminiert. Dass tatsächlich kein Setter implementiert ist, lässt sich übrigens mit der Methode getOwnPropertyDescriptor in Erfahrung bringen, welche ein Objekt zurückgibt, das die Attribute einer Eigenschaft enthält. Diese Methode wird im folgenden Beispiel für die Eigenschaft size aufgerufen.


Beispiel
const descriptor = Object.getOwnPropertyDescriptor(Map.prototype, 'size');

console.log(typeof descriptor.set); // undefined

console.log(descriptor.configurable); // true


Nach dem Aufruf der Methode getOwnPropertyDescriptor wird das Ergebnis der Überprüfung des Attributes set mit dem Operator typeof in die Konsole geschrieben, wobei bestätigt wird, dass kein Setter für diese Eigenschaft definiert ist. Wie die Ausgabe des Wertes des Attributes configurable zeigt, ist size jedoch konfigurierbar, das heißt es ist grundsätzlich möglich, selbst einen Setter für diese Eigenschaft anzulegen.


Beispiel
Object.defineProperty(Map.prototype, 'size', {
  set (value) {
    if (this.size <= value) {
      return;
    }
    const keys = Array.from(this.keys( )),
    length = keys.length;
    for (let index = value; index < length; index++) {
      this.delete(keys[index]);
    }
  }
});


Ein Setter für die Eigenschaft size könnte wie hier mit der Methode definedProperty definiert werden, wobei für den Fall, dass ein Wert zugewiesen wird der kleiner ist als der gegenwärtige Wert von size, alle überzähligen Einträge aus der Map entfernt werden. Es sei allerdings darauf hingewiesen, dass solche Manipulationen von eingebauten Objekten nicht zu empfehlen sind. Das heißt es wäre grundsätzlich besser, sollte wirklich ein Bedarf bestehen, eine von Map abgeleitete Klasse zu erzeugen und den Setter ebenso wie den Getter auf deren prototypischen Objekt zu definieren, wobei darüber hinaus innerhalb des Setters der zugewiesene Wert geprüft werden sollte, was in dem Beispiel oben aus Gründen der Einfachheit unterlassen wurde.

Spezifikation