Map.keys()和Map.values()返回迭代器而非数组,需用[...map.keys()]或Array.from()转数组才能调用map、forEach等方法;遍历顺序严格等于插入顺序;for...of可直接遍历迭代器,性能更优。

Map.keys() 和 Map.values() 返回的是迭代器,不是数组
直接对 Map.keys() 或 Map.values() 调用 .map()、.forEach() 会报错,因为它们返回的是 MapIterator,不是 Array。常见错误现象是:TypeError: map is not a function 或 undefined is not a function。
必须显式转成数组才能用数组方法:
- 用
[...map.keys()]展开为数组(推荐,简洁) - 用
Array.from(map.keys())(兼容旧环境,但稍冗长) - 避免
map.keys().toArray()—— 这个方法根本不存在
提取键或值时,顺序始终与插入顺序一致
Map 保证遍历顺序 = 插入顺序,所以 map.keys() 和 map.values() 的迭代结果严格对应。这点和普通对象的 Object.keys() 不同(后者在 ES2015 前无序,现在虽多数有序但不保证)。
使用场景举例:需要按添加顺序还原配置项名,或做「最近写入优先」的缓存清理 —— 直接用 [...map.keys()].pop() 就能拿到最后插入的键。
- 插入顺序即遍历顺序,无需额外排序
- 删除某键后,后续键的遍历位置不会“前移”——
Map是链表结构,不是稀疏数组 - 如果依赖顺序做逻辑,别用
Object替代Map,否则在 Node.js 12 以下或某些 Safari 版本可能出错
values() 提取的是值的引用,不是拷贝
如果 Map 存的是对象、数组等引用类型,map.values() 返回的迭代器产生的每个值,都指向原对象的同一内存地址。修改其中一个,会影响 Map 内部存储的值。
示例:
const m = new Map();
m.set('a', { x: 1 });
const vals = [...m.values()];
vals[0].x = 99;
console.log(m.get('a').x); // 输出 99
- 想深拷贝值?得自己用
JSON.parse(JSON.stringify())或结构化克隆(structuredClone(),需环境支持) - 基本类型(
string、number、boolean)不受影响,赋值即复制 - 如果值是
Promise或function,无法被JSON.stringify序列化,注意 fallback 方案
在 for...of 循环里直接用 keys()/values() 最省事
不需要转数组也能遍历,且性能更好(避免创建中间数组)。这是最轻量、最常用的场景。
比如批量处理所有键:
for (const key of myMap.keys()) {
console.log(key);
}
-
for...of原生支持迭代器,keys()和values()就是为它设计的 - 比
[...myMap.keys()].forEach(...)少一次内存分配,大数据量时差异明显 - 不能用
for (let i = 0; i —— 迭代器没有 <code>length属性

















