我有一个基于简单功能的用例/ 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}`);
}
然后,我添加了一个Map,users
以保留由键入的多个用户的集合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
Map引用了整个过程中的User Objects。没有其他参考单个用户对象。
作为示例,我在交互式NodeJS shell上运行此代码,我添加了四个用户并打印它们:
在不修改现有代码的情况下向用户添加更多信息
现在说一个新功能是必需的,其中每个用户的社交媒体平台(SMP)链接都需要与用户对象一起进行跟踪。
这里的关键还在于,必须在对现有代码的干预最少的情况下实现此功能。
对于WeakMaps,可以通过以下方式实现。
我为Twitter,Facebook,LinkedIn添加了三个单独的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链接添加到给定SMP WeakMap的功能。
/**
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 WeakMap(通过垃圾回收)中清除SMP链接,因为如果没有User Object,则无法访问其任何SMP链接。
...继续上例,我删除了用户Bill,然后打印出与他关联的SMP的链接:
无需任何其他代码即可单独删除SMP链接,而无需修改该功能之前的现有代码。
如果有其他方法可以添加带有/不带有WeakMaps的此功能,请随时发表评论。