# Map 基本用法

Javascript 的对象（Object），本质上是键值对的集合（Hash 结构），但是传统上只能用字符串当作健。

```javascript
const data = {}
const element = document.getElementById('myDiv')

data[element] = 'metadata'
data['[object HTMLDivElement]'] // metadata

```

从上面代码可以看出，由于对象只接受字符串作为键名，所以 `element` 被自动转为字符串 `[object HTMLDivElement]`&#x20;

为了解决这个问题，`ES6` 提供了 `Map` 数据结构。`Map` 结构提供“值 - 值“的对应，是一种更完善的 `Hash` 结构实现。如果我们需要“键值对“的数据结构，`Map` 比 `Object` 更合适

```javascript
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 作为参数

### 数组

```javascript
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` 接受数组作为参数的算法：

```javascript
const items = [
  ['name', '张三'],
  ['title', 'Author']
]

const map = new Map()

items.forEach(
  ([key, value]) => map.set(key, value)
}
```

### 其他

```javascript
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 结构才将其视为同一个键

```javascript
const map = new Map()

map.set(['a'], 555)
map.get(['a']) // undefined

```

上面代码的 set 和 get 方法，表面是针对同一个键。但实际上这是两个不同的数组实例，内存地址是不一样的，因此 `get` 方法无法读取该键，返回 `undefined`&#x20;

### 以简单类型的值为键

如果 Map 的键是一个简单类型的值（数字、字符串、布尔值），则只要两个值严格相等，Map 将其视为一个键。虽然`NaN`不严格相等于自身，但 Map 将其视为同一个键

```javascript
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

```
