map集合的理解

Map 是一个含有数据的键的集合,跟普通的 Object一样。但是它们最大的差别是Map允许键是任何类型。
关于Map的方法和属性如下:

new Map() 创建一个空集合
map.set(key, value) 存储含有值的键
map.get(key) 根据键来返回值,如果 key 不在 map 里将会返回 undefined
map.has(key) 如果key存在则返回 true,否则返回 false
map.delete(key) 根据键来删除值
map.clear 清空集合
map.size 返回当前全部元素的数量
举个例子:

let map = new Map();
map.set('1', 'str1');
map.set(1, 'num1');
map.set(true, 'bool1');

//Map 会保持类型,而不会像Object将键转化为字符串
alert( map.get(1) );   // 'num1'
alert( map.get('1') );  // 'str1'

Map 还可以使用对象作为键
示例:

let john = { name: 'John' };

//创建一个集合可以存储每个游客的来访次数
let visitsCountMap = new Map();

// john 的来访次数是123 
visitsCountMap.set(john, 123);

//读取 john 的来访次数
alert( visitsCountMap.get(john) ); // 123

使用对象作为键是 Map 最出名也是最重要的特点。

Map 是怎么比较键的?
为了测试键的一致性,Map 使用 SameValueZero 算法。它大致上使用严格相等 ===,但不同的是 NaN 被看成是等于 NaN。所以 NaN 也可以被用作键。(这个算法不能被改变或者自定义)

链式调用
每一次调用 map.set 都会返回集合本身,所以我们可以使用:

map.set('1', 'str1').set(1, 'num1').set(true, 'bool1');

Map 迭代

如果要在 map 里使用循环,可以使用以下三个方法:

map.keys() 返回所有键的迭代器
map.values() 返回所有值的迭代器
map.entries() 返回包含所有键值对的迭代器,在 for…of 循环中默认被使用
示例:

let recipeMap = new Map([
 ['cucumber', 500], 
 ['tomatoes', 350], 
 ['onion', 50]
])//迭代键
for (let vegetable of recipeMap.keys()) {
    alert(vegetable); // cucumber, tomatoes, onion
}

//迭代值
for (let amount of recipeMap.values()) {
    alert(amount); // 500, 350, 50
}

//迭代键值对
for (let entry of recipeMap) { // 效果跟 recipeMap.entries() 相同
  alert(entry);  // 依次是 cucumber,500 tomatoes,350  onion,50
}

按顺序插入
迭代的顺序与插入键的顺序相同。Map 会保持相同的顺序,不像普通 Object 不保证顺序。
除此之外,Map 有个内建 forEach 方法,跟 Array 一样:

//对每个 (key, value) 对运行 forEach 函数
recipeMap.forEach( (value, key, map) => {
   alert(`${key}: ${value}`); // cucumber: 500
})

Object.entries: 把对象转化为 map
当 Map 被创建之后,我们可以传入带有键值对的数组(或其它可迭代的对象)来进行初始化,像这样:

//包含 [key, value] 对的数组
let map = new Map([
  ['1', 'str1'],
  [1, 'num1'],
  [true, 'bool1']
]);
alert( map.get('1') ); 

如果我们有个纯对象,并且想利用这个纯对象来创建 Map,可以使用内建方法 Object.entries(obj),它返回一个具有相同格式的并且带有键值对的数组对象。
示例:

let obj = {
  name: 'John',
  age: 30
};
let map = new Map(Object.entries(obj));
alert( map.get('name') );  // John

这里,Object.entries 返回一个含有键值对的数组:[ [‘name’,‘John’], [‘age’, 30] ]。这就是 Map 所需要的参数格式。

Object.fromEntries: 把 map 转化为对象
我们刚刚已经利用 Object.entries(obj) 把一个纯对象转化成 Map
Object.fromEntries 方法的作用是相反的:给定一个具有 [key, value] 对的数组,它会根据给定数组转化为 Object:

let prices = Object.fromEntries([
  ['banana', 1],
  ['orange', 2],
  ['meat', 3]
]);

alert(prices.orange); // 2

我们可以使用 Object.fromEntries 从 Map 中得到一个纯对象。
例如:我们存了数据在 Map 中,但是我们需要把它转给需要纯对象的第三方代码。
示例:

let map = new Map();
map.set('banana', 1);
map.set('orange', 2);
map.set('meat', 3);

let obj = Object.fromEntries(map.entries()); 

alert(obj.orange); // 2

调用 map.entries() 将返回含有键值对的数组,这刚好是 Object.fromEntries 所需要的格式。
当然,使用下面的方式也是可以的:

let  obj = Object.fromEntries(map);

上面的代码作用是一样的,因为 Object.fromEntries 需要一个可迭代对象作为参数,map 的标准迭代会返回跟 map.entries() 一样的键值对。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值