JavaScript >> Javascript-Tutorial >  >> Tags >> map

ECMAScript 6-Sammlungen, Teil 3:WeakMaps

Weakmaps ähneln regulären Maps darin, dass sie einen Wert einem eindeutigen Schlüssel zuordnen. Dieser Schlüssel kann später verwendet werden, um den identifizierten Wert abzurufen. Weakmaps sind anders, da der Schlüssel ein Objekt sein muss und kein primitiver Wert sein kann. Das mag wie eine seltsame Einschränkung erscheinen, aber es ist eigentlich der Kern dessen, was Weakmaps anders und nützlich macht.

Eine Weakmap enthält nur einen schwachen Verweis auf einen Schlüssel, was bedeutet, dass der Verweis innerhalb der Weakmap die Garbage Collection dieses Objekts nicht verhindert. Wenn das Objekt vom Garbage Collector zerstört wird, entfernt die Weakmap automatisch das von diesem Objekt identifizierte Schlüssel-Wert-Paar. Das kanonische Beispiel für die Verwendung von Weakmaps ist das Erstellen eines Objekts, das sich auf ein bestimmtes DOM-Element bezieht. Zum Beispiel verwaltet jQuery intern einen Cache von Objekten, einen für jedes DOM-Element, auf das verwiesen wurde. Die Verwendung einer Weakmap würde es jQuery ermöglichen, mit einem DOM-Element verknüpften Speicher automatisch freizugeben, wenn es aus dem Dokument entfernt wird.

Das ECMAScript 6 WeakMap Typ ist eine ungeordnete Liste von Schlüssel-Wert-Paaren, wobei der Schlüssel ein Nicht-Null-Objekt sein muss und der Wert einen beliebigen Typ haben kann. Die Schnittstelle für WeakMap ist dem von Map sehr ähnlich darin set() und get() werden verwendet, um Daten hinzuzufügen bzw. Daten abzurufen:

var map = new WeakMap(),
    element = document.querySelector(".element");

map.set(element, "Original");

// later
var value = map.get(element);
console.log(value);             // "Original"

// later still - remove reference
element.parentNode.removeChild(element);
element = null;

value = map.get(element);
console.log(value);             // undefined

In diesem Beispiel wird ein Schlüssel-Wert-Paar gespeichert. Der Schlüssel ist ein DOM-Element, das zum Speichern eines entsprechenden Zeichenfolgenwerts verwendet wird. Dieser Wert wurde später abgerufen, indem das DOM-Element an get() übergeben wurde . Wenn das DOM-Element dann aus dem Dokument entfernt wird und die darauf verweisende Variable auf null gesetzt wird , dann werden die Daten auch aus der Weakmap entfernt und der nächste Versuch, mit dem DOM-Element verknüpfte Daten abzurufen, schlägt fehl.

Dieses Beispiel ist etwas irreführend, da der zweite Aufruf von map.get(element) verwendet den Wert von null (welcher element gesetzt wurde) und kein Verweis auf das DOM-Element. Sie können null nicht verwenden als Schlüssel in Weakmaps, sodass dieser Code nicht wirklich eine gültige Suche durchführt. Leider gibt es keinen Teil der Schnittstelle, mit dem Sie abfragen können, ob eine Referenz gelöscht wurde oder nicht (weil die Referenz nicht mehr existiert).

Hinweis:Die Weakmap set() -Methode gibt einen Fehler aus, wenn Sie versuchen, einen primitiven Wert als Schlüssel zu verwenden. Wenn Sie einen primitiven Wert als Schlüssel verwenden möchten, verwenden Sie am besten Map stattdessen.

Weakmaps haben auch has() um festzustellen, ob ein Schlüssel in der Karte vorhanden ist und delete() zum Entfernen eines Schlüssel-Wert-Paares.

var map = new WeakMap(),
    element = document.querySelector(".element");

map.set(element, "Original");

console.log(map.has(element));   // true
console.log(map.get(element));   // "Original"

map.delete(element);
console.log(map.has(element));   // false
console.log(map.get(element));   // undefined

Hier wird wiederum ein DOM-Element als Schlüssel in einer Weakmap verwendet. Die has() -Methode ist nützlich, um zu überprüfen, ob eine Referenz derzeit als Schlüssel in der Weakmap verwendet wird. Beachten Sie, dass dies nur funktioniert, wenn Sie eine Nicht-Null-Referenz auf einen Schlüssel haben. Der Schlüssel wird mit delete() zwangsweise aus der Weakmap entfernt , an welcher Stelle has() gibt false zurück und get() gab undefined zurück .

Browser-Unterstützung

Sowohl Firefox als auch Chrome haben WeakMap implementiert , in Chrome müssen Sie die ECMAScript 6-Funktionen jedoch manuell aktivieren:Gehen Sie zu chrome://flags und aktivieren Sie „Experimentelle JavaScript-Funktionen“. Beide Implementierungen sind gemäß dem aktuellen Strohmann 1 abgeschlossen Spezifikation (obwohl die aktuelle ECMAScript 6-Spezifikation auch einen clear() definiert Methode).

Nutzung und Einschränkungen

Weakmaps haben einen ganz bestimmten Anwendungsfall im Sinn, nämlich die Zuordnung von Werten zu Objekten, die in Zukunft verschwinden könnten. Die Möglichkeit, Speicher für diese Objekte freizugeben, ist nützlich für JavaScript-Bibliotheken, die DOM-Elemente mit benutzerdefinierten Objekten wie jQuery und YUI umschließen. Es werden wahrscheinlich weitere Anwendungsfälle entdeckt, sobald die Implementierungen abgeschlossen und weit verbreitet sind, aber kurzfristig haben Sie kein schlechtes Gewissen, wenn Sie keinen guten Ort für die Verwendung von Weakmaps finden.

In vielen Fällen ist wahrscheinlich eine normale Karte das, was Sie verwenden möchten. Weakmaps sind dahingehend eingeschränkt, dass sie nicht aufzählbar sind und Sie nicht nachverfolgen können, wie viele Elemente darin enthalten sind. Es gibt auch keine Möglichkeit, eine Liste aller Schlüssel abzurufen. Wenn Sie diese Art von Funktionalität benötigen, müssen Sie eine normale Karte verwenden. Wenn Sie dies nicht tun und nur Objekte als Schlüssel verwenden möchten, ist eine Weakmap möglicherweise die richtige Wahl.

Referenzen

  1. WeakMaps Strawman (ECMA)