这是我参与「第四届青训营 」笔记创作活动的的第6天
Map
Map是es6新增的键/值存储机制的集合类型。
创建空映射
const map=new Map();
方法
初始化Map实例,可以传入的数据是可迭代对象(原生可迭代对象以及自定义可迭代对象)。
- 使用set()方法再添加键/值对。
- 使用get()和has()进行查询。
- 通过size属性获取映射中的键/值对的数量。
- 使用delete()和clear()删除值。
const m = new Map();
//插入一个键值对
m.set(key,value)
//set方法返回集合映射实例,可以使用链式写法
m.set(key,value).set(key2,value2)
//根据key值查询得到value值
const value1=m.has(key)
const value2=m.get(key)
//集合中键值对的个数
alert(m.size)
//删除一个键值对
m.delete(key)
//清空集合
m.clear()
可迭代
与Object只能使用数值、字符串或符号作为键不同,Map可以使用任何JavaScript数据类型作为键。
Map实例会维护键值对的插入顺序,可以根据插入顺序执行迭代操作。
映射实例提供一个迭代器,可以通过entries或者Symbol.iterator属性引用entries())取得这个迭代器。
const map = new Map();
map.set(key,value).set(key2,value2)
for(let m in map.entries){
alert(m)
}
for(let m in map[System.iterator]){
alert(m)
}
//因为entries是默认迭代器,可以通过扩展运算符,将集合映射实例转为键值对数组
let arr=[...map]
//keys方法和values方法分别返回对应的键、值组成的迭代器
for(let m in m.keys()){alert(m)}
for(let m in m.values()){alert(m)}
使用回调方式,则可以调用映射的forEach(callback, opt_thisArg)方法并传入回调,依次迭代每个键/值对。forEach传入的第一个参数,为回调函数,第二个参数重写回调内部的this的值。
const map = new Map();
map.set(key,value).set(key2,value2)
map.forEach((key,value)=>{
alert(`${key}-${value}`)
})
。
怎么确定使用Object还是Map?
内存占用
不同浏览器对于Object和Map的工程级实现不同,存储单个键/值对所占用的内存数量都会随键的数量线性增加。一般对于给定大小内存,Map可以比Object多存储50%左右。
查找速度
在把Object当成数组使用的情况下(比如使用连续整数作为属性key),浏览器引擎可以进行优化,在内存中使用更高效的布局。这对Map来说是不可能的。
插入性能
如果涉及大量插入操作,Map性能更好一点。
删除性能
删除对象,我们一直采用一种折中的方式,将对象设置为null或者undefined。Map中的delete操作更快,如果涉及大量删除,使用Map。
WeakMap
WeakMap是Map的“兄弟”类型,其API也是Map的子集。
弱映射的弱主要指垃圾回收程序对于该种映射中键值的处理方式。
WeakMap实例之所以限制只能用对象作为键。
弱映射中的键只能是Object或者继承自Object的类型,尝试使用非对象设置键会抛出TypeError。
之所以键只能是对象,是为了保证只有通过对键对象的引用才能取得值。“弱”表示弱类型中的键不属于正式的引用,不会阻止垃圾回收。只要键存在,对键的引用就存在,键值对就存在,就不会被当做垃圾回收。
如果允许原始值,那就没办法区分初始化时使用的字符串字面量和初始化之后使用的一个相等的字符串了,没有办法通过创建对于键对象的引用取到值。
const wm = new WeakMap();
const container = {
key: {}
};
//因为container对象维持着对于弱映射键引用,键值对就存在,就不会被垃圾回收。
wm.set(container.key, "val");
function removeReference() {
//对于弱映射键的引用消失,键值对被破坏,弱映射实例也被垃圾回收。
container.key = null;
}
具有的方法:
- 使用set()再添加键/值对;
- 使用get()和has()查询;
- 使用delete()删除:
弱映射不可迭代键。因为弱映射中的键随时可能被销毁。没有迭代键值对或者清空集合的方法。
应用场景:
因为WeakMap实例不会妨碍垃圾回收,所以非常适合保存关联元数据。
const weakMap=new WeakMap()
const btn=document.querySelector('#btn')
//当btn节点被从DOM树中删除,且weakMap实例对象没有被其他地方引用,那么就会被垃圾回收程序回收。
weakMap.set(btn,{disabled:true})