New JavaScript Set methods title. A vibrant gradient with a JavaScript logo in the bottom-left corner and a venn diagram in the top-right corner.

新的 JavaScript Set 方法

作者头像Brian Smith阅读时间:6 分钟

新的 JavaScript Set 方法即将发布!自 Firefox 127 起,这些方法已在大多数主流浏览器引擎中可用,这意味着您无需 使用 polyfill 使其在所有地方都能正常工作

本文适合那些刚接触 JavaScript 中 Set 并希望了解如何使用这些新的 JavaScript 方法的人阅读。我将以一些基本的示例来突出显示使用这些方法的一些优势,展示了为什么您可能更愿意使用这些方法,而不是自己构建实现。

Set 方法有哪些新功能?

对于那些想要 TL;DR 的人,以下是具有跨浏览器支持的新方法的要点

  • intersection() 返回一个新集合,其中包含此集合和给定集合中的所有元素。
  • union() 返回一个新集合,其中包含此集合和给定集合中的所有元素。
  • difference() 返回一个新集合,其中包含此集合中但不在给定集合中的所有元素。
  • symmetricDifference() 返回一个新集合,其中包含任意一个集合中但不在两个集合中的所有元素。
  • isSubsetOf() 返回一个布尔值,指示集合中的所有元素是否都在特定集合中。
  • isSupersetOf() 返回一个布尔值,指示集合中的所有元素是否都在特定集合中。
  • isDisjointFrom() 返回一个布尔值,指示此集合是否与特定集合没有共同元素。

如果您阅读(或略读)了上面的列表并感到困惑,请不要担心,我们将在接下来的部分中描述它们的作用。所有这些方法都用于检查集合的内容与另一个特定集合的内容相比如何。

什么是 JavaScript Set?

集合类似于 数组,区别在于每个值只能存储一次。例如,我们可以取一个项目列表,将它们全部添加到集合中,然后检查集合的结果。右侧的列表是左侧 <ol> 列表的内容,但已转换为集合。我们从列表中删除了所有重复项,因为我们保证集合是唯一的

在如此小的示例中,这可能看起来并不起眼,但拥有一个内置方法来创建唯一的项目集合非常方便,尤其是在处理更大的数据和更复杂的数据类型和对象时。例如,考虑您可以像这样向集合中添加元素

js
const dogs = new Set();
const yoshi = { name: "Yoshi", personality: "Friendly" };
dogs.add(yoshi);

检查元素是否在一个集合中通常也比在数组中快,因此这适用于您需要在更大的数据集中关注性能的用例。您还可以根据现有集合来组合具有特定逻辑属性的新集合,下面我们将看一些示例。

我们将介绍下面所有新的方法,但如果您想了解有关 Set 的所有操作,请查看 实例方法 文档。

两个集合的并集

如果您不熟悉集合,这是一个不错的入门示例。使用并集,我们可以检查哪些元素存在于“任一集合或两个集合中”。在下面的示例中,我们有两个列表,我们想要创建一个第三个列表,它包含两个列表中的所有项目,但没有重复项

js
// Create a union of both sets
const unionSet = set1.union(set2);

// List the items in the union
unionSet.forEach((item) => {
  const li = document.createElement("li");
  li.textContent = item;
  unionList.appendChild(li);
});

我们使用每个列表项的 HTML textContent 来创建字符串集合,但您可以看到,如果我们考虑到集合可以包含像数组或对象这样的数据类型,那么这将是多么强大。

这很有用,因为我们不需要任何自定义实现来删除重复项、执行相等性检查或进行其他比较。一旦我们在集合中拥有元素,我们就知道它们都是唯一的,union 方法是一种优化的方法,可以创建一个由“任一集合或两个集合中”出现的(唯一)项目组成的第三个集合。

集合交集

使用集合交集,我们可以检查哪些元素出现在两个集合中,以查看重叠部分。在本例中,我们不会像上面使用 union 方法那样将交集集合显示为第三个列表,而是可以使用它来突出显示“仅出现在两个集合中”的元素

js
// Make the intersection set
const intersectionSet = set1.intersection(set2);

// Loop through lists and highlight if they're in the intersection
allListItems.forEach((item) => {
  if (intersectionSet.has(item.textContent)) {
    item.className = "match";
  }
});

集合对称差

在查看差集之前,让我们看一下 symmetricDifference,它听起来可能很复杂,但希望下面的示例能够澄清它。对称差的作用是让我们检查哪个元素存在于任意一个集合中,但不在两个集合中

js
const setNotBoth = set1.symmetricDifference(set2);

allListItems.forEach((item) => {
  if (setNotBoth.has(item.textContent)) {
    item.className = "match";
  }
});

如果这一切都是新的,您正在努力理解,请将对称差交集示例进行比较。您应该看到 symmetricDifference 方法执行与 intersection 方法相反的逻辑运算。

集合差集

使用集合差集,我们可以检查哪些元素存在于一个集合中,但不存在于另一个集合中。在本例中,我们创建了两个新集合,而不是一个。第一个(set1only)是使用 set1.difference(set2) 创建的,我们返回的是一个新的集合,其中包含“仅出现在集合一中”的项目。我们对新的集合 set2only 做同样的事情,以找到那些在集合二中但不在集合一中的项目。对于每个列表,我们可以使用使用 difference 创建的集合来突出显示不在另一个列表中的列表项。

js
const set1only = set1.difference(set2);
const set2only = set2.difference(set1);

allListItems.forEach((item) => {
  if (set1only.has(item.textContent)) {
    item.className = "setOneMatch";
  } else if (set2only.has(item.textContent)) {
    item.className = "setTwoMatch";
  }
});

子集、超集和不相交

最后,我们可以探讨的新的方法和概念是子集、超集和“不相交”方法。到目前为止,您已经熟悉了返回新集合的集合操作。子集、超集和不相交方法不会返回新集合,而是返回一个 布尔值,以指示某些状态或逻辑检查。

我们可以先查看的前两个是子集超集。我们没有突出显示列表项,而是有一些语句或断言,例如“集合一是的集合二的子集”。然后,我们根据类似 if (set1.isSupersetOf(set2)) 这样的检查的结果,在列表项中添加一些文本(TRUE / FALSE

js
if (set1.isSubsetOf(set2)) {
  oneSubTwo.textContent += " [TRUE]";
} else {
  oneSubTwo.textContent += " [FALSE]";
}

因此,使用子集,我们可以检查集合中的所有项目是否都出现在另一个集合中。使用超集,我们正在执行相反的操作,以查看一个集合是否包含来自另一个集合的所有项目,以及一些其他项目。

我们要看的最后一个方法是 isDisjointFrom(),我们可以使用它来找出两个集合是否没有共同元素。下面的第一个和第二个集合彼此不不相交,因为它们有一个共同元素(“C”)。第三个集合与另外两个集合不相交,因为它与这两个集合都没有共同项目

总结

我希望您喜欢这篇文章,了解了 Set 方法以及我认为集合是一个有趣且值得理解的概念的原因。您是否知道在现实世界示例中使用这些方法的不同方法?请随时 联系我们 并告诉我您的想法,或者告诉我是否有遗漏的地方!您应该为下一个项目做好一切准备,所以下次再见!

关注 MDN 的信息

订阅 MDN 时事通讯,不错过有关最新 Web 开发趋势、技巧和最佳实践的任何更新。