Use let in for loops. The difference is that var is function scoped and let is block scoped. When you use var you will be able to access i anywhere in the function it's declared in, even outside of the for loop. Generally you only want to use i inside the for loop so it's better to use let. const shouldn't work because i++ implies you are reassigning the value of i. Answer from Space_Atlas on reddit.com
Top answer
1 of 3
18

let is introduced in Ecma Script 6 - the new javascript version - which is still in development at the time of this writing. Therefore, using var will get you across more browsers for the time being.

On the other hand, I urge people to use let instead of var from now on. I would go ahead and list the reasons but you have already have a link in your post with a great explanation in it. Long story short, let helps you avoid the variable hoisting in javascript and keep your variables' scope at just where it needs to be.

update

I've forgotten about this post until I recently got an upvote. I'd like to update this statement. I personally use const as much as I can these days. If you get into linting your code, which I highly recommend, and use something like airbnb lint rules, it will also tell you to use const. It will make your variables a constant so you will not be able to mutate them once you set their value thus it is not applicable in all cases. const and let also have advantages in terms of scope over var and it is well worth a read. My hierarchy of usage goes as such const > let > var

2 of 3
11

Yes, you would want to use let there as it will be scoped only to that block.

Additionally, using let in this way will let you avoid accidentally creating a closure if you are calling a function in your loop and passing the counter as a parameter.

EDIT: Maybe this should be better put as: Ask yourself if you need to access the value of your variable outside of the loop. If you do, use var; in all other cases, use let.

Discussions

