Very weird behavior when using "var" keyword in an ajax request

104 views Asked by At

I've been worrying about this for a while and I can't realize what's really happening. Explanation in code comments. There are 2 versions of an application, one of them throws weird results and the second one does the expected work.

var id = "test1";

$.post("http://fiddle.jshell.net/echo/json/", {"data": "data"}, function(a) {
     alert(id); // will throw undefined

     var id = "test2";
     alert(id); // will throw "test2" as expected
});

$.post("http://fiddle.jshell.net/echo/json/", {"data": "data"}, function(a) {
    alert(id); // will throw "test1" as expected

    id = "test2";
    alert(id); // will throw "test2" as expected
});

I'm not sure if it has something to do with ajax call, or an anonymous function, but this is just the way I discovered this so I better keep it there. Could somebody explain what am I missing? Why does it behave differently when I ommit the var keyword? You can try everything out here on jsFiddle

3

There are 3 answers

5
Adam Jenkins On BEST ANSWER

Cool, you discovered hoisting. MDN explains it as good as anyone:

Because variable declarations (and declarations in general) are processed before any code is executed, declaring a variable anywhere in the code is equivalent to declaring it at the top. This also means that a variable can appear to be used before it's declared. This behavior is called "hoisting", as it appears that the variable declaration is moved to the top of the function or global code.

Code sample from MDN link below:

bla = 2
var bla;
// ...

// is implicitly understood as:

var bla;
bla = 2;

You can see how this will result in the "weird behaviour":

alert(testId);
var testId = 2;

is equivalent to:

var testId;
alert(testId);
testId = 2;

Which brings me to the final bit of knowledge I can impart, always declare your variables at the top of your code blocks so this "weird behaviour" is coded into your programs (and never throws you off again):

function someFunction() {
   var
    firstVar,
    secondVar,
    thirdVar;

    //rest of your code statements here
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting

2
Daniel A. White On

Its called hoisting. var id is moved to the top of the function.

2
Andre Pena On

As the others said, it's hoisting. But just so you can have a clearer view of what is happening, the first code is actually executed like this:

var id = "test1";

$.post("http://fiddle.jshell.net/echo/json/", {"data": "data"}, function(a) {
     // this is because of hoisting
     var id = undefined;
     alert(id); // will throw undefined

     id = "test2";
     alert(id); // will throw "test2" as expected
});