Map集合类型见解

110 阅读2分钟

ES6以前,在JavaScript中实现“键值”式存储可以使用object来方便高效地完成,也就是使用对象属性作为健,再使用属性来引用值。但这种实现有点问题,所以TC39给键值存储定义了一个规范! map是一种新的集合类型,为这门语言带来了真正的键值存储机制。

const m1 = new Map() // 创建一个空映射

const m2 = new Map([
    ["key1", "value1"],
    ["key2", "value2"],
    ["key3", "value3"],
])

增删查改

const m = new Map()

// 增
m.set(key1, val1)
 .set(key2, val2) // set()会 return m 自身,所以可以链式调用
 
// 删
m.delete(key2) // 如果有该 key 则删除成功并返回 true,否则删除失败并 返回 false
m.clear() // 清除全部

// 查
m.has(key1) // true
m.get(key1) // val1
m.size // 1

// 改 无

注意:Map中的 key 与 val 中的映射是根据 引用 来实现绑定的,也就是说,引用一个临时的对象将不能再取到其映射:

m.set([], 'a Array')
m.get([]) // undefined

const oneObj = {}
m.set(oneObj, 'a Object')
m.get(oneObj) // string: a Object

Map和Object很像,但最大的不同便是:

  • Map实例会维护键值对,实行迭代会根据插入顺序进行迭代操作,而Object的迭代顺序不纯。如果需要迭代键值对,且需要维护顺序,那么Map最合适了

那么选择Map还是Object呢?总结红皮书的话就是:

  • 内存占用 给定固定大小的内存,Map大约可以比Object多存储50%的键/值。不过在平常开发中可以忽略此对性能产生的影响
  • 插入性能 Map插入操作稍微比Object快一些,涉及到大量的插入操作的话,更适合用Map
  • 查找速度 大型Object和Map中查找键/值的性能差异极小,只包含少量键/值对时,Object速度更快。如果把Object当成数组使用(比如使用连续整数作为属性),浏览器引擎可以进行优化(为其分配连续空间?),涉及大量查找操作时,选择Object更好。
  • 删除性能 Map的delete()操作比插入和查找更快,如果代码涉及大量删除操作,选择Map更佳。

使用delete删除Object属性的性能一直饱受诟病,为此,选择将属性值设置为undefined或null让浏览器进行垃圾回收的效果甚至更好

生产中有什么值得用到Map的地方?

TODO: 暂时还没想到(从上面分析来看用到delete操作多的地方很可能需要)

Map的好兄弟 WeakMap

TODO:待了解