现代JS学习笔记:Map映射
Posted by Mars . Modified at
学习内容:《现代JavaScript教程》
Map:映射
什么是Map
Map是一种带键的数据项的集合,是一种特殊的Object。
Map的特点
Map与普通对象Object数据结构的最大不同是:
Map允许键名是任何类型(包含null,undefined和NaN),而Object只有字符串类型的键名(即使传入其他类型也会自动转换为String类型)。
Map的方法和属性
- new Map() —— 创建 map。
- map.set(key, value) —— 根据键存储值。(返回Map本身,可以链式调用)
- map.get(key) —— 根据键来返回值,如果 map 中不存在对应的 key,则返回 undefined。
- map.has(key) —— 如果 key 存在则返回 true,否则返回 false。
- map.delete(key) —— 删除指定键的值。
- map.clear() —— 清空 map。
- map.size —— 返回当前元素个数。
Map的遍历
实现Map数据结构的遍历,有三种方法:
- map.keys() —— 遍历并返回所有的键(returns an iterable for keys),
- map.values() —— 遍历并返回所有的值(returns an iterable for values),
- map.entries() —— 遍历并返回所有的实体(returns an iterable for entries)[key, value],for..of 在默认情况下使用的就是这个。
在 Map 和 Set 中迭代总是按照值插入的顺序进行的,所以我们不能说这些集合是无序的,但是我们不能对元素进行重新排序,也不能直接按其编号来获取元素。
Map与Object的互相转换
从普通Object生成Map
使用Object.entries()。
这个函数可以把普通对象转换为键值对数组组成的数组。
然后使用这个数组传入new Map()即可生成对应Map。
let mapObj = {
good: 'boy',
say(){
console.log(this.good);
}
};
let map1 = new Map(Object.entries(mapObj));
console.log(map1.get('good')); //’boy’
从Map生成普通Object
Map()构造函数可以接受一个由键值对组成的数组[key, value]为元素,构成的数组作为参数,使用每一个元素的键值对自动生成Map。
let a = new Map( [[key1, value1],[key2, value2]] );
// 自动生成Map: key1对应value1,key2对应value2.
Map.entries()可以返回一个可迭代的键/值对,可供Object.fromEntries()使用生成对应普通Object。
所以使用Object.fromEntries(map.entries())就可以把Map转为Object。
还可以省略,直接传入Map。Object.fromEntries(map)
WeakMap 弱映射
WeakMap弱映射,它有两个特殊性:
- 只能接受对象作为键名,其他类型无效;
- 键名引用的对象,外部全部失去引用后,即使在Map内存在,也会被垃圾回收机制识别并回收。
常规的Map有一个垃圾回收机制的问题。
当Map的键是一个对象时,即使对象在外部被设置为null,Map也依然在引用着该对象,依然存储在内存中,不会被当做垃圾清除。
WeakMap可以解决这个问题。当一个对象仅仅是作为 WeakMap 的键而存在 —— 它将会被从 map和内存中自动删除。
// 创建方式:
let a = new WeakMap();
WeakMap的方法
WeakMap 不支持迭代以及 keys(),values() 和 entries() 方法。所以没有办法获取 WeakMap 的所有键或值。
WeakMap 只有以下的方法:
- weakMap.get(key)
- weakMap.set(key, value)
- weakMap.delete(key)
- weakMap.has(key)
因为不能确定浏览器的垃圾回收时机(即使外部对象被解除引用,weakmap里面的元素也可能不会瞬间立即被删除,而是要等待垃圾回收的时机。),所以WeakMap里面的元素数量是不能确定的,因此没设有keys这一类方法。
WeakMap应用场景
计算结果缓存
缓存函数计算结果,如果入参obj是引用类型,使用WeakMap
可以在入参obj被销毁的时候,同步自动消除缓存的结果数据,不需手动消除。
let cache = new WeakMap();
function A(obj) {
if (cache.has(obj)) return cache.get(obj);
// ... some calculate...
cache.set(obj, res);
return res;
}
obj = null;
// obj in cache is destoryed automatically. (no more need)
储存外部引入的数据
从外部引入的数据,想要临时保存在本地,但是又希望不因为本地的引用而影响外部变量本身的垃圾回收(与外部变量共存亡),可以使用WeakMap。