1. ECMAScript 6 新增的 Set 是一种新集合类型,为这门语言带来集合数据结构。Set 在很多方面都 像是加强的 Map,这是因为它们的大多数 API 和行为都是共有的。

一、基本API

使用 new 关键字和 Set 构造函数可以创建一个空集合 :

  1. const m = new Set();

如果想在创建的同时初始化实例,则可以给 Set 构造函数传入一个可迭代对象,其中需要包含插入 到新集合实例中的元素:

  1. // 使用数组初始化集合
  2. const s1 = new Set(["val1", "val2", "val3"]);
  3. alert(s1.size); // 3

初始化之后,可以使用 add()增加值,使用 has()查询,通过 size 取得元素数量,以及使用 delete() 和 clear()删除元素 :

  1. const s = new Set();
  2. alert(s.has("Matt")); // false
  3. alert(s.size); // 0
  4. s.add("Matt")
  5. .add("Frisbie");
  6. alert(s.has("Matt")); // true
  7. alert(s.size); // 2
  8. s.delete("Matt");
  9. alert(s.has("Matt")); // false
  10. alert(s.has("Frisbie")); // true
  11. alert(s.size); // 1
  12. s.clear(); // 销毁集合实例中的所有值
  13. alert(s.has("Matt")); // false
  14. alert(s.has("Frisbie")); // false
  15. alert(s.size); // 0
  16. add()返回集合的实例,所以可以将多个添加操作连缀起来,包括初始化:
  17. const s = new Set().add("val1");
  18. s.add("val2")
  19. .add("val3");
  20. alert(s.size); // 3
  1. Map 类似,Set 可以包含任何 JavaScript 数据类型作为值。集合也使用 SameValueZero 操作
  2. ECMAScript 内部定义,无法在语言中使用),基本上相当于使用严格对象相等的标准来检查值的匹
  3. 配性。
  4. const s = new Set();
  5. const functionVal = function() {};
  6. const symbolVal = Symbol();
  7. const objectVal = new Object();
  8. s.add(functionVal);
  9. s.add(symbolVal);
  10. s.add(objectVal);
  11. alert(s.has(functionVal)); // true
  12. alert(s.has(symbolVal)); // true
  13. alert(s.has(objectVal)); // true
  14. // SameValueZero 检查意味着独立的实例不会冲突
  15. alert(s.has(function() {})); // false

二、顺序与迭代

Set 会维护值插入时的顺序,因此支持按顺序迭代。
集合实例可以提供一个迭代器(Iterator),能以插入顺序生成集合内容。可以通过 values()方 法及其别名方法 keys()(或者 Symbol.iterator 属性,它引用 values())取得这个迭代器:

  1. const s = new Set(["val1", "val2", "val3"]);
  2. alert(s.values === s[Symbol.iterator]); // true
  3. alert(s.keys === s[Symbol.iterator]); // true
  4. for (let value of s.values()) {
  5. alert(value);
  6. }
  7. // val1
  8. // val2
  9. // val3
  10. for (let value of s[Symbol.iterator]()) {
  11. alert(value);
  12. }
  13. // val1
  14. // val2
  15. // val3
  16. 因为 values()是默认迭代器,所以可以直接对集合实例使用扩展操作,把集合转换为数组:
  17. const s = new Set(["val1", "val2", "val3"]);
  18. console.log([...s]); // ["val1", "val2", "val3"]
  19. 集合的 entries()方法返回一个迭代器,可以按照插入顺序产生包含两个元素的数组,这两个元
  20. 素是集合中每个值的重复出现:
  21. const s = new Set(["val1", "val2", "val3"]);
  22. for (let pair of s.entries()) {
  23. console.log(pair);
  24. }
  25. // ["val1", "val1"]
  26. // ["val2", "val2"]
  27. // ["val3", "val3"]
  28. 如果不使用迭代器,而是使用回调方式,则可以调用集合的 forEach()方法并传入回调,依次迭
  29. 代每个键/值对。传入的回调接收可选的第二个参数,这个参数用于重写回调内部 this 的值:
  30. const s = new Set(["val1", "val2", "val3"]);
  31. s.forEach((val, dupVal) => alert(`${val} -> ${dupVal}`));
  32. // val1 -> val1
  33. // val2 -> val2
  34. // val3 -> val3