for...of loop. Should I use const or let?
Asked Answered
P

5

77

When using a for of loop, both of these are allowed and work:

const numbers = [1,2,3];
// works
for(let number of numbers) {
    console.log(number);
}
// also works
for(const number of numbers) {
    console.log(number);
}

I always use const since I cannot fathom changing the number variable in any context, but when I see a for...of loop in other people's code, it often uses let. Maybe there's a drawback to const that I didn't see? Browser bugs?

Why use const and when to use let in for...of loops?

Pointless answered 21/10, 2019 at 9:9 Comment(12)
The only difference is due to the usual rules of const vs let, the fact that they're declared in a for..of loop declaration doesn't change anythingTeddi
@Teddi This question is specifically about for...of, I know what const means in general. If what you say is true, why are developpers ever using let? I see them using const everywhere else, but still let in loops.Lanyard
do you assign a value to number later?Tragedian
People probably use let because they're either too lazy to write additional characters, or because they don't care about the difference. Unless it actually gets reassigned somewhere, feel fee to just call it bad code and use const instead (IMO)Teddi
@NinaScholz As I said, I don't and can't fanthom it. But still I see for(let x... in examples, so I was thinking there must be something other developpers know and I don't.Lanyard
There are lots of crappy examples and tutorials out there that follow bad practices, unfortunately, especially with a language as popular as JavascriptTeddi
This is a duplicate. The fact that the variables are being declared in a for loop declaration makes no difference at allTeddi
When you want to reassign number inside for...of for whatever reason, use let (Something like anotherArray.push(++number). Else, use const.Doucette
This is not a duplicate and I can tell you EXACTLY why it is done.Semaphore
@Semaphore I agree with your sentiment, but the EDIT: section in the text was not appropriate so I rolled it back.Lanyard
@TomášZato-ReinstateMonica I'm glad you did, it was awkward. just we need to reopen it. However I suggest the title edit was good since it pointed to the core issue not of 'which to use' but why it's so prevalent.Semaphore
@TomášZato-ReinstateMonica well, the question was reopened and so I moved my thoughts to their own answer. I feel better clarifying that! The question of using it in loops really is different than general difference between them :)Semaphore
S
54

There is a simple reason for the prevalence of for(let i instead of for(const i among even experienced devs/tutorial makers who are not modifying the value in the loop body and understand const/let.

Many people see const as a 'constant' which should never change. ever. (of course it never changes). But they further feel awkward 'redefining multiple constants with the same name'. For example, having const server = 'fun.example.com' in one place, and const server = 'boring.example.com' in another place would be 'objectionable'.

The variables in loops (at least in most C-like syntax languages which JavaScript is based on) are the variables that change THE MOST. Nothing gets it's value changed more than the 'i' in all the for loops. The 'i' typically ends up being a 'register variable' on the CPU itself (not in RAM) so that it can 'change faster'. And this was even true in JavaScript since it's inception with 'var', and is still true when you do a simple for(let i=0;i<50;i++). ie for(const i=0;i<50;i++) throws an error.

So you can start to see the dissonance between an 'i' that changes (or is redefined) potentially thousands of times per second as you iterate through a list and for(const i. So for(const i... 'looks' or 'feels' like i will only ever have the first value it is assigned. It seems 'wrong' to say const i.. and on the next line of code, i could be totally different values each time 'through the loop'. And even if you 'know' you are 'redefining it for each run through the loop', to some devs, that itself is questionable.

For this reason, many devs prefer to reserve const in JavaScript for 'values that are defined once and represent a single value throughout the 'whole execution of the program' or at least 'everything in a class'.

So the answer to the question in your 'title' (should I use) is probably 'keep using const since you have a reason and it makes sense to you'. And the answer to the doubt you had of "why is for(let i so common" is what I answered here as well. For some, they just have habit of for(let because it works for both 'for loops' and 'iterations through list'. For others, it's a conscious choice because they don't like 'redefining a const' over and over.

And I would humbly suggest that if you do use const please don't use i for the 'item' since i is so associated with an integer variable that increments. At least if you use a good name like item it feels more comfortable thinking of it as a single thing that only existed once. And I humbly suggest that if you use 'let' also don't use let i of for the same reason. Use i only for actual incrementing items. Ie use for(let item of items) or for(let i=0;i<y;i++)

Semaphore answered 30/7, 2020 at 17:45 Comment(5)
This should be the accepted answer. It responds directly to the question rather than explaining the difference between const and let, which the asker clearly already understands.Tartuffe
This might be the reason indeed, but the reasoning makes no sense. Creating multiple variables with the same name happens all the time, when functions are called or when classes are created. Do people avoid const declarations in function scopes? No.Humming
@Humming yes they do, in most languages. using const everywhere in javascript is quite an anomaly. honestly i think people were just showing off. it's like the people who want to put types everywhere always trying to be as restrictive as is possible in any given syntax. you would expect let everywhere except references to fixed 'hard coded' values. My guess people who use 'const' where let would be just as good are the same people who will vote for typscript to replace javascript.Semaphore
@Semaphore That does not match my experience, neither from JS/TS nor other languages. You may need to do some more functional programming to understand the mindset, but it's absolutely not about "showing off", it's about conveying intention. People use const because let would not be "just as good", it would be worse.Humming
@Humming const in something like mapping a function an an array or inline iteration just is better in a show off sense and in no 'actual' sense. nobody has any question about your 'intent', and nobody is going to go crazy and reuse your variable for some other purpose. and const doesn't stop them since they could just change it to let if they wanted. const definitely has it's place, but it can also be empty virtue signaling heh.Semaphore
T
63

Why use const and when to use let in for...of loops?

If there are no assignments to the identifier within the loop body, it's a matter of style whether you use let or const.

Use const if you want the identifier within the loop body to be read-only (so that, for instance, if someone modifies the code later to add an assignment, it's a proactive error). Use let if you want to be able to assign to it (because you have an assignment in your code, or you want someone to be able to add one later without changing the declaration).

You can do this with for-of and for-in loops. A for loop's control variable is normally not constant (since in the normal case you update it in the "update" clause of the for; if you don't, for may be the wrong loop to use), so you normally use let with it.


For clarity, here's an example with an assignment within the loop body:

for (let str of ["a", " b", " c "]) {
    str = str.trim();
//  ^^^^^----- assignment to the identifier
    console.log(`[${str}]`);
}

If you use const for str in the above, you get an error:

for (const str of ["a", " b", " c "]) {
    str = str.trim();
//  ^^^^^----- Error
    console.log(`[${str}]`);
}
Turkestan answered 21/10, 2019 at 9:17 Comment(4)
I'd argue about "entirely a matter of style" part. const provides extra protection. I have seen so many times loop variable modified say for display purpose but the code below still relies on the original value.Novelia
@T.J.Crowder You answered a question about performance of const, let and var before: https://mcmap.net/q/36538/-v8-javascript-performance-implications-of-const-let-and-var. I wonder if using const over let in a for loop would have implications for engine optimizations? I understand it's negligible in practice... just curious.Cowpoke
@Cowpoke - You can't use const in a for loop in most cases (though you can in some), because of the "increment" part of the loop. On for (let i = 0; i < 10; ++i) for instance, after an iteration and the test, when doing the ++i part the engine creates the new i for the new iteration, assigns it the value the old i had, and then does the increment part: ++i, which modifies the new i. So you can only use const in a for where the control variable doesn't change, something like for (const x = start(); !x.done(); x.next()) { console.log(x.current()); } (cont'd)Turkestan
... That's unusual enough and minor enough that I doubt it's an optimization target for engine implementers. I do use const with for-in and for-of loops as a matter of habit because I almost never want to modify the per-iteration variable within the block, and there I suspect (but don't know) there might be some benefit if you create functions within the loop body. I doubt the benefits are significant if there are any, though, as you say. :-)Turkestan
S
54

There is a simple reason for the prevalence of for(let i instead of for(const i among even experienced devs/tutorial makers who are not modifying the value in the loop body and understand const/let.

Many people see const as a 'constant' which should never change. ever. (of course it never changes). But they further feel awkward 'redefining multiple constants with the same name'. For example, having const server = 'fun.example.com' in one place, and const server = 'boring.example.com' in another place would be 'objectionable'.

The variables in loops (at least in most C-like syntax languages which JavaScript is based on) are the variables that change THE MOST. Nothing gets it's value changed more than the 'i' in all the for loops. The 'i' typically ends up being a 'register variable' on the CPU itself (not in RAM) so that it can 'change faster'. And this was even true in JavaScript since it's inception with 'var', and is still true when you do a simple for(let i=0;i<50;i++). ie for(const i=0;i<50;i++) throws an error.

So you can start to see the dissonance between an 'i' that changes (or is redefined) potentially thousands of times per second as you iterate through a list and for(const i. So for(const i... 'looks' or 'feels' like i will only ever have the first value it is assigned. It seems 'wrong' to say const i.. and on the next line of code, i could be totally different values each time 'through the loop'. And even if you 'know' you are 'redefining it for each run through the loop', to some devs, that itself is questionable.

For this reason, many devs prefer to reserve const in JavaScript for 'values that are defined once and represent a single value throughout the 'whole execution of the program' or at least 'everything in a class'.

So the answer to the question in your 'title' (should I use) is probably 'keep using const since you have a reason and it makes sense to you'. And the answer to the doubt you had of "why is for(let i so common" is what I answered here as well. For some, they just have habit of for(let because it works for both 'for loops' and 'iterations through list'. For others, it's a conscious choice because they don't like 'redefining a const' over and over.

And I would humbly suggest that if you do use const please don't use i for the 'item' since i is so associated with an integer variable that increments. At least if you use a good name like item it feels more comfortable thinking of it as a single thing that only existed once. And I humbly suggest that if you use 'let' also don't use let i of for the same reason. Use i only for actual incrementing items. Ie use for(let item of items) or for(let i=0;i<y;i++)

Semaphore answered 30/7, 2020 at 17:45 Comment(5)
This should be the accepted answer. It responds directly to the question rather than explaining the difference between const and let, which the asker clearly already understands.Tartuffe
This might be the reason indeed, but the reasoning makes no sense. Creating multiple variables with the same name happens all the time, when functions are called or when classes are created. Do people avoid const declarations in function scopes? No.Humming
@Humming yes they do, in most languages. using const everywhere in javascript is quite an anomaly. honestly i think people were just showing off. it's like the people who want to put types everywhere always trying to be as restrictive as is possible in any given syntax. you would expect let everywhere except references to fixed 'hard coded' values. My guess people who use 'const' where let would be just as good are the same people who will vote for typscript to replace javascript.Semaphore
@Semaphore That does not match my experience, neither from JS/TS nor other languages. You may need to do some more functional programming to understand the mindset, but it's absolutely not about "showing off", it's about conveying intention. People use const because let would not be "just as good", it would be worse.Humming
@Humming const in something like mapping a function an an array or inline iteration just is better in a show off sense and in no 'actual' sense. nobody has any question about your 'intent', and nobody is going to go crazy and reuse your variable for some other purpose. and const doesn't stop them since they could just change it to let if they wanted. const definitely has it's place, but it can also be empty virtue signaling heh.Semaphore
L
0

You can use let instead of const if you reassign the variable inside the block.

const iterable = [10, 20, 30];

for (let value of iterable) {
  value += 1;
  console.log(value);
}
// 11
// 21
// 31
Leopoldine answered 21/10, 2019 at 9:12 Comment(0)
N
0

I think the const inside the for is not necessary. The const is used when the variable does not change inside the for:

let tmp = 0;
for(const num of numbers){
 tmp += num;
}

If you must modify the variable you can use let:

for(let num of numbers){
 num += 5;
}

But I prefer iterating over the array using this syntax:

numbers.forEach(num => {
  console.log(num)
});
Neckar answered 21/10, 2019 at 9:16 Comment(0)
K
0

There was a bug in versions prior to firefox 51 where using for...of with const threw a syntax error.

If supporting these older browsers matters to you, always use for...of with let.

Knudson answered 1/5 at 3:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.