# 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.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

```toml bunfig.toml
[lint.rules]
"no-loop-func" = "error" # or "warn"
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad */}
```js
for (var i = 0; i < buttons.length; i++) {
  buttons[i].onclick = function () {
    select(i); // always buttons.length
  };
}
```

{/* bad */}
```js
let page = 0;
while (page < pages.length) {
  tasks.push(() => download(pages[page]));
  page++;
}
```

Not reported. Each iteration gets its own `i` and `page`:

{/* good */}
```js
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:

{/* good */}
```js
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:

{/* good */}
```js
for (var i = 0; i < buttons.length; i++) {
  (function () {
    select(i);
  })();
}
```
