Back to all questions

What's wrong with var in a loop with setTimeout?

Devs Hive

Devs Hive

Seen on interview: 5 users

This is one of those old chestnuts that these days you'll mostly meet only in interviews at so-called "trash galley" companies. Most often, the question is split into 2 parts:

First, you'll be asked what gets logged to the console

for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}

// Результат
// 3
// 3
// 3

We got this output because var has function scope, so the variable і is effectively shared across all iterations. It is overwritten on every iteration, and by the time the loop finishes, its value is 3. Since setTimeout schedules a macrotask, it waits for the synchronous code to finish, and by the time all three console.log calls run, і=3.

Next, you may be asked how to fix it

The most obvious way is to use let. It has block scope, and a new scope is created for each iteration. Besides let, you can use IIFE (Immediately Invoked Function Expression), which also creates a new scope on each iteration.

for (var i = 0; i < 3; i++) {
(function(i) {
setTimeout(() => console.log(i), 100);
})(i);
}

Seen on interview?

Comments (0)

Sign in to leave a comment

No comments yet. Be the first!