JavaScript 一文掌握Map以及Map与Object之间的区别
Map
Map是JavaScript的一种数据结构,主要用于有序保存键值对,任何值都可以作为一个键或者值。
Map实现了iterator接口,遵循可迭代协议
1 特点
- 有序插入/输出
- 任意值都可以作为键
2 key
- 键的比较基于sameValueZero算法
- 在作为键的时候,NaN与NaN是相等的
- -0和+0作为键是相等的
3 api
- size 返回Map内含多少个键值对
- get 通过key获取map中某个元素
- set 添加或更新map中的元素
- delete(key) 移除map中指定key的元素
- clear 移除Map中的所有元素
- entries 返回一个迭代器对象,包含map中所有键值对[key,value],可以用forof遍历,迭代顺序与Map对象的插入顺序相同
- keys 返回一个迭代器对象,包含map中按顺序插入的key值
- values 返回一个迭代器对象,包含map中按顺序插入的每个元素的value值
- forEach 按照顺序对map中的键值对执行回调,回调函数参数为value,key,map
4 map和Object的区别
4.1 键名冲突
map默认不包含key
Object默认有原型上的属性,可能会造成键名冲突
虽然可以用Object.create(null)来创建一个没有原型的对象,但是这种用法不太常见
4.2 键的顺序
map中的key是有序的,迭代的时候回按照顺序返回key值
ES6之后,对象保留了字符串和symbol类型key的创建顺序,但是在存在字符串key和数字key的情况下,会优先迭代数字key, 说明对象的key是无序的(参考mdn)
4.3 键的类型
map的键可以是任意类型
Object的键只能是字符串(数字)或者symbol
4.4 键的个数
map提供了size用来计算元素个数
Object只能手动计算键的个数
4.5 迭代
map实现了iterator接口,因此是可迭代的,能够用forof遍历
Object没有实现iterator接口,不可直接迭代,只能以某种形式获取键之后才能迭代
4.6 性能
在频繁增删的场景下表现更好
在频繁添加和删除键值对的场景下未作出优化
4.7 其他
JSON支持Object,不支持map
5 map与数组/对象之间的相互转换
5.1 map与数组之间的转换
map转数组
// 获取键数组
const kArr = Array.from(map.keys())
console.log(kArr) // [ 'key', 'key1' ]
// 获取值数组
const vArr = Array.from(map.values())
console.log(vArr) // [ 'value', 'value1' ]
// 获取键值对数组,或者也可以使用[...map]
const kvArr = Array.from(map.entries())
console.log(kvArr) // [ [ 'key', 'value' ], [ 'key1', 'value1' ] ]
数组转map
// 数组转map,必须是二维数组
const arrToMap = new Map([['key','value'],['key1','value1']])
console.log(arrToMap) // Map(2) { 'key' => 'value', 'key1' => 'value1' }
5.2 map与对象之间的转换
map转对象
// 1 使用forof
const obj = {}
for (const [key,v] of map) {
obj[key] = v
}
console.log(obj) //{ key: 'value', key1: 'value1' }
// 2 使用forEach
map.forEach((v,k,map)=>{
obj[k] = v
})
console.log(obj) //{ key: 'value', key1: 'value1' }
对象转map
使用Object.keys或者forin
forin需要结合hasOwnProperty使用来避开原型上的属性
// 对象转map
const obj = { key: 'value', key1: 'value1' }
const objToMap = new Map()
Object.keys(obj).forEach((key) => objToMap.set(key, obj[key]))
console.log(objToMap) // Map(2) { 'key' => 'value', 'key1' => 'value1' }
for (const key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
objToMap.set(key, obj[key])
}
}
console.log(objToMap) // Map(2) { 'key' => 'value', 'key1' => 'value1' }
6 map与Object的使用场景?
6.1 何时使用Object
- 当存储简单数字类型,并且key都是string或者symbol的时候,优先使用Object,字面量形式创建的Object更加高效
- 当需要联合this实现一些逻辑的时候,需要使用Object,Object中的非箭头函数函数指向调用者即Object本身,这点map做不到
- 与后端接口交互时,需要使用Object,JSON不支持map格式
6.2 何时使用map
- 必须保证键的输出顺序与插入顺序一致时,优先使用map,因为Object在键全部是字符串或symbol时候的迭代顺序,在有数字或者汉字的情况下key会乱序
- 数据量大、增删频繁的时候优先使用map,map对增删频繁的场景做了优化
- 需要直接获取size
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)