Map/WeakMap
Map
Map是一组键值对的结构,用于解决以往不能用对象做为键的问题
- 具有极快的查找速度
- 函数、对象、基本类型都可以作为键或值
声明定义
可以接受一个数组作为参数,该数组的成员是一个表示键值对的数组。
const m = new Map([
['mkimq', '在线文档'],
['mkimq.com', '网站']
])
console.log(m.get('mkimq'))
使用set 方法添加元素,支持链式操作
const map = new Map()
map.set('mkimq', '在线文档').set('age', 18)
console.log(map.entries())
对于键是对象的Map, 键保存的是内存地址,值相同但内存地址不同的视为两个键。
获取数量
获取数据数量
console.log(map.size)
元素检测
检测元素是否存在
console.log(map.has('mkimq'))
读取元素
map.get('mkimq')
删除元素
使用 delete() 方法删除单个元素
map.delete('mkimq')
使用clear方法清除Map所有元素
map.clear()
遍历数据
使用 keys()/values()/entries() 都可以返回可遍历的迭代对象。
const map = new Map([['mkimq', '在线文档'], ['age', 18]])
console.log(map.keys())
console.log(map.values())
console.log(map.entries())
可以使用keys/values 函数遍历键与值
for (const key of map.keys()){
console.log(key)
}
for (const value of map.values()){
console.log(value)
}
使用for/of遍历操作,直播遍历Map 等同于使用entries() 函数
for (const [key, value] of map) {
console.log(`${key}=>${value}`)
}
使用forEach遍历操作
map.forEach((value, key) => {
console.log(`${key}=>${value}`)
})
数组转换
可以使用展开语法 或 Array.form 静态方法将Set类型转为数组,这样就可以使用数组处理函数了
console.log(...map)
console.log(...map.entries())
console.log(...map.values())
console.log(...map.keys())
节点集合
map的key可以为任意类型,下面使用DOM节点做为键来记录数据。
<body>
<div desc="在线文档">mkimq</div>
<div desc="站点">mkimq.com</div>
</body>
<script>
const divMap = new Map()
const divs = document.querySelectorAll('div')
divs.forEach(div => {
divMap.set(div, {
content: div.getAttribute('desc')
})
});
divMap.forEach((config, elem) => {
elem.addEventListener('click', function() {
alert(divMap.get(this).content)
})
})
</script>
WeakMap
WeakMap 对象是一组键/值对的集
- 键名必须是对象
- WeaMap对键名是弱引用的,键值是正常引用
- 垃圾回收不考虑WeaMap的键名,不会改变引用计数器,键在其他地方不被引用时即删除
- 因为WeakMap 是弱引用,由于其他地方操作成员可能会不存在,所以不可以进行forEach()遍历等操作
- 也是因为弱引用,WeaMap 结构没有keys(),values(),entries()等方法和 size 属性
- 当键的外部引用删除时,希望自动删除数据时使用 WeakMap
声明定义
以下操作由于键不是对象类型将产生错误
错误示范
new WeakMap('mkimq')
将DOM节点保存到WeakMap
const map = new WeakMap()
document
.querySelectorAll('div')
.forEach(item => map.set(item, item.innerHTML))
基本操作
下面是WeakMap的常用指令
const mk = new WeakMap()
const arr = ['mkimq']
// 添加
mk.set(arr, 'mkimq')
// 删除
mk.delete(arr)
// 检索判断
mk.has(arr)
垃圾回收
WakeMap的键名对象不会增加引用计数器,如果一个对象不被引用了会自动删除。
- 下例当hd删除时内存即清除,因为WeakMap是弱引用不会产生引用计数
- 当垃圾回收时因为对象被删除,这时WakeMap也就没有记录了
const mk = new WeakMap()
let arr = {}
mk.set(arr, 'mkimq')
console.log(mk.has(arr))
arr = null
console.log(mk)