什么是map数据结构?
- 在js中,传统的Object中,hash的键值对,键只能为字符串,现在为了解决一些特殊的需求,在es6中加入了map数据结构,他可以接受各种类型的值作为hash的键
简单的用法
const a = new Map()
const b = ['a']
a.set(b,111) // 设置一个键
a.get(b) //111 获取值
a.has(b) //true 查询是否含有
a.delete(b) //true 删除
a.has(b) //true
- Map的用法当然不会这有一些简单的,它可以直接接受一个数组为参数,事实上,不局限于数组,任何可遍历的对象甚至只要具有Interator接口的数据结构都是可以当作map的参数,当然需要每个成员需要是双元素的,因为我们是要生成一个个的键值对
const map = new Map([
['a', '兔子'],
['b', '小狗']
])
map.get('a') //兔子
map.get('b') //小狗
- 上面代码的结果和我们预期的结果是一样的,不难想出他的运行结果基本如下
const items = [
['a', '兔子'],
['b', '小狗']
]
const map = new Map()
items.map(([key, value]) =>{
map.set(key, value)
})
- 当然如你预期的一样,如果你去获取一个位置的键,你将得到的会是undefined
a.get('asdf') //undefined
- 需要注意的是,只有对同一个对象的引用,map才会视为同一个键
const map = new Map()
map.set(['a'], 111)
map.get(['a']) // undefined
为什么会这样? 是因为['a'] 这个对象是在存放在堆内存中,两个['a']的内存地址是不同的,这样第二次get的时候和第一次设置的时候不是同一个地址,获取的时候就会为undefined
如果你觉得上面的有些不是太懂的话,我们接着看下面来帮助你理解为什么两个['a']地址不相同
const map = new Map()
const a1 = ['a']
const a2 = ['a']
map.set(a1,111)
.set(a2,222)
map.get(a1) //111
map.get(a2) //222
- 这样的话是不是容易理解了一些,a1和a2虽然值相同,但是指向的内存地址并不相同,和我们预期的一样,如下:
a1 === a2 //false
由上面就可以看出,map在设计的时候键是与内存地址绑定的,是不是同一个键是看内存地址是否相同,这样做到好处,是我们在扩展别人的库或者方法的时候不用担心用了已经存在的属性而冲突
内存地址
- 先看下面
['a'] === ['a'] //false
const a1 = ['a']
const a2 = ['a']
a1 === a2 //false
上面两种写法的是相同的,只是第二种把两个不同的内存地址赋值给了两个变量
-
当然如果你想彻底搞懂内存地址到底是怎么会是的话,你就需要了解栈内存和堆内存,我们先简单的理解成,栈只存放简单的数据类型,如果需要存放对象的话,就把对象放进堆内存中,留了一个地址(门牌号)放进栈中,看下图帮助你简单快速的理解
通过上图我们不难看出内存地址具体是怎么不同的。一些关于map数据结构更详细的文档,还请大家去看阮老师的es6文档。