JavaScript Map是什么?它如何存储键值对?

来源:网络编程作者:高宇头衔:草根站长
导读:本期聚焦于小伙伴创作的《JavaScript Map是什么?它如何存储键值对?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JavaScript Map是什么?它如何存储键值对?》有用,将其分享出去将是对创作者最好的鼓励。

JavaScript Map是ES6标准中新增的一种内置数据结构,它的核心作用就是存储键值对,和传统的Object对象功能类似,但在键的类型支持、迭代性能、键值对操作等方面有明显差异,更适合需要频繁增删键值对的场景。

JavaScript Map是什么?它如何存储键值对?

Map的基本概念

Map本质上是一个可迭代的键值对集合,它的键可以是任意类型的值,包括原始类型(如数字、字符串、布尔值)、对象、函数等,这一点和Object只能使用字符串或者Symbol作为键有很大区别。Map内部会维护键值对的插入顺序,迭代的时候会按照插入顺序依次返回键值对。

我们可以通过new Map()构造函数来创建一个Map实例,构造函数支持传入一个可迭代的键值对数组作为初始值,示例代码如下:

// 创建空Map
const emptyMap = new Map();

// 创建带初始值的Map,初始值是二维数组,每个子数组的第一个元素是键,第二个是值
const initMap = new Map([
  ['name', '张三'],
  [18, '年龄'],
  [{ id: 1 }, '对象作为键']
]);

console.log(initMap.size); // 输出3,size属性表示Map中键值对的数量

Map的核心操作方法

Map提供了一系列操作键值对的方法,常用的有以下几种:

  • set(key, value):向Map中添加新的键值对,如果键已经存在则更新对应的值,返回Map实例本身,支持链式调用。
  • get(key):根据键获取对应的值,如果键不存在则返回undefined。
  • has(key):判断Map中是否存在指定的键,返回布尔值。
  • delete(key):删除指定键对应的键值对,删除成功返回true,否则返回false。
  • clear():清空Map中所有的键值对,没有返回值。

下面是这些方法的简单使用示例:

const userMap = new Map();

// 添加键值对
userMap.set('name', '李四')
  .set('age', 20)
  .set('hobby', '篮球');

console.log(userMap.get('name')); // 输出李四
console.log(userMap.has('age')); // 输出true

userMap.delete('hobby');
console.log(userMap.has('hobby')); // 输出false

userMap.clear();
console.log(userMap.size); // 输出0

Map如何存储键值对

Map的存储机制并不是像Object那样依赖原型链和属性描述符,它的内部实现通常采用哈希表结合链表(或者红黑树)的结构,具体存储逻辑如下:

键的哈希处理

当向Map中添加一个键值对时,首先会对键进行哈希计算,生成一个对应的哈希值。对于不同类型的键,哈希计算的方式不同:

  • 对于原始类型的键,直接使用值本身的特征计算哈希,比如数字键的哈希就是数字本身,字符串键会根据字符串的内容计算哈希值。
  • 对于对象类型的键,Map会使用对象的内存地址作为哈希计算的依据,这也是为什么两个不同的空对象作为键时,会被认为是不同的键,示例:
const objMap = new Map();
const obj1 = {};
const obj2 = {};

objMap.set(obj1, '对象1');
objMap.set(obj2, '对象2');

console.log(objMap.get(obj1)); // 输出对象1
console.log(objMap.get(obj2)); // 输出对象2
console.log(objMap.get({})); // 输出undefined,新空对象和obj1、obj2内存地址不同

哈希冲突的处理

如果不同的键计算出了相同的哈希值,就会产生哈希冲突,Map内部会通过链表或者红黑树来保存这些哈希值相同的键值对,当查询的时候,先通过哈希值定位到对应的桶,再遍历桶内的键值对,通过严格相等(===)比较键是否匹配,匹配到就返回对应的值。

顺序维护

Map会额外维护一个插入顺序的链表,每次添加键值对的时候,会把新的键值对节点追加到链表末尾,迭代的时候按照这个链表的顺序依次返回,所以Map的迭代顺序是固定的插入顺序,这和Object的键遍历顺序(先数字键升序,再字符串键、Symbol键插入顺序)有明显区别。

Map和Object的对比

为了更清楚Map的适用场景,我们可以对比一下Map和Object的差异:

对比项MapObject
键的类型任意类型仅字符串、Symbol
键值对数量获取size属性直接获取需要手动计算Object.keys(obj).length
迭代性能原生支持迭代,频繁增删时性能更好需要转换才能迭代,频繁增删时可能有性能损耗
默认键没有默认键,不会和原型链属性冲突有原型链上的默认属性,可能存在键冲突

Map的迭代方式

Map是可迭代对象,支持多种迭代方式:

  • for...of循环:直接迭代Map,每次返回[key, value]形式的数组。
  • forEach方法:遍历所有键值对,回调函数参数依次是value、key、map本身。
  • keys()、values()、entries()方法:分别返回键的迭代器、值的迭代器、键值对的迭代器。

迭代示例代码如下:

const demoMap = new Map([
  ['a', 1],
  ['b', 2]
]);

// for...of迭代
for (const [key, value] of demoMap) {
  console.log(key, value); // 依次输出 a 1、b 2
}

// forEach迭代
demoMap.forEach((value, key) => {
  console.log(key, value); // 依次输出 a 1、b 2
});

// entries迭代
for (const item of demoMap.entries()) {
  console.log(item); // 依次输出 ['a', 1]、['b', 2]
}

使用注意事项

在使用Map的时候需要注意以下几点:

  • Map的键的比较使用的是严格相等(===),但是NaN是个例外,Map认为NaN等于NaN,所以可以用NaN作为键,并且同一个Map中只能有一个NaN键。
  • 如果需要把对象作为键,并且希望对象的属性变化不影响键的匹配,需要注意Map是根据对象的内存地址来判断键是否相同的,修改对象的属性不会改变内存地址,所以还是能匹配到对应的键值对。
const nanMap = new Map();
nanMap.set(NaN, 'not a number');
console.log(nanMap.get(NaN)); // 输出not a number,说明Map认为NaN等于NaN

const keyObj = { x: 1 };
const testMap = new Map();
testMap.set(keyObj, '初始值');
keyObj.x = 2; // 修改对象属性,内存地址不变
console.log(testMap.get(keyObj)); // 输出初始值,依然能匹配到

总的来说,当我们存储的键不是字符串或者Symbol,或者需要频繁增删键值对、需要固定的插入顺序迭代时,优先选择Map作为存储结构,能获得更好的代码可读性和性能表现。

JavaScriptMap键值对数据结构修改时间:2026-06-24 00:51:47

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。