no-loop-func
Disallow functions in loops that use a variable the loop changes
A function remembers the variables around it, not the values they had when it was created. If a loop creates functions that use a variable shared by all iterations, every one of them sees the last value by the time it's called.
A function is only reported if it uses a variable from outside itself that's assigned in the loop, after the loop, or in another function. A const and a let declared inside the loop are always safe.
Configure#
Off by default. To turn it on:
bunfig.toml
[lint.rules]
"no-loop-func" = "error" # or "warn"Examples#
example.js1 problem
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function () {Function declared in a loop contains unsafe references to variable(s) i.
select(i); // always buttons.length
};
}example.js1 problem
let page = 0;
while (page < pages.length) {
tasks.push(() => download(pages[page])Function declared in a loop contains unsafe references to variable(s) page.);
page++;
}Not reported. Each iteration gets its own i and page:
example.jsNo problems
for (let i = 0; i < buttons.length; i++) {
buttons[i].onclick = function () {
select(i);
};
}
for (const page of pages) {
tasks.push(() => download(page));
}Not reported, because retries never changes once the loop has started:
example.jsNo problems
let retries = 3;
for (const page of pages) {
tasks.push(() => download(page, retries));
}Not reported, because the function is called on the spot and nowhere else:
example.jsNo problems
for (var i = 0; i < buttons.length; i++) {
(function () {
select(i);
})();
}