Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 255
Martin. Avatar asked Dec 15 '22 13:12

Martin.


2 Answers

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

like image 53
Adam Avatar answered Feb 24 '23 12:02

Adam


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
});
like image 35
André Pena Avatar answered Feb 24 '23 13:02

André Pena