object 、 map 、weakmap区别

一、基本定义与用途对比

特性 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 2

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

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

常见答案:

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

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

    ini 复制代码
    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) 创建纯净对象:

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

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

回答关键词:

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

四、总结口诀 🧠

🔹 Object:键有限、性能一般、结构化存储

🔹 Map:键无限、性能优、可迭代

🔹 WeakMap:键弱引用、不可遍历、适合缓存

相关推荐
shyshi6 小时前
vercel 部署 node 服务和解决 vercel 不可访问的问题
前端·javascript
.生产的驴6 小时前
React 模块化Axios封装请求 统一响应格式 请求统一处理
前端·javascript·react.js·前端框架·json·ecmascript·html5
前端大神之路6 小时前
vue2 响应式原理
前端
一个努力的小码农6 小时前
Rust中if let与while let语法糖的工程哲学
前端·rust
雾岛听风来6 小时前
Android开发中常用高效数据结构
前端·javascript·后端
IT_陈寒6 小时前
Vue 3性能优化实战:这5个Composition API技巧让你的应用快30%
前端·人工智能·后端
IT_陈寒7 小时前
Vue3性能翻倍的5个秘密:从Composition API到Tree Shaking实战指南
前端·人工智能·后端
IT_陈寒7 小时前
JavaScript 性能优化:3个V8引擎隐藏技巧让你的代码提速50%
前端·人工智能·后端
沐怡旸7 小时前
【技术选型】前端框架:Vue vs React - 组合式API与Hooks的哲学之争
前端·面试