Skip to content

for (let i ...) closures in the update expression see final value #88

@RealColdFry

Description

@RealColdFry

Repro:

const fns: (() => number)[] = [];
for (let i = 0; i < 3; i++, fns.push(() => i)) {}
return fns.map(f => f());

Expected: [1, 2, 3]
Actual: [3, 3, 3]

Per ECMA-262 CreatePerIterationEnvironment (invoked from the for statement's LabelledEvaluation), let in a for creates a fresh binding per iteration, and the update expression runs inside that per-iteration environment. We emit a single shared local i and run the update in the outer scope, so closures built in the update clause all capture the same variable. A per-iteration body wrapper isn't enough; the update expression must also run inside the per-iteration scope.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions