ES6: Is it dangerous to delete elements from Set/Map during Set/Map iteration?

后端 未结 2 817
情话喂你
情话喂你 2020-11-28 13:05

Safe code for new Set() may look like:

let items = [];
for (let item of set)
  if (isBad(item))
    items.push(item);
for (let item of items)
  s         


        
相关标签:
2条回答
  • 2020-11-28 14:00

    I would say yes, it's safe. When you iterate over the Set/Map using for ... of under the hood the loop is going through @@iterator. And Iterator operates with .next() only: so no indices and no matter what is before the current position. Only one next element is important.

    So until you remove elements "in front of" the current iterator position - it's safe to do it.

    0 讨论(0)
  • 2020-11-28 14:03

    Yes, you can simplify to that, it's totally safe.

    • Sets and Maps are always iterated in insertion order
    • Deleting an item does not affect the position of any iterator - you can visualise the shape of the collection not being changed, just being emptied.
    • So: elements that are deleted and have not yet been iterated won't be iterated
    • Elements that have already been iterated and are deleted (like in your case) won't affect anything but other iterations/lookups.
    • Elements that are added (and are not already part of the collection) during the iteration will always be iterated

    From that last point follows that the only dangerous thing to do would be something like

    const s = new Set([1]);
    for (let x of s) {
        s.delete(x);
        s.add(1);
    }
    

    but not because of undefined behaviour or memory accumulation, but because of the infinite loop.

    0 讨论(0)
提交回复
热议问题