Javascript for loop variable scope [duplicate] - javascript

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.

Related

question about scope, closures and Let variables [duplicate]

This question already has answers here:
setTimeout in for-loop does not print consecutive values [duplicate]
(10 answers)
JavaScript closure inside loops – simple practical example
(44 answers)
What is the difference between "let" and "var"?
(39 answers)
Closed 1 year ago.
I am reading about closures, and I found these small exercises that I solved by chance, but I don't understand why they work.
The exercise is :
for (var i = 0; i < 3; i++) {
setTimeout(function log() {
console.log(i); // What is logged?
}, 1000);
}
I get that 3 will be printed 3 times because the value captured by log() when the for() ends.
Additionally, it was asked how to fix it for the console to print 0,1,2, and I found (by chance, to be honest), that it works by doing :
for ( let i =0 ...
But I guess because Let is block scoped, but i don't really know how to explain it in simple words.
The variables defined with let are blocked scope which means once you go out of the bracket it loses its value and if you try to access it will throw you an error. So, when the for is running the, i present in the console.log() will store the value for it like 0,1,etc.
whereas in the var part the var will be stored in memory and when the timeout is about to expire it will access the variable i in the memory and print whatever is there for that variable at that time.

Why incrementor is printing 3 even condition is checking for less then 3? [duplicate]

This question already has answers here:
What is the difference between "let" and "var"?
(39 answers)
JavaScript closure inside loops – simple practical example
(44 answers)
How do JavaScript closures work?
(86 answers)
Closed 4 years ago.
for below code output will print "3" for 3 times, i.e updates same variable for 3 times
for(var k=0;k<3;k++){
setTimeout(()=>{
console.log(k)
},1000)
}
similarly if i use let instead of var 1,2,3
for(var k=0;k<3;k++){
setTimeout(()=>{
console.log(k)
},1000)
}
i know why it prints 0,1,2 as i is different every time. i'm just wondering why its printing 3 in case of var as condition is to checking for less then 3?
The above result is because, var defines variable globally, or locally to an entire function regardless of block scope.
let creates a variable declaration for each loop which is block level declaration. So basically it creates a scope within { }.
If you want to print using var keyword use self invoked functions :
for(var k=0;k<3;k++){
(function(k){
setTimeout(()=>{
console.log(k)
},1000)
})(k);
}
the function setTimeout will execute after the delay provided. The code execution doesn't stop since the javascript is based on concurrency model and event loop, so the execution continues till the delay provided. which in case, increment the k. Also, the post-increment operator will use the value before iteration. So, for last iteration the value of k is 3, but since we have given a delay, it would print 3 every time.

Is let the same used inside and outside a loop [duplicate]

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.

JS, dynamic callback function (i.e. dynamic constants), click example [duplicate]

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.

Explaining IIFE Inside Loop [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
How do JavaScript closures work?
(86 answers)
Closed 6 years ago.
I read this article, but I have some issues understanding it.
var funcs = [];
for (var i = 0; i < 3; i++) {
(function IIFE(arg) {
funcs[arg] = function output() {
console.log("My value: " + arg);
};
})(i);
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
How can I explain the mechanism of this snippet?
Start: i has value of 0. IIFE gets the value of i and stores it in arg.
funcs[0] just get assigned to a function named output.
second time, when i is 1, funcs[1] gets a totally new function? Is this false?
.....
The problem is here, How does funcs[0](); know that arg was 0? How things interact?
Function output() looks up and ask IIFE function to give the required value? right? Can someone say which illustration is correct?
By Providing this picture, for example, number 1, I mean, when funcs[0]() gets executed, output looks for arg, it doesn't find it, then goes to higher scope and finds it. each function has it's own IIFE, for example. I'n not sure how far are this from Javascript or even programming world, but help me get it!

Categories

Resources