JavaScript 中 Object 和 Map 的详细对比

4 分钟
39 阅读
JavaScript 中 Object 和 Map 的详细对比

JavaScript 中 Object 和 Map 的详细对比

1. 基本定义

Object(对象)

javascript 复制代码
const obj = {
  name: '张三',
  age: 25
};

Map

javascript 复制代码
const map = new Map();
map.set('name', '张三');
map.set('age', 25);

2. 主要区别

2.1 键的类型

  • Object

    • 键只能是字符串或 Symbol
    • 如果使用其他类型作为键,会被自动转换为字符串
    javascript 复制代码
    const obj = {};
    obj[1] = '数字键';  // 键会被转换为 '1'
    obj[{}] = '对象键'; // 键会被转换为 '[object Object]'
  • Map

    • 键可以是任意类型(包括对象、函数、基本类型)
    • 不会自动转换键的类型
    javascript 复制代码
    const map = new Map();
    map.set(1, '数字键');  // 键保持为数字 1
    map.set({}, '对象键'); // 键保持为对象 {}

2.2 键值对数量

  • Object

    • 没有内置方法获取键值对数量
    • 需要使用 Object.keys(obj).length
  • Map

    • size 属性直接获取键值对数量
    javascript 复制代码
    map.size; // 直接获取数量

2.3 迭代

  • Object

    • 没有内置的迭代方法
    • 需要使用 Object.keys()Object.values()Object.entries()
    javascript 复制代码
    for (const key in obj) {
      console.log(key, obj[key]);
    }
  • Map

    • 内置迭代器
    • 可以直接使用 for...of 循环
    javascript 复制代码
    for (const [key, value] of map) {
      console.log(key, value);
    }

2.4 性能

  • Object

    • 在键值对数量较少时性能更好
    • 适合固定结构的数据
  • Map

    • 在频繁增删键值对时性能更好
    • 适合动态变化的数据

2.5 序列化

  • Object

    • 可以直接使用 JSON.stringify() 序列化
    javascript 复制代码
    JSON.stringify(obj); // 可以正常序列化
  • Map

    • 不能直接使用 JSON.stringify() 序列化
    • 需要先转换为数组或对象
    javascript 复制代码
    JSON.stringify(Array.from(map)); // 需要转换

3. 使用场景

适合使用 Object 的场景

  1. 数据结构固定且简单
  2. 需要 JSON 序列化
  3. 键都是字符串或 Symbol
  4. 需要与现有代码或 API 兼容

适合使用 Map 的场景

  1. 键的类型多样
  2. 需要频繁增删键值对
  3. 需要保持键的原始类型
  4. 需要迭代操作
  5. 需要知道键值对数量

4. 常用方法对比

Object 方法

javascript 复制代码
// 创建
const obj = {};

// 设置值
obj.key = 'value';
obj['key'] = 'value';

// 获取值
const value = obj.key;
const value = obj['key'];

// 删除
delete obj.key;

// 检查存在
'key' in obj;
obj.hasOwnProperty('key');

// 获取所有键
Object.keys(obj);

// 获取所有值
Object.values(obj);

// 获取所有键值对
Object.entries(obj);

Map 方法

javascript 复制代码
// 创建
const map = new Map();

// 设置值
map.set('key', 'value');

// 获取值
const value = map.get('key');

// 删除
map.delete('key');

// 检查存在
map.has('key');

// 获取所有键
map.keys();

// 获取所有值
map.values();

// 获取所有键值对
map.entries();

// 清空
map.clear();

// 获取大小
map.size;

5. 特殊特性

Object 的特殊特性

  1. 原型链继承
  2. 可以定义 getter/setter
  3. 支持对象字面量语法
  4. 支持解构赋值

Map 的特殊特性

  1. 保持插入顺序
  2. 键可以是任意类型
  3. 性能优化(大量数据时)
  4. 专门的迭代方法

6. 实际应用示例

使用 Object 的场景

javascript 复制代码
// 用户信息
const user = {
  name: '张三',
  age: 25,
  email: 'zhangsan@example.com'
};

// 配置对象
const config = {
  apiUrl: 'https://api.example.com',
  timeout: 5000,
  retryTimes: 3
};

使用 Map 的场景

javascript 复制代码
// 缓存系统
const cache = new Map();
function getData(key) {
  if (cache.has(key)) {
    return cache.get(key);
  }
  const data = fetchData(key);
  cache.set(key, data);
  return data;
}

// 对象关联
const userMap = new Map();
const user1 = { id: 1 };
const user2 = { id: 2 };
userMap.set(user1, '张三');
userMap.set(user2, '李四');

7. 总结

特性 Object Map
键类型 字符串/Symbol 任意类型
大小获取 需要计算 直接获取
迭代 需要转换 直接支持
性能 少量数据快 大量数据快
序列化 直接支持 需要转换
原型链 支持 不支持
插入顺序 不保证 保证

选择使用 Object 还是 Map 主要取决于具体的使用场景和需求。在大多数情况下,如果数据结构简单且固定,使用 Object 更为合适;如果需要更灵活的数据结构或特殊的键类型,则 Map 是更好的选择。

评论

评论

发表评论