I know it works with Set
, but I was under the impression that it would also work with Array. So I tried it in Chrome and was surprised that it didn't work:
const array = [1,2,3,4,5,6]
for (const item of array) {
if (item === 3 || item === 4) {
array.splice(array.indexOf(item), 1);
}
}
console.log(array) // [1,2,4,5,6]
It didn't delete the 4
.
So my question is, is iteration safety only supposed to work with Set
and Map
, but not Array
?
(If this is the case, then other than the simple syntax, I don't see the benefit of using it over for(;;)
. I was under the impression this for..of
was going to prevent bugs, even with Array
, like it does with Set
and Map
)
Note, as a trick, I can do it by cloning the array (or reverse iteration):
const array = [1,2,3,4,5,6]
for (const item of Array.from(array)) {
if (item === 3 || item === 4) {
array.splice(array.indexOf(item), 1);
}
}
console.log(array) // [1,2,5,6]
No, (as your example demonstrates) it's not safe to remove elements from an array while iterating it.
The default array iterator stores the current index, and it does not update this index when you call splice
on the array. It just continues at the same position, no matter what you did to the elements in the array. You can read the spec for ArrayIterator
objects, they basically work like a for (var index=0; index<array.length; index++) yield array[index];
loop.