JavaScript学习-Map
一、含义和基本用法
JavaScript 的对象(Object ) 本质上都是键值对的集合(Hash) ,但是它只能使用 字符串来作为键,这给它的使用带来了很大的限制。
const data = {} const element = document.getElementById('myDiv'); data[element] = 'metadate'; data['[Object HTMLDivElement]'] // 'metadate'
上面的代码原意是将获取的 DOM 元素作为键,但是由于 Object 只能接受字符串作为键,所以他会把 dom 元素转为一个字符串。
为了解决这种问题,ES6 提供了 Map 数据结构,它类似于对象,但是它的 ‘键’ 是不仅只限于字符串,各种类型的值都可以作为 ‘键’ ,包括对象也可以作为它的键 ,也就是说,Object 提供了一个 ’字符串-值‘的对应关系,而 Map 提供了一种 ’值-值‘的数据结构,
可以使用 new Map 来创建一个 Map 实例,可以传递一个表示键值对的数组作为参数,如下:
const map = new Map([ [ 'name': 'zhagnsan' ], ['title':'author'] ])
Map 构造函数接受数组作为参数,其实执行的是下面的算法:
const items = [ ['name', 'zhangsan'], ['titel', 'author'] ] const map = new Map() items.forEach(([key, value]) => map.set(key, value))
不只是只有数组才可以作为参数,只要是具有 Iterator 接口并且每一个成员都是一个双元素数据的数据结构都可以作为 map 构造函数的参数,也就是说,Set 和 map 都可以用来生成新的 map
注意:只有对同一对象的引用,Map 才会将它当作一个键
const map = new Map() map.set(['a'], 555) map.get(['a']) // undefined
上面虽然是看起来是同一个键,但是实际上却是两个值,因为内存地址是不一样的,同样,同样的两个值的两个实例在Map 结构中也会被视为两个键,如下:
const map = new Map() const k1 = ['a'] const k2 = ['a'] map.set(k1, 111).set(k2, 222) map.get(k1) // 111 map.get(k2) // 222
由上面可以知道,Map 的键实际上是和内存地址绑定的,只要内存地址不一样,就会被视为两个键,这就解决了同名属性碰撞的问题,当我们扩展别人的 库的时候,如果使用对象作为键名,不用担心自己的属性和原作者的属性同名。
如果Map 的键是一个基本类型的值,则只要两个值严格相等,Map 就会将其视为一个键,包括0 和-0,另外虽然NaN不严格等于本身,但是 Map 将其视为同一个键。
二、实例的属性和方法
具体可以查看:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map
三、与其他数据结构的相互转化
Map转为数组:Map转为数组最方便的方法就是使用扩展运算符(...)
const map = new Map().set(true, 7).set({ foo: '3' }, ['abc']) console.log([...map]) // [ [ true, 7 ], [ { foo: '3' }, [ 'abc' ] ] ]
数组转为Map:将数组传入Map 的构造函数作为参数就可以了
const map=new Map([[true,7],[{foo:3},['abc']]]) console.log(map) // { true => 7, { foo: 3 } => [ 'abc' ] }
Map转为对象:只要是map对象的健是字符串就可以将map转为对象了
function strMapToObj(strMap){ let obj=Object.create(null); for(let [k,v] of strMap){ obj[k]=v; } return obj; } const myMap=new Map().set('yes',true).set('no',false) const obj=strMapToObj(myMap) console.log(obj) // { yes: true, no: false }
Map转为JSON,有两种情况:
一种是map的健是字符串,可以将它转为对象JSON
function strMapToJson(strMap){ return JSON.stringify(strMapToJson(strMap)) } let myMap=new Map().set('yes',true).set('no',false); const json=setMapToJson(myMap) console.log(json)
一种是map的健不是字符串,可以将它转为数组JSON:
function mapToArrayJson(map){ return JSON.stringify([...map]) } let myMap=new Map().set(true,7).set({foo:3},['abc']) const json=mapToArrayJson(myMap) console.log(json) // [[true,7],[{"foo":3},["abc"]]]