Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scope of variables in JavaScript callback functions

Tags:

I expected the code below to alert "0" and "1", but it alert "2" twice. I don't understand the reason. Don't know if it is a problem of jQuery. Also, please help me to edit title and tags of this post if they are inaccurate.

<html>     <head>         <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>         <script type="text/javascript">             $(function() {                 for (var i=0; i<2; i++) {                     $.get('http://www.google.com/', function() {                         alert(i);                     });                 }             });         </script>     </head>     <body>     </body> </html> 
like image 342
Ethan Avatar asked May 17 '10 23:05

Ethan


People also ask

What are the scope of a variable in JavaScript?

JavaScript variables have only two scopes. Global Variables − A global variable has global scope which means it can be defined anywhere in your JavaScript code. Local Variables − A local variable will be visible only within a function where it is defined. Function parameters are always local to that function.

Can I return value from callback function JavaScript?

When a callback function completes execution, it returns any return value that it might have to the DataBlade API, which invoked it.


2 Answers

You're sharing the single i variable among all of the callbacks.

Because Javascript closures capture variables by reference, the callbacks will always use the current value of i. Therefore, when jQuery calls the callbacks after the loop executes, i will always be 2.

You need to reference i as the parameter to a separate function.

For example:

function sendRequest(i) {     $.get('http://www.google.com/', function() {         alert(i);     }); }  for (var i = 0; i < 2; i++) {     sendRequest(i); } 

This way, each callback will have a separate closure with a separate i parameter.

like image 113
SLaks Avatar answered Sep 25 '22 14:09

SLaks


Alternative to SLaks' answer

$(function() {     for (var i=0; i<2; i++) {         $.get('http://www.google.com/', function(i) {             return function() { alert(i); }         }(i));     } }); 
like image 35
Tomalak Avatar answered Sep 25 '22 14:09

Tomalak