object 、 map 、weakmap区别

140 阅读3分钟

一、基本定义与用途对比

特性ObjectMapWeakMap
键(key)类型只能是字符串或 Symbol任意类型(对象、函数、原始值)只能是对象(不能是原始值)
键的顺序无序(ES6 虽然保证部分顺序,但不建议依赖)有序(按插入顺序)无序
可迭代性不可直接迭代(需用 Object.keys/values/entries可直接迭代(for...of不可迭代
键值统计无法直接获取大小(需 Object.keys(obj).length.size 属性无法获取大小
内存管理强引用,键的引用会阻止垃圾回收强引用弱引用(键对象若无其他引用会被 GC 回收)
性能不适合频繁增删键值适合频繁增删操作适合临时存储对象私有数据
典型使用场景一般的键值对象需要任意类型键或频繁操作缓存、私有数据存储

二、详细区别讲解

1️⃣ 键的类型区别

const obj = {};
obj[1] = 'a';
obj[{x:1}] = 'b';
console.log(obj); // { '1': 'a', '[object Object]': 'b' } —— 键会被转为字符串
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

let obj = {name: 'yo'};
const weakMap = new WeakMap();
weakMap.set(obj, 'some data');
obj = null; // 解除外部引用

// 当垃圾回收时,weakMap中的键会自动被回收

WeakMap 的键是弱引用,不会阻止垃圾回收。

🚫 WeakMap 不可遍历,因为 GC 机制可能随时清除键值。


3️⃣ 可迭代性与遍历

const map = new Map([['a',1], ['b',2]]);
for (const [key, value] of map) {
  console.log(key, value);
}
// 输出:a 1, b 2

Object 没有这样的直接遍历方式,需要:

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 的应用场景?

常见答案:

  1. 私有数据存储(避免暴露给外部):

    const _private = new WeakMap();
    class Person {
      constructor(name) {
        _private.set(this, { name });
      }
      getName() {
        return _private.get(this).name;
      }
    }
    
  2. DOM 元素缓存

    const 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) 创建纯净对象:

const obj = Object.create(null);
obj['__proto__'] = 'polluted'; // 不会污染原型

🧩 面试题 5:Map 与 WeakMap 的区别?

回答关键词:

  • WeakMap 键只能是对象;
  • WeakMap 键是弱引用,不影响 GC;
  • WeakMap 不可遍历;
  • Map 支持任意类型键、可遍历、可统计 size。

四、总结口诀 🧠

🔹 Object:键有限、性能一般、结构化存储
🔹 Map:键无限、性能优、可迭代
🔹 WeakMap:键弱引用、不可遍历、适合缓存