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:待了解