现代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。

Keywords: JavaScript
previousPost nextPost
已经有 1000000 个小伙伴看完了这篇推文。