JavaScript中的Map类
在 JavaScript 中,Map 是 ES6(ECMAScript 2015)引入的一种全新的数据结构,用于存储键值对(key-value pairs)。
专门用来解决传统对象({})无法用非字符串 / 非 Symbol 类型作为键、键会被隐式转换、无法获取键值对数量等痛点。
一、为什么需要 Map?与 Object 的对比
在使用
Map 之前,开发者通常用普通对象 {} 来存储键值对,但对象存在以下局限:表格
| 特性 | Object | Map |
|---|---|---|
| 键的类型 | 只能是字符串或 Symbol | 任意类型(对象、函数、数字、布尔值等) |
| 键值对数量 | 需手动计算(Object.keys().length) |
直接通过 .size 获取 |
| 遍历顺序 | ES2015 前不保证,之后按插入顺序(但语义不清晰) | 严格保证插入顺序 |
| 原型干扰 | 可能继承原型链上的属性(如 toString) |
无原型污染,纯净的键值对集合 |
| 性能 | 频繁增删时性能较差 | 针对增删优化,大数据量下性能更优 |
| 序列化 | 可直接 JSON.stringify |
需手动转换(如转为数组或对象) |
✅ 结论:当你需要非字符串键、频繁操作、或明确需要有序集合时,优先使用 Map。
二、Map 的基本用法
1. 创建 Map
// 空 Map
const map = new Map();
// 初始化时传入二维数组
const userMap = new Map([
['name', '小明'],
['年龄',18 ], // 数字键
['是学生',true] // 布尔键
]);
Myname = userMap.get('name');
console.log(Myname)
MyAge = userMap.get('年龄');
console.log(MyAge)
MyStudent = userMap.get('是学生')
console.log(MyStudent)
运行结果如下:

2. 核心 API
| 方法 | 说明 | 示例 |
|---|---|---|
set(key, value) |
添加或更新键值对,支持链式调用 | map.set('a', 1).set('b', 2) |
get(key) |
获取指定键的值,不存在返回 undefined |
map.get('a') |
has(key) |
判断是否存在某键 | map.has('a') // true |
delete(key) |
删除指定键,返回是否删除成功 | map.delete('a') |
clear() |
清空所有键值对 | map.clear() |
size |
属性,返回键值对数量 | map.size |
map.entries() |
[key, value] (数组) |
需要同时处理键和值时(默认遍历方式) |
2.1 基本用法
const map = new Map();
map.set('name', 'Bob');
map.set(100, 'number-key');
map.set({ id: 1 }, 'object-key');
console.log(map.get('name')); // "Bob"
console.log(map.get(100)); // "number-key"
console.log(map.has({ id: 1 })); // false!(不同对象引用)
console.log(map.size); // 3
const objKey = { id: 1 };
map.set(objKey, 'same-object-key');
console.log(map.has(objKey)); // true(相同引用)
console.log(map.size) // 4
map.clear() // 清空
console.log(map.size); // 0
⚠️ 注意:对象作为键时,比较的是引用地址,而非内容。两个内容相同但不同的对象被视为不同的键。
运行结果如下:

2.2 map.entries()用法
map.entries() 是 JavaScript Map 对象的一个方法,用于返回一个新的迭代器(Iterator)对象。这个迭代器包含了 Map 中所有键值对的数组,格式为 [key, value]。它是
Map 遍历的核心机制之一,也是 for...of 循环默认调用的方法。 基本用法与返回值 ,如下:
const map = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
const iterator = map.entries();
console.log(iterator);
// 输出: MapIterator { [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] }
运行结果如下:
HTML中输出结果如下:

- 返回值:一个
Map Iterator对象。 - 内容格式:每次迭代产出一个包含两个元素的数组
[key, value]。 - 顺序:严格按照插入顺序排列。
配合 for...of 循环(最常用),可以直接解构出 key 和 value,代码如下所示:
const map = new Map([
['name', 'Alice'],
['age', 25],
['role', 'Admin']
]);
for (const [key, value] of map.entries()) {
console.log(`${key}: ${value}`);
}
// 输出:
// name: Alice
// age: 25
// role: Admin
运行结果如下:

💡 小知识:如果你直接写 for (const [key, value] of map),其实底层自动调用的就是 map.entries()。所以以下两行代码效果完全一样:
for (const [k, v] of map) { ... } // 简写
for (const [k, v] of map.entries()) { ... } // 显式调用
如果你想把 Map 的所有键值对一次性变成一个二维数组,可以使用扩展运算符 ... 或 Array.from()。
const entriesArray = [...map.entries()];
// 结果: [ ['name', 'Alice'], ['age', 25], ['role', 'Admin'] ]
// 或者
const entriesArray2 = Array.from(map.entries());
三、遍历 Map
Map 是可迭代对象,支持多种遍历方式,且默认按插入顺序。1. for...of 遍历
const map = new Map([['a', 1], ['b', 2]]);
// 遍历 [键, 值]
for (const [key, value] of map) {
console.log(key, value); // a 1 b 2
}
// 只遍历键
for (const key of map.keys()) {
console.log(key); // a b
}
// 只遍历值
for (const value of map.values()) {
console.log( value); // 1 2
}
// 遍历键值对
for (const [key, value] of map.entries()) {
console.log(key, value); // a 1 b 2
}
运行结果如下:

