Skip to content

loopFunctions

Reports function declarations and expressions inside loops that reference variables modified by the loop.

✅ This rule is included in the performance preset.

Creating functions inside loops that reference variables modified by the loop often leads to unexpected behavior. Functions created in this way share the same scope and capture references to loop variables rather than their values at creation time. This means all created functions typically reference the final value of the loop variable, not the value during their creation.

This behavior is a common source of bugs in JavaScript applications, especially when creating event handlers, callbacks, or other deferred operations within loops.

const
const handlers: never[]
handlers
= [];
for (let
let i: number
i
= 0;
let i: number
i
< 5;
let i: number
i
++) {
const handlers: never[]
handlers
.
Array<never>.push(...items: never[]): number

Appends new elements to the end of an array, and returns the new length of the array.

@paramitems New elements to add to the array.

push
(function () {
Error ts(2345) ― Argument of type '() => number' is not assignable to parameter of type 'never'.
return
let i: number
i
;
});
}
// All handlers return 5, not 0, 1, 2, 3, 4
const
const items: string[]
items
= ["a", "b", "c"];
for (let
let i: number
i
= 0;
let i: number
i
<
const items: string[]
items
.
Array<string>.length: number

Gets or sets the length of the array. This is a number one higher than the highest index in the array.

length
;
let i: number
i
++) {
const button: any
button
.
any
addEventListener
("click", () => {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const items: string[]
items
[
let i: number
i
]);
});
}

This rule is not configurable.

If you are using modern JavaScript with let or const declarations in for loops, each iteration creates a new binding, which can mitigate some of the issues this rule warns about. However, the rule still catches cases where the behavior might be unexpected, so it’s generally beneficial to keep it enabled.

You may wish to disable this rule if you have a specific use case where creating functions in loops is intentional and the captured variable references are the desired behavior.

Made with ❤️‍🔥 around the world by the Flint team and contributors.