With setTimeOut, why it console 4, 5 times ? javascript [duplicate] - javascript

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 8 months ago.
If I run this code then it console 4 at 5 time, can anyone explain why it is happening ?
let number = 1;
for (var i=0; i<5; i++){
number=i;
setTimeout(()=>{
console.log(number)
},1000)
}
Also if I modify this to as below then output is 5 times 5 ?
for (var i=0; i<5; i++){
setTimeout(()=>{
console.log(i)
},1000)
}
And why it prints 0 to 4 when we use let like
for (let i=0; i<5; i++){
setTimeout(()=>{
console.log(i)
},1000)
}

Its a typical use case of var being functional scope ,every iteration of for loop shares the same value of var (doesn't creates a new scope as var being functional scope) which is kind of global in here
so when the last condition arrives i<5 i is already has become 4 ,and it is shared by every callback of setTimeout so they all prints 4 ,4 times
But in case of let a new scope is formed in every iteration ,as let being a block scope (for loop has a block scope)

Related

console.log always prints the highest index in a for loop [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 4 years ago.
Below is the simple jest test block in JavaScript, under the describe I've written a simple test to print the current index of the loop (until 5) of which it is put in. But the result is always Test 5
describe("Hello", async ()=>{
for(var i=0; i<5; ++i){
test(``Test ${i}``, async ()=>{
await console.debug("Test "+ i);
});
}
});
Can someone please clarify, how does it work?
Use let instead of var, let will preserve the scope for each async call. So in each loop, new values of i will be passed to your method and those values will stay preserved. In the case of var the variable i will be function scoped (that function being the one you use as callback in describe()) so when your asyn method resolves, you will see the value of i which exists inside your callback, since the loop would already have ended the value would be 5.
for(let i=0; i<5; ++i){
// dummy async method
setTimeout(() => {
console.log(i)
}, 2000)
}

Why do var and let produce different outputs in closures? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
What is the difference between "let" and "var"?
(39 answers)
Closed 5 years ago.
Consider these 2 snippets:
With let:
for(let i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 100)
}
With var:
for(var i = 0; i < 10; i++) { //HERE
setTimeout(function() {
console.log(i);
}, 100)
}
From my understanding, let only affects the scoping of the variables, so why are the outputs of the 2 loops should be same, so why does let print 0-9 and var prints 10 10 times?
Because you have a timeout in your loop, none of your logs are being called until the entire loop is finished.
After the loop is finished, the value of i is 10 if you use var.
But let is block scoped, meaning it's the same value anywhere in the loop, even in an async function like setTimeout (unless you manually change it inside the loop) - because the loop creates a new scope on each iteration, it's almost like each iteration creates a new "instance" of the i variable when you use let, whereas using var each loop is using the same instance of the i variable.

using setTimeout with var and let - different results [duplicate]

This question already has answers here:
What is the difference between "let" and "var"?
(39 answers)
Closed 5 years ago.
Why the following code returns 10 times 10 and print hey as first line?
for (var i = 0; i < 10; ++i) {
setTimeout(() => console.log(i), 0)
}
console.log('hey')
When if instead I use let I get properly the counting, but why the line hey is always printed first?
for (let i = 0; i < 10; ++i) {
setTimeout(() => console.log(i), 0)
}
console.log('hey')
My question actually contains two:
First why hey is printed first.
Why using let the counting is printed properly.
setTimeout() is an asynchronous function
console.log('hey')
won't wait for it to finish before printing, since JS is single threaded, it would wait for the program to run and then pick the setTimeout() from event queue
difference between let and var can be found in this answer. Basically since let has scope limited to the for loop, the setTimeout can refer to only 1 value of i. If we use var then it is function scope and each function would get the same value of i

its not printing 0,1,2,3,4,5...10 its printing 10 ten times [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
I am new to js
I thought below code will output 0,1,2,3,4,5,6,7,8,9 with a gap of 10 ms.
but it's not printing like that it's printing 10 ten times.
is it due to set a timeout or something else?
can you guys tell me why it's happening...it will help me so much with understanding js
for( var i=0; i< 10; i++) {
setTimeout(function(){
console.log(i);
}, 10);
}
It's because of closure, you should do something like that
for( var i=0; i< 10; i++) {
(function(j){
setTimeout(function(){ console.log(j); }, 10);
}(i));
}
This is basic javascript closure, you can read more here How do JavaScript closures work?
The problem is that the for loop finishes first, so at the end, i will equal 10. After that, the setTimeout functions will get called and when they check the value of i, they'll find it equal to the last value from the for loop which 10.
What I did is called an IIFE (Immediately Invoked Function Expression) which creates a new variable for the scope of the setTimeout function, so when the timeout comes, it finds its own variable that hasn't changed.

Why do functions defined in a loop all return the same value? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 7 years ago.
I'm confused by the following JavaScript code. I wrote a loop and defined a function inside the loop, but when I call a function defined in the loop, I only get 10 rather than the index.
Obviously, in the following code I abstracted out stuff that isn't relevant:
objectArray = [];
for (i = 0; i< 10; i++){
objectArray[i] = {};
}
for (i = 0; i< 10; i++){
objectArray[i].get_number = function(){
return i;
}
}
console.log(objectArray[5].get_number()); // returns 10 rather than 5
I always get 10 rather than i as expected.
It's because of JavaScript closure. The method objectArray[i].get_number has direct access to i (not a copy of i). The value of i lives on in memory because each method objectArray[i].get_number still has access to it. There's only one i, and when the loop iterates it, it increases by one. When a method objectArray[i].get_number accesses it, the loop has already run to completion, so it accesses the final value of i.

Categories