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

  1. 当存储简单数字类型,并且key都是string或者symbol的时候,优先使用Object,字面量形式创建的Object更加高效
  2. 当需要联合this实现一些逻辑的时候,需要使用Object,Object中的非箭头函数函数指向调用者即Object本身,这点map做不到
  3. 与后端接口交互时,需要使用Object,JSON不支持map格式

6.2 何时使用map

  1. 必须保证键的输出顺序与插入顺序一致时,优先使用map,因为Object在键全部是字符串或symbol时候的迭代顺序,在有数字或者汉字的情况下key会乱序
  2. 数据量大、增删频繁的时候优先使用map,map对增删频繁的场景做了优化
  3. 需要直接获取size
posted @ 2022-06-21 16:07  IslandZzzz  阅读(336)  评论(1编辑  收藏  举报