为了账号安全,请及时绑定邮箱和手机立即绑定

为什么在JavaScript中你应该更偏向于使用Map而不是对象

JavaScript 开发者经常使用简单的对象作为键值存储,但 Map 数据结构有几个很有说服力的优点。让我们看看为什么在下一个项目中你可能会选择 Map 而不是普通的对象。

1. 灵活性的关键类型:

Map的一个最重要的优点是它能够将任何值作为键,而不仅仅是字符串和符号。

    // 对象的键总是会被转换为字符串形式
    const obj = {};
    obj[true] = "value1";
    obj[1] = "value2";
    obj[{ key: 1 }] = "value3";

    console.log(Object.keys(obj));
    // 打印结果: ["true", "1", "[object Object]"]

    // 在Map中,键会保持它们原始的类型
    const map = new Map();
    map.set(true, "value1");
    map.set(1, "value2");
    map.set({ key: 1 }, "value3");

    console.log([...map.keys()]);
    // 打印结果: [true, 1, { key: 1 }]

你可以通过点击来进入全屏模式,然后在需要的时候退出全屏模式。

大小管理

地图自带大小属性,而对象的大小则需要手动计算。

    // 对象
    const obj = { a: 1, b: 2, c: 3 };
    const size = Object.keys(obj).length; // 需要转换为数组:
    console.log(size); // 3

    // Map
    const map = new Map([
      ['a', 1],
      ['b', 2],
      ['c', 3]
    ]);
    console.log(map.size); // 3, 直接获取:

全屏 退出全屏

3. 更好的迭代优化

地图旨在频繁添加和删除键值对,并且在迭代时性能更佳。

// 性能测试

const 迭代数 = 1000000;

// 对象
const obj = {};
console.time('对象');
for (let i = 0; i < 迭代数; i++) {
  obj[`key${i}`] = i;
}
for (const key in obj) {
  const value = obj[key];
}
console.timeEnd('对象');

const map = new Map(); // Map 对象
console.time('Map');
for (let i = 0; i < 迭代数; i++) {
  map.set(`key${i}`, i);
}
for (const [key, value] of map) {
  // 直接访问键值
}
console.timeEnd('Map');

进入全屏,退出全屏

4. 常见操作的简单明了的方法

Map 提供了清晰且专为常见操作设计的函数。

    // Map 操作
    const map = new Map();

    // 添加条目
    map.set('key1', 'value1');
    map.set('key2', 'value2');

    // 检查是否存在
    console.log(map.has('key1')); // true

    // 获取值
    console.log(map.get('key1')); // 'value1'

    // 删除条目
    map.delete('key1');

    // 清空所有条目
    map.clear();

    // 与对象进行比较
    const obj = {};

    // 添加条目
    obj.key1 = 'value1';
    obj['key2'] = 'value2';

    // 检查是否存在
    console.log('key1' in obj); // true
    // 或
    console.log(obj.hasOwnProperty('key1')); // true

    // 获取值
    console.log(obj.key1); // 'value1'

    // 删除条目
    delete obj.key1;

    // 清空所有条目
    for (const key in obj) {
      delete obj[key];
    }

切换到全屏模式 切换回正常模式

5. 没有遇到原型链问题

地图不会像对象那样遇到继承问题。

定义一个空对象
const obj = {};
console.log(obj.toString); // [Function: toString]
这表示对象有一个名为toString的函数
console.log(obj.hasOwnProperty('toString')); // false
这表示对象没有直接拥有toString属性

定义一个空的Map
const map = new Map();
console.log(map.get('toString')); // undefined
这表示Map中没有键名为toString的项
console.log(map.has('toString')); // false
这表示Map中不存在键名为toString的项

全屏模式,关闭

6. 使用多种方式轻松进行迭代过程

地图内置了各种循环方法。

    const map = new Map([
      ['name', 'John'],
      ['age', 30],
      ['city', '纽约市']
    ]);

    // 遍历条目
    for (const [key, value] of map) {
      console.log(`${key}: ${value}`);
    }

    // 遍历键
    for (const key of map.keys()) {
      console.log(key);
    }

    // 遍历值
    for (const value of map.values()) {
      console.log(value);
    }

    // 使用 forEach
    map.forEach((value, key) => {
      console.log(`${key}: ${value}`);
    });

点击进入全屏模式 点击退出全屏模式

何时仍然需要使用对象

虽然地图很强大,但在某些情况下,还是用对象更好。

  1. 当你需要 JSON 序列化(Map 对象不能自动序列化)
  2. 当你需要访问简单的属性时
  3. 当你需要使用对象展开操作符
  4. 当你需要与 JSON API 交互时
    // JSON 序列化
    const obj = { name: 'John', age: 30 };
    const jsonStr = JSON.stringify(obj); // 这会正常工作

    const map = new Map([['name', 'John'], ['age', 30]]); // 定义一个 Map 对象
    const jsonStr2 = JSON.stringify(map); // 结果会是空的 JSON 对象

    // 不过,你可以将 Map 转换为 Object 来实现序列化
    const mapAsObj = Object.fromEntries(map);
    const jsonStr3 = JSON.stringify(mapAsObj); // 这也会正常工作

点击进入全屏模式 点击退出全屏模式

结尾

当你需要以下情况时,地图是更好的选择:

  • 查找路线和地点位置
  • 规划旅行
  • 确认方位
  • 搜索附近的设施和便利服务

  • 非字符串键值对
  • 频繁的添加和移除
  • 易于监控大小
  • 更好的迭代性能表现
  • 常见操作的清晰和一致的方法实现
  • 不受原型链问题的困扰

仔细考虑清楚您的用例,但当这些好处符合您的需求时,不要害怕用Map函数。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消