> 技术文档 > JavaScript数据结构-Map的使用_js map

JavaScript数据结构-Map的使用_js map

在 JavaScript 中,Map 是 ES6 引入的一种新的数据结构,它类似于对象,也是键值对的集合,但 Map 的键可以是任意类型的值(对象、函数、基本类型等),而传统对象的键只能是字符串或 Symbol,并且Map保留了插入顺序

一、Map 的特性

  • 键值对集合:存储键值对,类似对象
  • 键的多样性‌:键可以是任意数据类型(对象、函数、基本类型等),而不仅限于字符串或 Symbol。
  • 保留‌插入顺序:遍历时按插入顺序返回键值对
  • 直接获取大小‌:通过 size 属性快速获取元素数量
  • 支持‌迭代:原生支持 for…of、forEach 等遍历方式
  • 性能优化‌:在频繁增删键值对的场景下性能更优

二、创建 Map

1、‌创建一个空 Map

const emptySet = new Map();

2、创建一个带有初始键值对的 Map,通过二维数组初始化

const map2 = new Map([ [\'name\', \'张三\'], [\'age\', 25], [1, \'数字键\'], [{}, \'对象键\']]);

三、Map 的常用属性和方法

  • set() 添加元素

    const map = new Map();map.set(\'name\', \'李四\');map.set(1, \'数字一\');map.set({id: 1}, \'对象键值\');
  • get() 获取元素

    console.log(map.get(\'name\')); // 李四console.log(map.get(1)); // 数字一
  • has() 检查键是否存在

    console.log(map.has(\'name\')); // trueconsole.log(map.has(\'address\')); // false
  • delete() 删除元素

    map.delete(\'name\');console.log(map.has(\'name\')); // false
  • clear() 清空 Map

    map.clear();console.log(map.size); // 0
  • size属性 获取大小

    console.log(map.size); // 元素数量

四、遍历 Map

1、 for…of 循环

const map = new Map([ [\'a\', 1], [\'b\', 2], [\'c\', 3]]);for (const [key, value] of map) { console.log(key, value);}

2、forEach 方法

map.forEach((value, key) => { console.log(key, value);});

3、获取迭代器

  • 获取键的迭代器 keys()

    for (const key of map.keys()) { console.log(key);}
  • 获取值的迭代器 values()

    for (const value of map.values()) { console.log(value);}
  • 获取键值对的迭代器 entries()
    返回一个包含 [key, value] 对的迭代器

    for (const [key, value] of map.entries()) { console.log(key, value);}

五、Map 与 Object 的比较

特性 Map Object 键的类型 任意值 String 或 Symbol 键的顺序 插入顺序 不一定 大小 size属性 手动计算 性能(频繁增删) 更优 一般 序列化 不能直接JSON序列化 可以直接序列化 默认键 无 有原型链上的键

六、与对象/数组的转换‌

1、对象转为Map‌

const obj = { a: 1, b: 2 };const map = new Map(Object.entries(obj));

2、Map转为对象‌

const map = new Map([[\"a\", 1], [\"b\", 2]]);const obj = Object.fromEntries(map);

3、Map转为数组‌

console.log([...map]); // 转二维数组console.log([...map.keys()]); // 所有键的数组

七、使用场景

  • 需要键不是字符串/符号时:比如要用对象作为键

  • 需要保持插入顺序时:Map 会记住键的原始插入顺序

  • 频繁增删键值对时:Map 性能更好

  • 需要知道数据大小时:Map 有 size 属性

八、使用示例

1、统计字符出现次数

function countChars(str) { const result = new Map(); for (const char of str) { result.set(char, (result.get(char) || 0) + 1); } return result;}const charCount = countChars(\'hello world\');console.log(charCount.get(\'o\')); // 2

2、使用复杂对象作为键

const user1 = {id: 1, name: \'admin\'};const user2 = {id: 2, name: \'test\'};const userMapData = new Map();userMapData.set(user1, {roleCode: \'admin\', createTime: \'2025-04-09\'});userMapData.set(user2, {roleCode: \'user\', createTime: \'2025-04-09\'});console.log(userMapData.get(user1).roleCode); // \'admin\'

3、对象关联元数据
dom对象本身作为键存储额外数据,避免污染对象属性

const domMetadata = new Map();const button = document.querySelector(\"#myButton\");// 绑定点击次数元数据domMetadata.set(button, { clickCount: 0 });button.addEventListener(\"click\", () => { const metadata = domMetadata.get(button); metadata.clickCount++; console.log(`点击次数:${metadata.clickCount}`);});

九、注意事项

1、对象作为键时: Map 的键是基于引用比较的,两个看起来相同的对象作为键是不同的

const map = new Map();map.set({}, \'value1\');map.set({}, \'value2\');console.log(map.size, map.get({})); // 2 undefined(不同引用)let obj = {};map.set(obj, \'value3\');console.log(map.obj); // value3

2、 NaN 作为键时: 虽然 NaN !== NaN,但在 Map 中被视作同一键

map.set(NaN, \'not a number\');console.log(map.get(NaN)); // \'not a number\'

Map 是一种强大且灵活的数据结构,通过灵活使用 Map,可以更高效地处理复杂键类型和有序键值对的场景,提升代码可读性和性能。