以对象为Map键值时,能否按示例访问对应值并调用sendMessage方法?
问题分析与解决方案
你的代码无法按预期访问到目标元素并调用sendMessage方法,核心问题有三个:
1. Map.get()用法错误
Map.get()需要传入具体的键值,而非筛选函数。你写的socketTracker.get(({ userId }) => userId === 123)是无效调用,Map不会遍历键来匹配回调,直接返回undefined。
2. 对象作为Map键的引用特性
你用{ socketId, userId }作为Map的键,但对象是引用类型——每次创建的对象都是新的内存引用,哪怕属性值完全一致,也会被Map判定为不同的键。就算你传入get({ userId: 123, socketId: 456 }),也找不到之前存入的键,因为这是两个不同的对象。
3. sendMessage方法的this指向错误
sendMessage用普通函数声明,调用时this会指向Map的值对象(即包含sendMessage的那个对象),但这个值对象里并没有socketId和userId属性,就算成功调用,也会返回Socket ID: undefined这类错误结果。
修正后的代码示例
根据业务需求,有两种常见的修复方式:
方式一:用唯一标识(如userId)作为Map键
如果userId是唯一的,直接用它作为键最简洁:
const socketTracker = new Map(); const addToSocketTracker = ({ userId, socketId }) => { socketTracker.set(userId, { socketId, userId, // 用箭头函数绑定上下文,直接引用外部变量 sendMessage: () => { return [`Socket ID: ${socketId}`, `User ID: ${userId}`].join('\n') } }); } addToSocketTracker({ userId: 123, socketId: 456 }) // 直接用userId查找 const element = socketTracker.get(123); console.log(element?.sendMessage()); // 输出: // Socket ID: 456 // User ID: 123
方式二:序列化对象作为键(需同时匹配多个属性时)
如果需要同时用userId和socketId作为匹配条件,可以把对象序列化为字符串作为键:
const socketTracker = new Map(); const addToSocketTracker = ({ userId, socketId }) => { const key = JSON.stringify({ userId, socketId }); socketTracker.set(key, { socketId, userId, sendMessage: () => { return [`Socket ID: ${socketId}`, `User ID: ${userId}`].join('\n') } }); } addToSocketTracker({ userId: 123, socketId: 456 }) // 用相同的序列化字符串查找 const element = socketTracker.get(JSON.stringify({ userId: 123, socketId: 456 })); console.log(element?.sendMessage());
内容的提问来源于stack exchange,提问作者Mike K
相关产品推荐
相关产品推荐

