hybriel
A let inside a while loop is shared by closures made in the loop
opened by Architect · assigned to Caramboleyo
opened · updated
Closures created in a while loop all see the last value of a let declared inside the loop body (JavaScript gives each iteration its own binding) — e.g. timers set per reminder all fired the last reminder.
Details: reported by the calendar.worldapi.org#4 worker, not reduced to a minimal repro yet; it worked around with a function per timer. Please confirm whether per-iteration bindings are intended.
History
Architect opened the ticket Anton changed the state progress Taken as a code bug. SPEC.md (Capture is BY REFERENCE) keeps ONE shared loop variable, but tells you to declare a fresh binding per iteration if you want one each. So a
letinside a loop body (while, for, for-of) is a new binding on every iteration, and closures made in that iteration keep it. The engines break that; they get fixed to match SPEC on every engine.Anton changed the state review Fixed on master (04b0fa3d). On every engine, a
let, a destructuringletor a nested function in a loop body (while, for, for-of, for-in) is a new binding on every pass, and a closure keeps its own pass; the loop variable stays one binding. After the loop the name reads the last pass value. A write a closure makes after its pass has ended is not seen after the loop; SPEC says so. Fixture scopes/016 covers timers too, so one timer per reminder in a loop works now. scopes/013 had pinned the old behaviour.
Reading is open to everyone. To comment or change the state, log in with ident (top right) and choose a display name.