0

This question deals with the case where you're using an index variable for iteration.

But does anyone know what happens when you are using a JS for ... of iteration and decide to remove elements from it in the course of the loop? As it happens I'm using a JS Set. But I presume the answer, whatever it is, would apply to a simple array as well... In Java you are not allowed to do this: it would produce a ConcurrentModificationException.

I.e.:

const nodes = new Set();
...
for( node of  nodes ){
  if( node.tagName === 'BR' ){
    nodes.delete( node );
  }
}

... in short can I be sure that JS would take the above code "in its stride" and would be guaranteed not to fail to iterate through any nodes, or conversely complain about some internal index variable being "out of range"?

NB there is also the case where you delete not the element you are currently processing, but another element which you find to be another member of the Set, e.g. in this case, if you found that node.parentNode was in the Set and you then deleted it. Quite surprised at the down votes here. This is not an obvious question and presumably involves intimate knowledge of JS algorithms.

NB2 I have tested it... and it seems to work OK. But that is not proof that it will always work OK.

mike rodent
  • 14,126
  • 11
  • 103
  • 157
  • 2
    I have. Why don't you, I don't know, think about things like proving a negative? – mike rodent Oct 18 '17 at 15:59
  • Duly noted and deleted. Why did you not include that you'd tried it in the question? On a side note, I will be greatly surprised if the ECMAScript spec actually mentions this case and the answer is almost certainly up to the implementer (i.e. not guaranteed consistent). – Jared Smith Oct 18 '17 at 16:00
  • @JaredSmith Here's a surprise! The spec is definite about the behavior of collection iteration. – Bergi Oct 18 '17 at 16:06
  • @JaredSmith Ah, yes, you make a good point there. I forgot, or hadn't thought clearly enough, that JS is not just one implementation, but a kind of "contract" defined by the spec. So I suppose risking this is just ... bad. – mike rodent Oct 18 '17 at 16:15
  • @Bergi Sorry, could you give a link to that: is this sort of pending-iteration deletion allowed? – mike rodent Oct 18 '17 at 16:16
  • @mikerodent *all* languages are with a formal spec are like that (e.g. C, Scheme): some are just lucky enough to also have a canonical reference implementation (e.g. Java, Python). Unfortunately, JS ain't one. But it also isn't the only, as any C/C++ coder can tell you. – Jared Smith Oct 18 '17 at 16:16
  • @mikerodent See the duplicate: yes, it's allowed. For spec links: it's the combination of how [Set iteration](http://www.ecma-international.org/ecma-262/6.0/#sec-%25setiteratorprototype%25.next) and [deletion](http://www.ecma-international.org/ecma-262/6.0/#sec-set.prototype.delete) are specified. – Bergi Oct 18 '17 at 16:19
  • @Bergi Great, thanks... looked at the other question. Problem solved! – mike rodent Oct 18 '17 at 16:25

0 Answers0