Closed Bug 1520421 Opened 7 years ago Closed 1 year ago

for..in loop iterating an Array doesn't iterate over a deleted/re-added element

Categories

(Core :: JavaScript Engine, defect, P5)

64 Branch
defect

Tracking

()

RESOLVED DUPLICATE of bug 1486656

People

(Reporter: sgarden, Unassigned)

Details

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0

Steps to reproduce:

I develop an application which doesn't work on FF in comparison with other browsers.

The issue deals with a piece code which relays on for..in loop to iterate an Array.

When the issue occurs, this array contains 3 elements which have been added with Array.push.

Please note that the code within the loop doesn't modify the iterated array.

Actual results:

The for..in loop iterates the two first elements and exits before processing the last element of the array.

Expected results:

I know for..in expressions are not the recommended way to iterate arrays.

But as far as I know, the for..in loop should process every elements.

I could reproduce the bug on JSFiddle.

https://jsfiddle.net/4qx5j8yc/

The for..in loop is supposed to hide every item in the chart legend. However, it doesn't iterate the last element (a serie object) within a series Array.

However I said the code doesn't modify the array. Actually, it looks like it might. So I suppose the combination of var..in loop and inner array manipulation results in a Undetermined behavior.

update function called there deletes and sets the 2th element.

reduced testcase:

const a = [10, 20, 30];
for (const i in a) {
  console.log(i);
  if (i == "1") {
    delete a[2];
    a[2] = 30;
  }
}
Status: UNCONFIRMED → NEW
Component: Untriaged → JavaScript Engine
Ever confirmed: true
Product: Firefox → Core

https://tc39.github.io/ecma262/#sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation

13.7.5.11 Runtime Semantics: LabelledEvaluation
...
IterationStatement : for (LeftHandSideExpression in Expression) Statement
Let keyResult be ? ForIn/OfHeadEvaluation(« », Expression, enumerate).

https://tc39.github.io/ecma262/#sec-runtime-semantics-forin-div-ofheadevaluation-tdznames-expr-iterationkind

13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation ( TDZnames, expr, iterationKind )
...
6. If iterationKind is enumerate, then
...
b. Let obj be ! ToObject(exprValue).
c. Return ? EnumerateObjectProperties(obj).

https://tc39.github.io/ecma262/#sec-enumerate-object-properties

13.7.5.15 EnumerateObjectProperties ( O )
...
2. Return an Iterator object (25.1.1.2) whose next method iterates over
all the String-valued keys of enumerable properties of O.
...
The mechanics and order of enumerating the properties is not
specified but must conform to the rules specified below.
...
Properties of the target object may be deleted during enumeration.
A property that is deleted before it is processed by the iterator's
next method is ignored. If new properties are added to the target
object during enumeration, the newly added properties are not guaranteed
to be processed in the active enumeration.

In the above case, property "2" is deleted, and added again.
so whether the added "2" is enumerated or not is just implementation-dependent.

I don't think we are going to start working on this immediately, since the standard permits this behavior... but in a long enough time frame, surely this will get standardized and one vendor or another will have to change behavior. Leaving this bug open.

Priority: -- → P5
Summary: for..in loop iterating an Array doesn't iterate over the last element → for..in loop iterating an Array doesn't iterate over a deleted/re-added element

In the meantime, as a workaround, try a for-of loop.

Severity: normal → S3
Status: NEW → RESOLVED
Closed: 1 year ago
Duplicate of bug: 1486656
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.