2. forEach 方法
// // 空 Map
// const map = new Map();
//
// // 初始化时传入二维数组
// const userMap = new Map([
// ['name', '小明'],
// ['年龄',18 ], // 数字键
// ['是学生',true] // 布尔键
// ]);
// Myname = userMap.get('name');
// console.log(Myname)
//
// MyAge = userMap.get('年龄');
// console.log(MyAge)
//
// MyStudent = userMap.get('是学生')
// console.log(MyStudent)
// const map = new Map();
//
// map.set('name', 'Bob');
// map.set(100, 'number-key');
// map.set({ id: 1 }, 'object-key');
//
// console.log(map.get('name')); // "Bob"
// console.log(map.get(100)); // "number-key"
// console.log(map.has({ id: 1 })); // false!(不同对象引用)
// console.log(map.size); // 3
//
// const objKey = { id: 1 };
// map.set(objKey, 'same-object-key');
// console.log(map.has(objKey)); // true(相同引用)
//
// console.log(map.size) // 4
//
// map.clear() // 清空
// console.log(map.size); // 0
const map = new Map([['a', 1], ['b', 2]]);
// 遍历 [键, 值]
for (const [key, value] of map) {
console.log(key, value); // a 1 b 2
}
// 只遍历键
for (const key of map.keys()) {
console.log(key); // a b
}
// 只遍历值
for (const value of map.values()) {
console.log( value); // 1 2
}
// 遍历键值对
for (const [key, value] of map.entries()) {
console.log(key, value); // a 1 b 2
}
// 分隔线
console.log("-----------------")
// forEach的用法
map.forEach((value, key) => {
console.log(key, value);
});
运行结果如下:
四、Map 与普通对象({})的区别
关键区别示例
// 对象:数字键会被转成字符串
const obj = {};
obj[1] = '这是“对象”';
console.log(obj['1']); // (键被隐式转换)
// Map:数字键和字符串键是两个不同键
const map = new Map();
map.set(1, '这是“Map类”');
console.log(map.get(1)); //
console.log(map.get('1')); // 输出“undefined” ✔ 不混淆
运行结果如下:
五、高级用法
1. 对象作为键(Map 最强特性)
const user1 = { name: '张三' };
const user2 = { name: '李四' };
const map = new Map();
map.set(user1, '管理员');
map.set(user2, '普通用户');
console.log(map.get(user1));; // '管理员'
运行结果如下:
2. Map ↔ 对象 互转
// Map → 对象(要求 Map 的键必须是字符串/Symbol)
const map = new Map([['a', 1], ['b', 2]]);
const obj = Object.fromEntries(map);
console.log(obj)
// 对象 → Map
const obj2 = { a: 1, b: 2 };
const map2 = new Map(Object.entries(obj2));
console.log(map2)
运行结果如下:
2. Map ↔ 数组 互转
const map = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
const arr = Array.from(map);
console.log(arr)
// 结果:[['a',1], ['b',2], ['c',3]]
// 或用扩展运算符:
const arr2 = [...map];
console.log(arr2)
运行结果如下:
六、注意事项
const map = new Map();
map.set({}, '空对象');
console.log(map.get({})); // undefined !!! 两个 {} 不是同一个对象
运行结果如下:

Map 是引用类型,赋值是传引用,不是深拷贝
2.new Map(iterable) 对参数的唯一要求
new Map(iterable) 对参数的唯一要求是:- 必须是可迭代的(拥有
Symbol.iterator方法,能被for...of遍历)。 - 遍历出的每一项必须是一个包含两个元素的序列(第一项作为 key,第二项作为 value)。
如果传入的数据不符合这两点(例如传入一个普通对象
{ a: 1 } 或者一维数组 ['a', 'b']),程序会报错。❌ 错误示范
// 错误 1: 传入普通对象 (对象默认不可迭代)
new Map({ a: 1, b: 2 });
// TypeError: object is not iterable
// 错误 2: 传入一维数组 (迭代出来的是单个字符/元素,不是 [key, value] 对)
new Map(['a', 'b']);
// TypeError: Iterator result undefined is not an object (或者类似的解构错误)

浙公网安备 33010602011771号