学学es6新增的Map的用法

879 阅读3分钟

这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

问题

面试官:你刚刚讲了set的用法(链接在此),很不错,那你能讲讲Map的用法吗?

面试者: map主要是用来遍历数组,不改变原数组,返回一个新数组。

面试官:不是数组的map方法,而是es新增的Map数据结构。

面试者:。。。。

以上纯属虚构,应该也不会有雷同的吧。

咱们今天来学学学学es6新增的Map的用法。

Map

在js中,一切皆为对象,大部分类型都可以有对象生成。但是对象有个不好的问题,就是它只能用字符串做key,如果你让对象做key,也会转成字符串来做key。

var obj = {}
var key = {key: 'a'}
obj[key] = 'value'
console.log(obj) // {[object Object]: 'value'}

可以看到key变成了[object Object],本质上是调用了对象的toString方法转成了[object Object]

所以为了能够识别出以对象命名的key,es6新增了Map数据结构。 事实上,Map除了可以以对象来命名key,其它基本类型也是可以。

// 第一种方式:
var key = {key: 'a'}
var map = new Map([
  [key, 'value'],
  ['a', 1]
])
console.log(map) // Map(1) {{…} => 'value', 'a' => 1}

// 第二种方式:
var key = {key: 'a'}
var map = new Map()
map.set(key, 'value') 
map.get(key) // value
map.set('a', 1) 
map.get('a') // 1
console.log(map) // Map(1) {{…} => 'value', 'a' => 1}

可以看到打印的是key是对象。

Map也是个构造函数,接受具有Iterator接口的参数,否则会报错。 通过数组传参,数组的每一项是代表键值对的数组。

以下数据具有Iterator接口

  • 数组
  • Map
  • Set
  • 字符串
  • 类数组,比如NodeListarguments

实例的属性

size

通过size可以知道Map现在有多少项。

var map = new Map([
 ['a', 1],
 ['b', 2],
 ['c', 3]
])
console.log(map.size) // 3

实例的方法

  1. set(key, value) 属性键值对
  2. get(key) 获取某个键对应的值
  3. has(key) 判断map是否有某个键
  4. delete(key) 删除map的键
  5. clear(key) 清空map
var map = new Map()
map.set('a', 1)
map.set('b', 2)
console.log(map.get('a')) // 1
console.log(map.has('a')) // true
map.delete('a')
console.log(map) // Map(1) {'b' => 2}
map.clear()
console.log(map) //Map(0) {size: 0}

还有keys(), values(), entries(),forEach()遍历方法。另外map也是有Iterator的接口的,也是可以进行for-of遍历,可以使用扩展运算符。

var map = new Map([
 ['a',1],
 ['b',2]
])
for(let item of map) {console.log(item)} // ['a', 1] ['b', 2]
for(let [key, value] of map) {console.log(key,value)} // a 1   b 2

for(let key of map.keys()) {console.log(key)} // a  b
for(let value of map.values()) {console.log(value)} // 1  2

// 等同于直接遍历map
for(let [key, value] of map.entries()) {console.log(key,value)} // ['a', 1] ['b', 2]

map.forEach((value, key) => {console.log(value, key)}) // 1 'a'    2 'b'

// 扩展运算符
console.log([...map]) // [ ['a',1], ['b',2] ]

WeakMap

WeakMap的用法跟Map类型,可以使用对象当作key。 但是WeakMap限制key只能是对象(不包含null),不能是其他类型。

new WeakMap([
 ['a',1],
 ['b',2]
])  // error: Invalid value used as weak map key

new WeakMap([
 [{key: 'a'},1],
 [{key: 'b'},2]
])  // success

还有一个地方不同,它的键是弱引用,一旦键不存在,在合适的时机该项键值对会自动被垃圾回收。

var obj = {}
var map = new Map([
 [obj,1]
])  

var weakmap = new WeakMap([
 [obj,1]
])  

obj = undefined
console.log(map) // Map(1) {{…} => 1}
console.log(weakmap) // WeakMap {}  合适的时机会被回收

它没有size属性,没有遍历的方法,只有get,set,delete,has方法。

var weakmap = new WeakMap() 
var obj = {}
weakmap.set(obj, 1) // 1
weakmap.get(obj) // 1
weakmap.has(obj) // true
weakmap.delete(obj) // 删除obj键值对

参考

Set 和 Map 数据结构