登录
首页 >  文章 >  前端

如何用 Map 存储键值对并支持非字符串类型的键名

时间:2026-05-05 15:24:36 439浏览 收藏

编程并不是一个机械性的工作,而是需要有思考,有创新的工作,语法是固定的,但解决问题的思路则是依靠人的思维,这就需要我们坚持学习和更新自己的知识。今天golang学习网就整理分享《如何用 Map 存储键值对并支持非字符串类型的键名》,文章讲解的知识点主要包括,如果你对文章方面的知识点感兴趣,就不要错过golang学习网,在这可以对大家的知识积累有所帮助,助力开发能力的提升。

Map支持任意类型键,基于SameValueZero算法比较:对象/数组按引用,原始值按值(0与-0相等);WeakMap仅支持对象键且不可遍历,适合关联对象生命周期的状态缓存。

如何用 Map 存储键值对并支持非字符串类型的键名

Map 支持任意类型的键,包括对象、函数、Symbol、数字、布尔值

JavaScript 的 Map 与普通对象({})本质不同:它不把键强制转为字符串,而是基于 SameValueZero 算法比较键的引用或值。这意味着你可以用 {a: 1}function() {}Symbol('x') 甚至 true 作为键,且不会被隐式转换。

常见错误是误以为 Map.set({}) 后还能用另一个字面量对象 {} 取出值——不行,因为它们是不同引用;而 Map.set(true, 'yes')Map.get(true) 是能匹配的,因为布尔值是原始值,SameValueZero 对原始值按值比较。

  • 对象/数组作键:依赖引用相等,适合缓存“某个实例”的计算结果
  • Symbol 作键:天然唯一,适合私有元数据注入(如给第三方对象打标记)
  • 数字/布尔/null/undefined 作键:按值匹配,但注意 0-0 在 Map 中被视为相同键(SameValueZero 规则)

别用对象字面量模拟 Map,否则键会自动 toString()

如果你写 const obj = {}; obj[{}]obj[{a:1}] = 'value',JS 会把对象调用 .toString() → 得到 '[object Object]',所有对象键都坍缩成同一个字符串。这不是 bug,是语言规范行为。

实操中容易踩坑的场景:

  • 想用 DOM 元素作键缓存样式信息,却用了普通对象 → 所有元素都变成 '[object HTMLDivElement]'
  • 用类实例作配置映射,但误用 {} 导致不同实例覆盖彼此
  • 以为 map[key] = value 能替代 map.set(key, value) → 实际上 Map 实例没有属性访问器,map[key] 永远是 undefined

Map.get() 查找失败时返回 undefined,不是抛错

Object.prototype.propertyIsEnumerablein 操作符不同,Map.get(key) 对不存在的键安静地返回 undefined,不会报错。这既是便利也是陷阱——你无法区分“键存在但值恰好是 undefined”和“键根本不存在”。

正确判断键是否存在,必须用 Map.has(key)

const m = new Map();
m.set({}, undefined);
console.log(m.get({})); // undefined —— 但这是找不到,还是找到了 undefined?
console.log(m.has({})); // false —— 正确方式
  • 若需区分,建议避免显式存 undefined,改用 null 或自定义哨兵值(如 NO_VALUE Symbol)
  • Map.keys() 返回迭代器,不能直接索引,要转数组才可用 [0];频繁随机访问键建议先 Array.from(m.keys())

WeakMap 是更严格的“对象键专用”版本,但不支持遍历

如果键**只可能是对象(且你希望它可被 GC 回收)**,优先选 WeakMap。它不允许用原始值(如字符串、数字)作键,且不暴露 .size.keys().values() 等方法——这是设计使然,防止内存泄漏探测。

典型适用场景:

  • 给第三方库返回的对象附加临时状态,又不想污染其原型或属性
  • 实现私有字段(ES2022 #field 出现前的主流方案)
  • 缓存计算结果,且缓存生命周期应与目标对象一致

注意:WeakMap 的键必须是对象,传入 WeakMap.set('str', 1) 会直接抛 TypeError: Invalid value used as weak map key

今天关于《如何用 Map 存储键值对并支持非字符串类型的键名》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>