Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript variable binding and loop

Consider such loop:

for(var it = 0; it < 2; it++) {     setTimeout(function() {         alert(it);     }, 1); } 

The output is:

=> 2 => 2 

I would like it to be: 0, 1. I see two ways to fix it:

Solution # 1.

This one based on the fact that we can pass data to setTimeout.

for(var it = 0; it < 2; it++) {     setTimeout(function(data) {         alert(data);     }, 1, it); } 

Solution # 2.

function foo(data) {     setTimeout(function() {         alert(data);     }, 1); }  for(var it = 0; it < 2; it++) {     foo(it); } 

Are there any other alternatives?

like image 205
alex2k8 Avatar asked Nov 04 '09 20:11

alex2k8


People also ask

What is variable binding in JavaScript?

A binding in JavaScript is the formal terminology for what a lot of people refer to as a variable. In ES2015+, a variable can be defined with the let keyword, but you can also define constant with the const keyword. A binding could refer to either a variable or a constant.

What are the 3 parts of a for loop in JavaScript?

JavaScript for loop is used to execute code repeatedly. for loop includes three parts: initialization, condition and iteration.

What is the loop in JavaScript?

Loops are used in JavaScript to perform repeated tasks based on a condition. Conditions typically return true or false . A loop will continue running until the defined condition returns false .


2 Answers

Not really anything more than the two ways that you have proposed, but here's another

for(var it = 0; it < 2; it++) {     (function() {         var m = it;            setTimeout(function() {             alert(m);         }, 1);     })();  } 

Essentially, you need to capture the variable value in a closure. This method uses an immediately invoked anonymous function to capture the outer variable value it in a local variable m.

Here's a Working Demo to play with. add /edit to the URL to see the code

like image 179
Russ Cam Avatar answered Sep 20 '22 10:09

Russ Cam


With the let keyword you can get around this completely:

for(let it = 0; it < 2; it++) {     setTimeout(function() {         alert(it);     }, 1); } 
like image 45
tbondwilkinson Avatar answered Sep 20 '22 10:09

tbondwilkinson