一、基本定义与用途对比
| 特性 | Object | Map | WeakMap | 
|---|---|---|---|
| 键(key)类型 | 只能是字符串或 Symbol | 任意类型(对象、函数、原始值) | 只能是对象(不能是原始值) | 
| 键的顺序 | 无序(ES6 虽然保证部分顺序,但不建议依赖) | 有序(按插入顺序) | 无序 | 
| 可迭代性 | 不可直接迭代(需用 Object.keys/values/entries) | 可直接迭代( for...of) | 不可迭代 | 
| 键值统计 | 无法直接获取大小(需 Object.keys(obj).length) | .size属性 | 无法获取大小 | 
| 内存管理 | 强引用,键的引用会阻止垃圾回收 | 强引用 | 弱引用(键对象若无其他引用会被 GC 回收) | 
| 性能 | 不适合频繁增删键值 | 适合频繁增删操作 | 适合临时存储对象私有数据 | 
| 典型使用场景 | 一般的键值对象 | 需要任意类型键或频繁操作 | 缓存、私有数据存储 | 
二、详细区别讲解
1️⃣ 键的类型区别
            
            
              css
              
              
            
          
          const obj = {};
obj[1] = 'a';
obj[{x:1}] = 'b';
console.log(obj); // { '1': 'a', '[object Object]': 'b' } ------ 键会被转为字符串
            
            
              c
              
              
            
          
          const map = new Map();
map.set(1, 'a');
map.set({x:1}, 'b');
console.log(map); // Map(2) { 1 => 'a', {x:1} => 'b' }✅ Map 的键不会被强制转换为字符串。
2️⃣ 垃圾回收与 WeakMap
            
            
              ini
              
              
            
          
          let obj = {name: 'yo'};
const weakMap = new WeakMap();
weakMap.set(obj, 'some data');
obj = null; // 解除外部引用
// 当垃圾回收时,weakMap中的键会自动被回收✅ WeakMap 的键是弱引用,不会阻止垃圾回收。
🚫 WeakMap 不可遍历,因为 GC 机制可能随时清除键值。
3️⃣ 可迭代性与遍历
            
            
              arduino
              
              
            
          
          const map = new Map([['a',1], ['b',2]]);
for (const [key, value] of map) {
  console.log(key, value);
}
// 输出:a 1, b 2Object 没有这样的直接遍历方式,需要:
            
            
              javascript
              
              
            
          
          Object.entries(obj).forEach(([k,v]) => console.log(k,v));WeakMap 无法遍历,也没有 .entries() / .keys() / .values() 方法。
4️⃣ 性能差异
- Map 在频繁增删键值场景中性能更好
 因为内部实现是 哈希表结构;
- Object 设计初衷是结构化数据存储;
- WeakMap 更适合做"私有数据"或"缓存",防止内存泄漏。
三、常见面试题 🎯
🧩 面试题 1:Object 与 Map 的主要区别是什么?
标准答案:
- Object 的键只能是字符串或 Symbol;
- Map 键可以是任意类型;
- Map 有序、可迭代;
- Map 有 .size;
- Map 增删查改性能更高;
- Object 更轻量但有原型链属性污染问题(除非用 Object.create(null))。
🧩 面试题 2:WeakMap 为什么不可遍历?
回答思路:
- 因为 WeakMap 的键是弱引用;
- 当键对象被垃圾回收后,WeakMap 会自动清理;
- 如果可以遍历,就会暴露被 GC 管理的对象引用,破坏内存回收机制;
✅ 所以 WeakMap 被设计成不可枚举、不可迭代。
🧩 面试题 3:WeakMap 的应用场景?
常见答案:
- 
私有数据存储(避免暴露给外部): kotlinconst _private = new WeakMap(); class Person { constructor(name) { _private.set(this, { name }); } getName() { return _private.get(this).name; } }
- 
DOM 元素缓存 iniconst cache = new WeakMap(); function processNode(node) { if (cache.has(node)) return cache.get(node); let result = heavyComputation(node); cache.set(node, result); return result; }
🧩 面试题 4:如何避免 Object 的原型污染?
标准答案:
使用
Object.create(null)创建纯净对象:
            
            
              javascript
              
              
            
          
          const obj = Object.create(null);
obj['__proto__'] = 'polluted'; // 不会污染原型🧩 面试题 5:Map 与 WeakMap 的区别?
回答关键词:
- WeakMap 键只能是对象;
- WeakMap 键是弱引用,不影响 GC;
- WeakMap 不可遍历;
- Map 支持任意类型键、可遍历、可统计 size。
四、总结口诀 🧠
🔹 Object:键有限、性能一般、结构化存储
🔹 Map:键无限、性能优、可迭代
🔹 WeakMap:键弱引用、不可遍历、适合缓存