Firstly, using a for...in
loop to iterate the indexes of an array shouldn't be done, instead, use a regular for
loop for that. If you want to iterate the values of an array, use something like a for...of
or .forEach()
loop.
The first difference between your two examples is probably the most obvious one. In your first example you've declared your variable with const
, so assigning it to a different value within the body of your for loop cannot be done. Whereas with let
you can reassign it if you need to.
For example, the below will throw an error if you try and reassign value
const array = ["a","b","c"];
for (const value of array) { // updated to for...of loop
value = 1; // this will throw!
console.log(value);
}
Whereas the below code will work fine:
let value
const array = ["a","b","c"];
for (value of array) {
value = 1; // works perfectly fine
console.log(value);
}
The other differences between your two examples are to do with scoping of the value
variable. In the first one, a new value
binding is created for each iteration of your array and invocation of the for
loop body, meaning that independent value
variables are essentially created for each iteration and scoped to the current block. This means that value
cannot be accessed outside of your for loop. In your second code block, let value
is declared outside of your for loop, so naturally, it can be accessed outside of your for
loop.
const array = ["a","b","c"];
for (const value of array) {
console.log(value);
}
console.log(value); // this will throw!
Compared with value
that is declared outside of the loop:
let value;
const array = ["a","b","c"];
for (value of array) {
console.log(value);
}
console.log(value); // this will work and log "c"
In addition to this, declaring value
outside of your for
loop means that the same global value
variable that you declared will be updated on each iteration of your for loop, resulting in each invocation of your for loop body sharing the same variable. The implications of this can be seen if you have a closure/function inside of your loop.
The below logs a
, b
, c
, because when the setTimeout()
callback function is declared in the loop it uses the unique binding created for value
for that particular iteration of the loop:
const array = ["a","b","c"];
for (const value of array) {
setTimeout(() => {
console.log(value);
}, 500);
}
// logs:
// a
// b
// c
This logs c
, c
, c
, because when the callback function is created, it uses the globally shared value of value
, and by the time the setTimeout()
s execute, the for loop would have completed (so value would be "c"
by that time):
let value;
const array = ["a","b","c"];
for (value of array) {
setTimeout(() => {
console.log(value);
}, 500);
}
// logs:
// c
// c
// c
As using const
(or let
) in the for
loop statement directly needs to create a new binding for each invocation of your loop, you could say that it takes up more memory, but that small amount should be negligible and something not to worry about. Moreover, JavaScript engines most likely will optimize for this, so I would suggest declaring your variables inside the loop statement directly, as it will minimize issues with leaking variables into the surrounding scope outside of your for
loop.