This question already has answers here:
Inconsistent scope rules of variables in for, for-in and for-of loops
(4 answers)
ECMAScript 2015: const in for loops
(3 answers)
Closed 4 years ago.
I'm fairly well-versed on the differences between es6 let and const in general. What I'm not so sure about, is within the definition of a for..of loop.
I know that an "old-school" for loop signature will not accept const
ie
for (let i = 0; i < 100; i++) ... // works in chrome
for (const i = 0; i < 100; i++) ... // does not work in chrome (reassignment error)
However, with a for..of loop, it does not seem to make a difference
const someArray = ['hello', 'hey'];
for (let elem of someArray) ... // works
for (const elem of someArray) ... // also works?
So what's going on here?
Why is const allowed in for..of but not an old-school for loop?
What is the ultimate result difference within the loop? (other than possibly reassigning elem within the loop which I wouldn't expect many people to be doing regardless)
Only one variable is reassigned hence the error
for (const i = 0; i < 100; i++)
There is a separate variable created for each loop, hence, works fine
for (const elem of someArray)
Related
This question already has answers here:
Explanation of `let` and block scoping with for loops
(5 answers)
JavaScript closure inside loops – simple practical example
(44 answers)
let keyword in the for loop
(3 answers)
JavaScript: Understanding let scope inside for loop [duplicate]
(3 answers)
Closed 6 months ago.
This question is inspired by a very famous trick interview question for javascript closures, however I am more interested into another aspect of it. The code goes as follows:
let i
for (i = 0; i < 3; i++) {
setTimeout(function log() {
console.log(i); // What is logged?
}, 1000);
}
The answer is 3 3 3, and (I think) I know the explanation, each callback function can access the same i variable, by the time they are executed its value is 3.
When we write let inside for loop like this:
for (let i = 0; i < 3; i++) {
setTimeout(function log() {
console.log(i); // What is logged?
}, 1000);
}
Now we get 0 1 2. Ok, here the explanation is that when declared this way, i is scoped to this loop, not available outside, and each iteration has its copy of i.
The part that bugs me: it does not seem to be a different variable in each step. If we change i in a first step, it will be changed for other steps.
for (let i = 0; i < 3; i++) {
setTimeout(function log() {
console.log(i); // What is logged?
}, 1000);
if (i === 0) i ++
}
The result now is 1 2, skipped one step.
So I see two possible explanations for this, but I cannot confirm this anywhere.
Closures work differently for block-scoped and function or global scoped variable
After each step of the loop, the current state of the variable declared in a loop is copied to a new variable for the next step of the loop
???
Note: Please let's not focus on why values are 3 3 3 instead of 2 2 2, let's not go into event loop with setTimeout etc. unless relevant to the answer. I feel like closures and variable scopes will be most relevant here.
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Explanation of `let` and block scoping with for loops
(5 answers)
Closed 2 years ago.
Consider the following code:
const captured = [];
for (var i = 0; i < 2; ++i) {
captured.push(() => console.log(i));
}
for (let x = 0; x < 2; ++x) {
captured.push(() => console.log(x));
}
captured.forEach(v => v());
This gives the above output in the snippet.
In both cases, we effectively have a loop variable that exists outside of the scope of the loop body, and in both cases that variable is being mutated.
The only way I can explain this output is if the let declared loop variable (block-scoped) is "magically" copied when it is captured.
Did I get this right?
This question already has answers here:
What is the difference between "let" and "var"?
(39 answers)
Closed 4 years ago.
The question pop up in my head when I read example 6 in this post https://stackoverflow.com/a/111111/6359753
Will there ever be a difference between
// Example 1
let i;
var arr = [1,2,3]
for (i=0; i<arr.length; i++){
// do stuff
}
and
// Example 2
var arr = [1,2,3]
for (let i=0; i<arr.length; i++){
// do stuff
}
If they are the same, why are they the same?
In other words, I don't really understand let's scope. If declared outside the loop, are they scoped outside the loop? example 2's let clearly are scoped inside the for loop, but example 1 I'm not so sure.
If it is declared in the for loop, it is visible only in the loop's body. Outside of loop i is not visible.
var arr = [1,2,3];
for (let i=0; i<arr.length; i++) {
}
console.log(i);
If it is declared outside the for loop, the scope of the variable is the closest surrounded block {}.
let i;
var arr = [1,2,3];
for (i = 0; i < arr.length; i++) {
}
console.log(i);
No, scope wise they are not same.
In the first example, variable i is the global variable and can be accessed throughout the program. But in the second example the scope of i is local to the for loop only, thus i can not be accessed from outside of for loop.
Here is an article that explains the difference between var, let and const.
I gives a great overview of how JS handles variables behind the scenes.
It explains hoisting of variables, scope(which was your question) and how to avoid some pitfalls when using let and const.
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
My code is:
for (i = 0; i < 3; i++) {
elem[i].click(function(event) { alert(i); });
}
Unfortunately that does not work. Any idea how to make it alert the same i as the i in elem[i].
Thank you!
You should use let for defining variable i. Unlike var, variables defined by let are block scoped. As a result, they won't be overwritten after each iteration.
for (let i = 0; i < 3; i++) {
elem[i].click(function(event) { alert(i); });
}
By the way, when ES6 is available, it's generally a bad idea to use closures in this case. It's kind of overkill.
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
node.js newbie here. I'm looping through an array of objects, and setting a timeout for doing some ops using each object individually, the timeout for each objects also depends on some key-value within the object. The code is here:
for (var idx in arr) {
var obj = arr[idx];
interval = obj['key'];
setTimeout(function(){my_func(obj);}, interval);
}
Now what is failing here is that whenever a timeout occurs and the code block for my_func is called, it always acts on the last object in the array, probably because the variable 'obj' at that time points to it. How do I get around this? I am guessing I need a pass by reference, or something similar. Please point me in the right direction if I'm missing something here.
You will need to use closure for this:
for (var idx in arr) {
var obj = arr[idx];
(function( obj ){
interval = obj['key'];
setTimeout(function(){my_func(obj);}, interval);
})( obj );
}//for()