Map

Map 是一个带键的数据项的集合,就像一个 Object 一样。 但是它们最大的差别是 Map 允许任何类型的键(key)。
它的方法和属性如下:

  • 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 —— 返回当前元素个数。
  1. let map = new Map();
  2. map.set('1', 'str1'); // 字符串键
  3. map.set(1, 'num1'); // 数字键
  4. map.set(true, 'bool1'); // 布尔值键
  5. // 还记得普通的 Object 吗? 它会将键转化为字符串
  6. // Map 则会保留键的类型,键不会被转换成字符串,所以下面这两个结果不同:
  7. alert( map.get(1) ); // 'num1'
  8. alert( map.get('1') ); // 'str1'
  9. alert( map.size ); // 3

链式调用
每一次 map.set 调用都会返回 map 本身,所以我们可以进行“链式”调用:
map.set(‘1’,’str1’).set(1,’num1’).set(true,’bool1’);

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 在默认情况下使用的就是这个。 ```javascript 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) }

  1. Map 有内置的 forEach 方法,与 Array 类似:
  2. ```javascript
  3. // 对每个键值对 (key, value) 运行 forEach 函数
  4. recipeMap.forEach( (value, key, map) => {
  5. alert(`${key}: ${value}`); // cucumber: 500 etc
  6. });

Object.entries:从对象创建 Map

当创建一个 Map 后,我们可以传入一个带有键值对的数组(或其它可迭代对象)来进行初始化

  1. // 键值对 [key, value] 数组
  2. let map = new Map([
  3. ['1', 'str1'],
  4. [1, 'num1'],
  5. [true, 'bool1']
  6. ]);
  7. alert( map.get('1') ); // str1
  8. // 从一个已有的普通对象(plain object)来创建一个 Map
  9. let obj = {
  10. name: "John",
  11. age: 30
  12. };
  13. let map = new Map(Object.entries(obj));
  14. alert( map.get('name') ); // John
  15. //Object.entries 返回键/值对数组:[ ["name","John"], ["age", 30] ]。这就是 Map 所需要的格式。

Object.fromEntries:从 Map 创建对象

Object.fromEntries 方法的作用:给定一个具有 [key, value] 键值对的数组,它会根据给定数组创建一个对象:

  1. let prices = Object.fromEntries([
  2. ['banana', 1],
  3. ['orange', 2],
  4. ['meat', 4]
  5. ]);
  6. // 现在 prices = { banana: 1, orange: 2, meat: 4 }
  7. alert(prices.orange); // 2

调用 map.entries() 将返回一个可迭代的键/值对,这刚好是 Object.fromEntries 所需要的格式。

  1. let map = new Map();
  2. map.set('banana', 1);
  3. map.set('orange', 2);
  4. map.set('meat', 4);
  5. let obj = Object.fromEntries(map.entries()); // 创建一个普通对象
  6. //上面那行可以简写,因为 Object.fromEntries 期望得到一个可迭代对象作为参数,
  7. 而不一定是数组。并且 map 的标准迭代会返回跟 map.entries() 一样的键/值对。
  8. 简写:let obj = Object.fromEntries(map); // 省掉 .entries()
  9. // obj = { banana: 1, orange: 2, meat: 4 }
  10. alert(obj.orange); // 2

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 里面的每一个值只出现一次的原因。

  1. let set = new Set();
  2. let john = { name: "John" };
  3. let pete = { name: "Pete" };
  4. let mary = { name: "Mary" };
  5. // visits,一些访客来访好几次
  6. set.add(john);
  7. set.add(pete);
  8. set.add(mary);
  9. set.add(john);
  10. set.add(mary);
  11. // set 只保留不重复的值
  12. alert( set.size ); // 3
  13. for (let user of set) {
  14. alert(user.name); // John(然后 Pete 和 Mary)
  15. }

Set 迭代(iteration)

可以使用 for..of 或 forEach 来遍历 Set:

  1. let set = new Set(["oranges", "apples", "bananas"]);
  2. for (let value of set) alert(value);
  3. // 与 forEach 相同:
  4. set.forEach((value, valueAgain, set) => {
  5. alert(value);
  6. });

forEach 的回调函数有三个参数:一个 value,然后是 同一个值 valueAgain,最后是目标对象。这3个参数是为了与 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。