5月28日 03:35

ES6 中的 Map 和原生的 Object 有什么区别?

Map 和 Object 都能存键值对,但 Map 是专门为"字典"场景设计的,解决了 Object 做字典时的几个硬伤。

键的类型:Object 的 key 只能是字符串或 Symbol,数字 1 和字符串 "1" 是同一个 key。Map 的 key 可以是任意类型——对象、函数、NaN 都行,用 SameValueZero 算法比较(NaN 等于 NaN)。

原型链污染:Object 有原型链,obj.__proto__obj.toString 这类属性名会冲突。Object.create(null) 能规避,但写法不直觉。Map 天然没有这个问题。

大小:Map 有 size 属性直接取。Object 要 Object.keys(obj).length

顺序:Map 严格按插入顺序迭代。Object 在 ES6 后基本也按插入顺序,但整数 key 会被提前排列,容易踩坑。

遍历:Map 直接 for...offorEach。Object 要先转数组(Object.entries())或用 for...in(还会遍历原型链)。

性能:频繁增删键值对时 Map 更快。Object 在 V8 中对连续整数 key 有快属性优化,但这种优化对字典场景没帮助。

序列化JSON.stringify 能直接处理 Object。Map 不行,需要先转成数组或对象。

js
const m = new Map(); const obj = {}; m.set(obj, 'value'); // 对象做 key,Object 做不到 m.set(1, 'num'); m.set('1', 'str'); // 1 和 '1' 是不同 key console.log(m.size); // 3

一句话:需要字典数据结构时优先用 Map,需要 JSON 序列化或简单配置对象时用 Object。

追问

WeakMap 和 Map 有什么区别?

WeakMap 的 key 必须是对象,值任意。key 是弱引用——被 GC 回收后对应条目自动消失。不可迭代(没有 sizeforEachkeys()),因为条目随时可能被回收。

MapWeakMap
key 类型任意仅对象
引用方式强引用弱引用
可迭代
size
典型场景字典存储关联私有数据

项目里 WeakMap 用在什么地方?

Vue 3 的响应式系统用 WeakMap 存对象 → 依赖关系,对象被销毁时依赖自动清理,不会内存泄漏。另一个常见场景:给 DOM 节点绑定额外数据,节点移除后数据自动释放。

Object.create(null) 能替代 Map 吗?

能解决原型链污染问题,但解决不了键类型限制、size 获取、顺序保证、迭代便利性。Map 是更完整的方案。

Map 的 key 用 NaN 会怎样?

Map 用 SameValueZero 算法比较键,NaN 等于 NaN,所以 NaN 可以正常作为 key,且不会重复。Object 中 NaN 作为 key 会被转成字符串 "NaN",行为一致,但 Map 的语义更明确。

标签:前端ES6