WeakMapsのこのシンプルな機能ベースのユースケース/例があります。
ユーザーのコレクションを管理する
私はで始まったUser
その特性が含まれ、オブジェクトfullname
、username
、age
、gender
と呼ばれる方法print
の他のプロパティの人間が読める要約を出力します。
/**
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}`);
}
次に、というusers
キーでマップされた複数のユーザーのコレクションを保持するために呼び出されるMapを追加しましたusername
。
/**
Collection of Users, keyed by username.
*/
var users = new Map();
コレクションの追加には、ユーザーを追加、取得、削除するためのヘルパー関数と、完全を期すためにすべてのユーザーを印刷するための関数も必要でした。
/**
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();
});
}
上記のすべてのコードがNodeJSなどで実行されている場合、users
プロセス全体でマップのみがユーザーオブジェクトへの参照を持ちます。個々のユーザーオブジェクトへの他の参照はありません。
このコードをインタラクティブなNodeJSシェルで実行します。例として、4人のユーザーを追加して印刷します。
既存のコードを変更せずに、ユーザーに情報を追加します
ここで、各ユーザーのソーシャルメディアプラットフォーム(SMP)リンクをユーザーオブジェクトと共に追跡する必要がある新しい機能が必要であるとしましょう。
ここで重要なのは、この機能は既存のコードへの介入を最小限に抑えて実装する必要があることです。
これは、次の方法でWeakMapsで可能です。
Twitter、Facebook、LinkedInの3つの個別のWeakMapを追加します。
/*
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();
ヘルパー関数getSMPWeakMap
が追加され、指定されたSMP名に関連付けられたWeakMapを返すだけです。
/**
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;
}
指定されたSMP WeakMapにユーザーのSMPリンクを追加する関数。
/**
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);
}
}
指定されたSMPに存在するユーザーのみを印刷する機能。
/**
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)}`)
}
});
}
ユーザーのSMPリンクを追加できるようになりました。各ユーザーが複数のSMPにリンクを持つ可能性もあります。
...前の例を続けて、ユーザーにSMPリンクを追加し、ユーザーBillとSarahに複数のリンクを追加して、各SMPのリンクを個別に印刷します。
次にusers
、を呼び出して、ユーザーがマップから削除されたとしdeleteUser
ます。これにより、ユーザーオブジェクトへの参照のみが削除されます。これはまた、ユーザーオブジェクトなしではSMPリンクのいずれにもアクセスできないため、SMPリンクのいずれか/すべて(ガベージコレクションによる)からSMPリンクをクリアします。
...例を続けて、私はユーザーBillを削除してから、ユーザーが関連付けられたSMPのリンクを出力します。
SMPリンクを個別に削除するために追加のコードを追加する必要はなく、この機能が変更される前の既存のコードも変更されません。
WeakMapsの有無にかかわらず、この機能を追加する他の方法がある場合は、コメントしてください。