- 存储带键的数据(keyed)集合的对象。
- 存储有序集合的数组。
Map是一个带键的数据项的集合,就像一个 Object 一样。 但是它们最大的差别是 Map 允许任何类型的键(key)。
Map它的方法和属性如下:
new Map()—— 创建 map。map.set(key, value)—— 根据键存储值。map.get(key)—— 根据键来返回值,如果map中不存在对应的key,则返回undefined。map.has(key)—— 如果key存在则返回true,否则返回false。map.delete(key)—— 删除指定键的值。map.clear()—— 清空 map。map.size—— 返回当前元素个数。
举个例子:
<!DOCTYPE html>
<script>
"use strict";
let map = new Map();
map.set('1', 'str1'); // 字符串键
map.set(1, 'num1'); // 数字键
map.set(true, 'bool1'); // 布尔值键
// 还记得普通的 Object 吗? 它会将键转化为字符串
// Map 则会保留键的类型,所以下面这两个结果不同:
alert( map.get(1) ); // 'num1'
alert( map.get('1') ); // 'str1'
alert( map.size ); // 3
</script>
Map 还可以使用对象作为键。
<!DOCTYPE html>
<script>
"use strict";
let john = { name: "John" };
// 存储每个用户的来访次数
let visitsCountMap = new Map();
// john 是 Map 中的键
visitsCountMap.set(john, 123);
alert( visitsCountMap.get(john) ); // 123
</script>
Map 使用 sameVlaueZero 算法来比较键是否相等。它和严格等于 === 差不多,但区别是 NaN 被看成是等于 NaN。所以 NaN 也可以被用作键。
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在默认情况下使用的就是这个。
<!DOCTYPE html>
<script>
"use strict";
let recipeMap = new Map([
['cucumber', 500],
['tomatoes', 350],
['onion', 50]
]);
// 遍历所有的键(vegetables)
for (let vegetable of recipeMap.keys()) {
alert(vegetable); // cucumber, tomatoes, onion
}
// 遍历所有的值(amounts)
for (let amount of recipeMap.values()) {
alert(amount); // 500, 350, 50
}
// 遍历所有的实体 [key, value]
for (let entry of recipeMap) { // 与 recipeMap.entries() 相同
alert(entry); // cucumber,500 (and so on)
}
</script>
Map 有内置的 forEach 方法,与 Array 类似
// 对每个键值对 (key, value) 运行 forEach 函数
recipeMap.forEach( (value, key, map) => {
alert(`${key}: ${value}`); // cucumber: 500 etc
});
Object.entries:从对象那个创建Map
<!DOCTYPE html>
<script>
"use strict";
// 键值对 [key, value] 数组
let map = new Map([
['1', 'str1'],
[1, 'num1'],
[true, 'bool1']
]);
alert( map.get('1') ); // str1
</script>
如果我们想从一个已有的普通对象(plain object)来创建一个 Map,那么我们可以使用内建方法 Object.entries(obj),该方法返回对象的键/值对数组,该数组格式完全按照 Map 所需的格式。
<!DOCTYPE html>
<script>
"use strict";
let obj = {
name: "John",
age: 30
};
let map = new Map(Object.entries(obj));
alert( map.get('name') ); // John
</script>
Object.entries返回键/值对数组:[ ["name","John"], ["age", 30] ]。这就是Map所需要的格式。
Object.fromEntries 方法的作用是相反的:给定一个具有 [key, value] 键值对的数组,它会根据给定数组创建一个对象
<!DOCTYPE html>
<script>
"use strict";
let prices = Object.fromEntries([
['banana', 1],
['orange', 2],
['meat', 4]
]);
// 现在 prices = { banana: 1, orange: 2, meat: 4 }
alert(prices.orange); // 2
</script>
可以使用 Object.fromEntries 从 Map 得到一个普通对象(plain object)
<!DOCTYPE html>
<script>
"use strict";
let map = new Map();
map.set('banana', 1);
map.set('orange', 2);
map.set('meat', 4);
let obj = Object.fromEntries(map.entries()); // 创建一个普通对象(plain object)(*)
// 完成了!
// obj = { banana: 1, orange: 2, meat: 4 }
alert(obj.orange); // 2
</script>
set
Set是一个特殊的类型集合 —— “值的集合”(没有键),它的每一个值只能出现一次。它的主要方法如下:
new Set(iterable)—— 创建一个set,如果提供了一个iterable对象(通常是数组),将会从数组里面复制值到set中。set.add(value)—— 添加一个值,返回 set 本身set.delete(value)—— 删除值,如果value在这个方法调用的时候存在则返回true,否则返回false。set.has(value)—— 如果value在 set 中,返回true,否则返回false。set.clear()—— 清空 set。set.size—— 返回元素个数。
它的主要特点是,重复使用同一个值调用 set.add(value) 并不会发生什么改变。这就是 Set 里面的每一个值只出现一次的原因。
Set迭代
使用 for..of 或 forEach 来遍历 Set:
<!DOCTYPE html>
<script>
"use strict";
let set = new Set(["oranges", "apples", "bananas"]);
for (let value of set) alert(value);
// 与 forEach 相同:
set.forEach((value, valueAgain, set) => {
alert(value);
});
</script>
forEach 的回调函数有三个参数,是为了与 Map 兼容。当然,这看起来确实有些奇怪。但是这对在特定情况下轻松地用 Set 代替 Map 很有帮助,反之亦然。
Map中用于迭代的方法在Set中也同样支持:
set.keys()—— 遍历并返回所有的值(returns an iterable object for values),set.values()—— 与set.keys()作用相同,这是为了兼容Map,set.entries()—— 遍历并返回所有的实体(returns an iterable object for entries)[value, value],它的存在也是为了兼容Map。
最后总结
Map—— 是一个带键的数据项的集合。方法和属性如下:
new Map([iterable])—— 创建 map,可选择带有[key,value]对的iterable(例如数组)来进行初始化。map.set(key, value)—— 根据键存储值。map.get(key)—— 根据键来返回值,如果map中不存在对应的key,则返回undefined。map.has(key)—— 如果key存在则返回true,否则返回false。map.delete(key)—— 删除指定键的值。map.clear()—— 清空 map 。map.size—— 返回当前元素个数。与普通对象
Object的不同点:
- 任何键、对象都可以作为键。
- 有其他的便捷方法,如
size属性。
Set—— 是一组唯一值的集合。方法和属性:
new Set([iterable])—— 创建 set,可选择带有iterable(例如数组)来进行初始化。set.add(value)—— 添加一个值(如果value存在则不做任何修改),返回 set 本身。set.delete(value)—— 删除值,如果value在这个方法调用的时候存在则返回true,否则返回false。set.has(value)—— 如果value在 set 中,返回true,否则返回false。set.clear()—— 清空 set。set.size—— 元素的个数。
在 Map 和 Set 中迭代总是按照值插入的顺序进行的,所以我们不能说这些集合是无序的,但是我们不能对元素进行重新排序,也不能直接按其编号来获取元素。
本文详细介绍了Map和Set两种数据结构,Map用于存储带键的数据集合,支持任意类型的键,提供了丰富的操作方法;Set则为无键值唯一集合,用于存储不重复的值,包括创建、添加、删除和迭代。
1628

被折叠的 条评论
为什么被折叠?