What is the difference between "let" and "var"?
Setting event listeners in a loop no longer requires an immediatelly invoked function expression for locally scoping i at each iteration. 2016-02-21T08:12:08.817Z+00:00 ... The use of "let" just defers this problem. So each iteration creates a private independent block scope, but the "i" variable ... More on stackoverflow.com
🌐 stackoverflow.com
Difference between var and let in for loop
for(let i = 0; i < 5; i++){ setTimeout(() => console.log(i) } Why the loop with let return 0,1,2,3,4 but loop with var return 5,5,5,5,5 ? ... This is because of hoisting. Declaring a variable with var in your for loop doesn’t limit its scope to just that block of code like it would using let. More on stackoverflow.com
🌐 stackoverflow.com
var vs. let inside a for loop
Is it a coincidence that 6 letters ... letters in Latin alphabets? ... Who was U. Uhlhorn, who first gave the correct proof of Wigner's theorem? Is it ever preferable to have an estimator with a larger variance? Words with at least 8 letters which have multiple occurrences of the same letter but not consecutively · Props on both sides of same turboprop engine. Is it possible? ... Why does the M06-2X functional, being not range-separated / long-range corrected, perform relatively well for charge-transfer ... More on stackoverflow.com
🌐 stackoverflow.com
Let vs. Var in a For Loop?
George Nixon is having issues with: I was having trouble getting this code to work as a loop through items: for (var i = 0; i More on teamtreehouse.com
🌐 teamtreehouse.com
1
October 27, 2017
🌐
DEV Community
dev.to › richardbray › why-the-var-and-let-keywords-shouldnt-be-used-interchangeably-3n07
Why the VAR and LET keywords shouldn't be used interchangeably - DEV Community
January 13, 2022 - var shows the function scoped variable in the main function (fn), but let shows the loop (_loop_1) inside the main function which is the extra bit of information saved in the event that goes through the event loop remembering the block scoped ...
🌐
Better Programming
betterprogramming.pub › scoping-in-javascript-for-loops-c5ffac6aa92b
Scoping in JavaScript For Loops. let vs. var inside your loop | by Johannes Baum | Better Programming
November 19, 2021 - I stumbled over two code snippets that made me think about the scoping in for loops and about a possible misunderstanding. The first one looks as follows: You can see it from time to time to demonstrate the event loop, the concept of closures, or as an interview question. The output of that code is: ... The variable i is captured in the closure of the anonymous function that calls console.log() and is invoked asynchronously via setTimeout().
🌐
Medium
medium.com › @amaldev.psn › why-let-and-var-behave-differently-in-loops-demystified-3f745aeaad3c
Why let and var Behave Differently in Loops — Demystified! | by Amaldev | Medium
July 9, 2025 - This is a mental model of how let ... with let i being freshly scoped to that block. On the other hand, var does not respect block scope; it is function-scoped....
Top answer
1 of 16
8394

Scoping rules

The main difference is scoping rules. Variables declared by var keyword are scoped to the immediate function body (hence the function scope) while let variables are scoped to the immediate enclosing block denoted by { } (hence the block scope).

function run() {
  var foo = "Foo";
  let bar = "Bar";

  console.log(foo, bar); // Foo Bar

  {
    var moo = "Mooo"
    let baz = "Bazz";
    console.log(moo, baz); // Mooo Bazz
  }

  console.log(moo); // Mooo
  console.log(baz); // ReferenceError
}

run();

The reason why let keyword was introduced to the language was function scope is confusing and was one of the main sources of bugs in JavaScript.

Take a look at this example from another Stack Overflow question:

var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++) {
  // and store them in funcs
  funcs[i] = function() {
    // each should log its value.
    console.log("My value: " + i);
  };
}
for (var j = 0; j < 3; j++) {
  // and now let's run each one to see
  funcs[j]();
}

My value: 3 was output to console each time funcs[j](); was invoked since anonymous functions were bound to the same variable.

People had to create immediately invoked functions to capture correct values from the loops but that was also hairy.

Hoisting

Variables declared with var keyword are hoisted and initialized which means they are accessible in their enclosing scope even before they are declared, however their value is undefined before the declaration statement is reached:

function checkHoisting() {
  console.log(foo); // undefined
  var foo = "Foo";
  console.log(foo); // Foo
}

checkHoisting();

let variables are hoisted but not initialized until their definition is evaluated. Accessing them before the initialization results in a ReferenceError. The variable is said to be in the temporal dead zone from the start of the block until the declaration statement is processed.

function checkHoisting() {
  console.log(foo); // ReferenceError
  let foo = "Foo";
  console.log(foo); // Foo
}

checkHoisting();

Creating global object property

At the top level, let, unlike var, does not create a property on the global object:

var foo = "Foo"; // globally scoped
let bar = "Bar"; // globally scoped but not part of the global object

console.log(window.foo); // Foo
console.log(window.bar); // undefined

Redeclaration

In strict mode, var will let you re-declare the same variable in the same scope while let raises a SyntaxError.

'use strict';
var foo = "foo1";
var foo = "foo2"; // No problem, 'foo1' is replaced with 'foo2'.

let bar = "bar1"; 
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared

2 of 16
851

let can also be used to avoid problems with closures. It binds fresh value rather than keeping an old reference as shown in examples below.

for(var i=1; i<6; i++) {
  $("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Clicking on each number will log to console:</p> 
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>

Code above demonstrates a classic JavaScript closure problem. Reference to the i variable is being stored in the click handler closure, rather than the actual value of i.

Every single click handler will refer to the same object because there’s only one counter object which holds 6 so you get six on each click.

A general workaround is to wrap this in an anonymous function and pass i as an argument. Such issues can also be avoided now by using let instead var as shown in the code below.

(Tested in Chrome and Firefox 50)

for(let i=1; i<6; i++) {
  $("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Clicking on each number will log to console:</p> 
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>

Find elsewhere
🌐
Stack Overflow
stackoverflow.com › questions › 71359009 › difference-between-var-and-let-in-for-loop
Difference between var and let in for loop
for(let i = 0; i < 5; i++){ setTimeout(() => console.log(i) } Why the loop with let return 0,1,2,3,4 but loop with var return 5,5,5,5,5 ? ... This is because of hoisting. Declaring a variable with var in your for loop doesn’t limit its scope to just that block of code like it would using let.
🌐
Codedamn
codedamn.com › news › javascript
Difference between let and var in JavaScript?
January 15, 2023 - It means that a variable declared with var can be accessed anywhere within the current function or global scope, while a variable declared with let can only be accessed within the block it was declared.
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Statements › let
let - JavaScript | MDN - Mozilla
The if block is evaluated because the outer var foo has a value. However due to lexical scoping this value is not available inside the block: the identifier foo inside the if block is the let foo. The expression foo + 55 throws a ReferenceError because initialization of let foo has not completed — it is still in the temporal dead zone. This phenomenon can be confusing in a situation like the following. The instruction let n of n.a is already inside the scope of the for...of loop's block.
🌐
Wes Bos
wesbos.com › for-of-es6
Quick Tip - Use let with for Loops in JavaScript - Wes Bos
August 31, 2016 - What do we know about let? It's block-scoped. We have curly brackets in the for loop. If you run it now, after a second we'll log zero through nine. We're not getting 10, 10 times. We getting it as it was declared each and every time. As a note, you couldn't use a const for this because it needs to overwrite itself, and you can't assign the same variable twice.
🌐
Stack Overflow
stackoverflow.com › questions › 75136033 › var-vs-let-inside-a-for-loop
var vs. let inside a for loop
const array = [1, 2, 3, 4]; for (let i = 0; i < array.length; i++) { setTimeout(() => { console.log(array[i]); }, 1000); } Whereas using var i = 0 in the for loop will produce undefined, undefined, undefined, undefined
🌐
JavaScript Tutorial
javascripttutorial.net › home › javascript tutorial › differences between var and let
Difference Between var and let in JavaScript
October 6, 2023 - In this example, the i variable is a global variable. Therefore, it can be accessed from both inside and after the for loop. The following example uses the let keyword instead of the var keyword:
🌐
Programiz
programiz.com › javascript › let-vs-var
JavaScript let Vs var (with Examples)
In the above program, the for loop redeclares the variable a. Hence the value of a is changed to 3 at the end. When a variable declared with let is used in a loop, the value of a variable does not change.
🌐
Medium
medium.com › @sumitgangwar127 › understanding-var-vs-let-in-javascript-loops-and-closures-e6539fd6bfff
Understanding var vs let in JavaScript Loops and Closures | by Sumitgangwar | Medium
November 4, 2024 - Let’s start with an example that illustrates the issue: ... Expected Output: You might expect this code to log 0, 1, and 2—the values of i at each iteration. Actual Output: After one second, the code logs: 3,3,3 .So, why is it logging 3 three times? var Scope: a. Variables declared with var are function-scoped. This means they do not have block scope, and a single instance of i is shared across all iterations of the loop.
🌐
Medium
medium.com › @singhshweta › let-vs-var-an-underestimated-difference-in-js-world-51a3f5641b81
let vs var : An underestimated difference in JS world | by Shweta Singh | Medium
February 3, 2022 - Let’s see. 👀 · The var keyword give the variable scope of the function in which its declared or the execution context and its closure. Therefore, declared only once. There will be only one reference for i which is used by each callback to fetchData, which means, by the time the callback method runs, the value of i must have changed to something else. In the above case, looks like, the entire loop has run already, and the i is set to 4.