使用 for..of 迭代时删除 Set 中的元素是否安全?

2024-04-18

是否指定可以删除实例中的任意元素Set迭代时使用for..of然后

  • 你不会在一个元素上迭代多次
  • 除了删除的元素之外,您不会错过迭代开始时集合中的任何其他元素

?


Yes,在迭代集合时添加元素和删除元素是完全可以的。 JavaScript 2015 (ES6) 已考虑并支持此用例。它将使其保持一致的状态。请注意,这也适用于迭代forEach.

直观地说:

集合迭代算法基本上看起来像这样:

Set position to 0
While position < calculateLength() // note it's calculated on each iteration
    return the element at set.entryList[position]

加法看起来像这样:

If element not in set
   Add element to the _end_ of the set

所以它不会干扰现有的迭代——他们会迭代它。

删除看起来像这样:

Replace all elements with are equal to `element` with a special empty value

用空值替换它而不是删除它可以确保它不会弄乱迭代器的位置。


Formally

Addition

这是规范的相关部分%SetIteratorPrototype%.next:

当索引小于条目的元素总数时重复。每次评估此方法时都必须重新确定元素的数量。

设置迭代器继续逐一迭代条目。

From Set.prototype.add:

将值附加为last条目的元素。

这确保了当向列表添加元素时,它将在迭代完成之前进行迭代,因为它总是在条目列表中获得一个新的槽。因此,这将按照规范的要求工作。

至于删除:

替换值为e的条目的元素具有值为空的元素。

用空元素替换它而不是删除它可以确保现有迭代器的迭代顺序不会失去或排序,并且它们将继续正确地迭代集合。

有代码

这是演示此功能的简短代码片段

var set = new Set([1]);
for(let item of set){
   if(item < 10) set.add(item+1);
   console.log(item);
}

它记录数字 1 到 10。这是一个不使用 for... 的版本,您今天可以在浏览器中运行:

var set = new Set([1]);
for (var _i = set[Symbol.iterator](), next; !(next = _i.next()).done;) {
   var item = next.value;
   if (item < 10) set.add(item + 1);
   document.body.innerHTML += " " + item;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 for..of 迭代时删除 Set 中的元素是否安全? 的相关文章

随机推荐