JavaScript Scope — Does var create a new variable in loops?
This is a daily Javascript challenge from the CodeShot archive. Practice your knowledge of Var Loop Scope Myth and improve your technical interview readiness.
Detailed Explanation
Why This Question Matters
If you've ever spent three hours debugging a loop only to realize all your asynchronous callbacks are returning the exact same value, you've run into the var scoping nightmare.
The question "Does using var inside a for loop create a new variable for each iteration?" is a classic interview trap. It tests whether you actually understand how JavaScript handles memory and scope, or if you're just guessing based on how other languages like Java or C# work. In those languages, a loop variable is usually local to the block. In JavaScript, var plays by a completely different set of rules.
Understanding the Code
Since we aren't looking at a specific snippet, let's look at the most common scenario where this trips people up:
At first glance, you'd expect this to print 0, 1, 2. But it doesn't. It prints 3, 3, 3. Why?
Because var is function-scoped, not block-scoped.
When you declare var i in the head of a for loop, JavaScript doesn't create a new i every time the loop restarts. Instead, it hoists that variable to the top of the surrounding function (or the global scope if you're not in a function).
Essentially, there is only one i for the entire loop. Every iteration of the loop is just updating the value of that single, shared variable. By the time the setTimeout callbacks actually execute, the loop has already finished, and that one shared i has been incremented to 3.
Finding the Correct Answer
The answer is FALSE. Using var does not create a new variable for each iteration.
If the answer were true, the setTimeout example above would work as expected because each callback would "capture" its own unique version of i.
To actually get a new variable per iteration, you need let.
When you use let, JavaScript creates a new lexical environment for every single iteration of the loop. It basically "snapshots" the value of i for that specific turn of the loop, which is why the callbacks work correctly.
Common Mistakes Developers Make
The biggest mistake is assuming that curly braces {} always create a new scope. In most modern languages, they do. In JavaScript, they only do if you're using let or const.
Another common pitfall is trying to "fix" the var issue using an IIFE (Immediately Invoked Function Expression). Before let existed in ES6, this was the standard workaround:
While this works (because functions *do* create scope), it's verbose and makes the code harder to read. If you see this in a legacy codebase, it's a tell-tale sign that the original developer was fighting with var scoping.
Real-World Usage
In a modern production environment, you'll rarely see var used in a for loop. Most style guides (like Airbnb or Google) explicitly ban it. However, understanding this is still critical for two reasons:
1. Legacy Codebases: You will inevitably encounter a project written in 2014 that is riddled with var. If you change a var to a let without understanding why it was there, you might accidentally change the behavior of the application.
2. Closure Leaks: This behavior is the root cause of many closure-related bugs. When you create functions inside a loop that reference a variable declared outside that loop, you're creating a closure. If that variable is shared (via var), all your closures are pointing to the same reference.
This comes up a lot when building dynamic UI elements—like generating a list of buttons and assigning a click handler to each. If you use var for the index, every button you click will trigger the action for the very last item in the list.
Key Takeaways
- var is function-scoped. It doesn't care about your loop blocks.
- Only one instance of a var variable exists regardless of how many times the loop runs.
- let is block-scoped and creates a fresh binding for every iteration.
- If you're dealing with asynchronous code (Promises, setTimeout, fetch) inside a loop, always use let.
- When in doubt, stop using var entirely. There is almost no reason to use it in modern JavaScript development.
Why this matters
Understanding Var Loop Scope Myth is crucial for passing technical interviews. In real-world applications, this concept often leads to subtle bugs if not handled correctly. For more details, you can always refer to the official MDN Documentation.