这是我参与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
- 字符串
- 类数组,比如
NodeList,arguments
实例的属性
size
通过size可以知道Map现在有多少项。
var map = new Map([
['a', 1],
['b', 2],
['c', 3]
])
console.log(map.size) // 3
实例的方法
- set(key, value) 属性键值对
- get(key) 获取某个键对应的值
- has(key) 判断map是否有某个键
- delete(key) 删除map的键
- 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键值对