Javascript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作健。
const data = {}
const element = document.getElementById('myDiv')
data[element] = 'metadata'
data['[object HTMLDivElement]'] // metadata
从上面代码可以看出,由于对象只接受字符串作为键名,所以 element
被自动转为字符串 [object HTMLDivElement]
为了解决这个问题,ES6
提供了 Map
数据结构。Map
结构提供“值 - 值“的对应,是一种更完善的 Hash
结构实现。如果我们需要“键值对“的数据结构,Map
比 Object
更合适
const m = new Map()
const o = {p: 'Hello World'}
m.set(o, 'content')
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false
接受 Iterator 作为参数
数组
const map = new Map([
['name', '张三'],
['title', 'Author']
])
map.size //2
map.has('name') // true
map.get('name') // 张三
map.has('title') // true
map.get('title') // Author
Map
接受数组作为参数的算法:
const items = [
['name', '张三'],
['title', 'Author']
]
const map = new Map()
items.forEach(
([key, value]) => map.set(key, value)
}
其他
const set = new Set([
['foo', 1],
['bar', 2]
]
const m1 = new Map(set)
m1.get('foo') // 1
const m2 = new Map([['baz', 3]])
const m3 = new Map(m2)
m3.get('baz') // 3
键的设置
以对象为键
只有对同一个对象的引用,Map 结构才将其视为同一个键
const map = new Map()
map.set(['a'], 555)
map.get(['a']) // undefined
上面代码的 set 和 get 方法,表面是针对同一个键。但实际上这是两个不同的数组实例,内存地址是不一样的,因此 get
方法无法读取该键,返回 undefined
以简单类型的值为键
如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键。虽然NaN
不严格相等于自身,但 Map 将其视为同一个键
let map = new Map()
map.set(-0, 123)
map.get(+0) // 123
map.set(true, 1)
map.set('true', 2)
map.get(true) // 1
map.set(undefined, 3)
map.set(null, 4)
map.get(undefined) // 3
map.set(NaN, 123)
map.get(NaN) // 123