是否指定在使用Set
进行迭代时可以删除for..of
实例中的任何元素
答案 0 :(得分:25)
是,在迭代时添加元素并删除元素是完全没问题的。这个用例被考虑并在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
用空值替换它而不是删除它确保它不会弄乱迭代器&#39;位置。
以下是%SetIteratorPrototype%.next
的规范的相关部分:
重复索引小于条目元素的总数。 每次评估此方法时,必须重新确定元素数量。
set迭代器继续逐个迭代这些条目。
来自Set.prototype.add
:
将值附加为条目的最后元素。
这确保了在向列表添加元素时,它将在迭代完成之前进行迭代,因为它总是在条目列表中获得新的插槽。因此,这将符合规范要求。
至于删除:
将值为e 的条目元素替换为值为空的元素。
用空元素替换它而不是删除它确保现有迭代器的迭代顺序不会输出或顺序,并且它们将继续正确迭代集合。
以下是演示此功能的简短代码段
var set = new Set([1]);
for(let item of set){
if(item < 10) set.add(item+1);
console.log(item);
}
其中记录了数字1到10.这是一个不用于...的版本,您今天可以在浏览器中运行:
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;
}
&#13;