Ich habe diesen einfachen funktionsbasierten Anwendungsfall / Beispiel für WeakMaps.
Verwalten Sie eine Sammlung von Benutzern
Ich begann mit einem off - User
Objekt , deren Eigenschaften umfassen ein fullname
, username
, age
, gender
und ein Verfahren genannt , print
das eines vom Menschen lesbare Zusammenfassung der anderen Eigenschaften druckt.
/**
Basic User Object with common properties.
*/
function User(username, fullname, age, gender) {
this.username = username;
this.fullname = fullname;
this.age = age;
this.gender = gender;
this.print = () => console.log(`${this.fullname} is a ${age} year old ${gender}`);
}
Ich habe dann eine Map hinzugefügt, die aufgerufen wird users
, um eine Sammlung mehrerer Benutzer zu speichern, die von verschlüsselt sind username
.
/**
Collection of Users, keyed by username.
*/
var users = new Map();
Das Hinzufügen der Sammlung erforderte außerdem Hilfsfunktionen zum Hinzufügen, Abrufen, Löschen eines Benutzers und sogar eine Funktion zum Drucken aller Benutzer der Vollständigkeit halber.
/**
Creates an User Object and adds it to the users Collection.
*/
var addUser = (username, fullname, age, gender) => {
let an_user = new User(username, fullname, age, gender);
users.set(username, an_user);
}
/**
Returns an User Object associated with the given username in the Collection.
*/
var getUser = (username) => {
return users.get(username);
}
/**
Deletes an User Object associated with the given username in the Collection.
*/
var deleteUser = (username) => {
users.delete(username);
}
/**
Prints summary of all the User Objects in the Collection.
*/
var printUsers = () => {
users.forEach((user) => {
user.print();
});
}
Wennusers
der gesamte oben genannte Code beispielsweise in NodeJS ausgeführt wird , enthält nur die Map den Verweis auf die Benutzerobjekte innerhalb des gesamten Prozesses. Es gibt keinen weiteren Verweis auf die einzelnen Benutzerobjekte.
Wenn Sie diesen Code als interaktive NodeJS-Shell ausführen, füge ich als Beispiel vier Benutzer hinzu und drucke sie aus:
Fügen Sie Benutzern weitere Informationen hinzu, ohne den vorhandenen Code zu ändern
Angenommen, es ist eine neue Funktion erforderlich, bei der die SMP-Links (Social Media Platform) jedes Benutzers zusammen mit den Benutzerobjekten verfolgt werden müssen.
Der Schlüssel hier ist auch, dass diese Funktion mit minimalem Eingriff in den vorhandenen Code implementiert werden muss.
Dies ist mit WeakMaps folgendermaßen möglich.
Ich füge drei separate WeakMaps für Twitter, Facebook, LinkedIn hinzu.
/*
WeakMaps for Social Media Platforms (SMPs).
Could be replaced by a single Map which can grow
dynamically based on different SMP names . . . anyway...
*/
var sm_platform_twitter = new WeakMap();
var sm_platform_facebook = new WeakMap();
var sm_platform_linkedin = new WeakMap();
Eine getSMPWeakMap
Hilfsfunktion wird einfach hinzugefügt, um die WeakMap zurückzugeben, die dem angegebenen SMP-Namen zugeordnet ist.
/**
Returns the WeakMap for the given SMP.
*/
var getSMPWeakMap = (sm_platform) => {
if(sm_platform == "Twitter") {
return sm_platform_twitter;
}
else if(sm_platform == "Facebook") {
return sm_platform_facebook;
}
else if(sm_platform == "LinkedIn") {
return sm_platform_linkedin;
}
return undefined;
}
Eine Funktion zum Hinzufügen eines Benutzer-SMP-Links zur angegebenen SMP-Schwachkarte.
/**
Adds a SMP link associated with a given User. The User must be already added to the Collection.
*/
var addUserSocialMediaLink = (username, sm_platform, sm_link) => {
let user = getUser(username);
let sm_platform_weakmap = getSMPWeakMap(sm_platform);
if(user && sm_platform_weakmap) {
sm_platform_weakmap.set(user, sm_link);
}
}
Eine Funktion zum Drucken nur der Benutzer, die auf dem angegebenen SMP vorhanden sind.
/**
Prints the User's fullname and corresponding SMP link of only those Users which are on the given SMP.
*/
var printSMPUsers = (sm_platform) => {
let sm_platform_weakmap = getSMPWeakMap(sm_platform);
console.log(`Users of ${sm_platform}:`)
users.forEach((user)=>{
if(sm_platform_weakmap.has(user)) {
console.log(`\t${user.fullname} : ${sm_platform_weakmap.get(user)}`)
}
});
}
Sie können jetzt SMP-Links für die Benutzer hinzufügen, auch mit der Möglichkeit, dass jeder Benutzer einen Link auf mehreren SMPs hat.
... Fortsetzung des vorherigen Beispiels: Ich füge den Benutzern SMP-Links hinzu, mehrere Links für die Benutzer Bill und Sarah, und drucke dann die Links für jedes SMP separat aus:
Angenommen, ein Benutzer wird users
durch einen Anruf aus der Karte gelöscht deleteUser
. Dadurch wird der einzige Verweis auf das Benutzerobjekt entfernt. Dadurch wird auch die SMP-Verbindung von allen SMP WeakMaps (von Garbage Collection) gelöscht, da ohne das Benutzerobjekt keine Möglichkeit besteht, auf eine der SMP-Verbindungen zuzugreifen.
... Wenn ich mit dem Beispiel fortfahre, lösche ich Benutzer Bill und drucke dann die Links der SMPs aus, mit denen er verbunden war:
Es ist kein zusätzlicher Code erforderlich, um den SMP-Link einzeln und den vorhandenen Code einzeln zu löschen, bevor diese Funktion ohnehin nicht geändert wurde.
Wenn es eine andere Möglichkeit gibt, diese Funktion mit / ohne WeakMaps hinzuzufügen, können Sie dies gerne kommentieren.