Mailing List Archive


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [tlug] Variable scope in Javascript driving me nuts



>> my function()
>> {
>>    var valid = false;
>>    string = JSON.stringify(data);
>>    $.post('jsonhandler.php', {JSON: string}, checkResult, "json");
>>    function checkResult(jsonDataReceived)
>>    {
>>       valid = jsonDataReceived.valid;
>>       console.log ("jsonDataReceived.valid = " + jsonDataReceived.valid);
>>       console.log ("valid inside checkResult = " + valid);
>>    }
>>    console.log ("valid OUTSIDE checkResult = " + valid);
>>    return valid;
>> }
>>
>> When I run this, this is what I see in the console log:
>>
>> valid OUTSIDE checkResult = false
>> jsonDataReceived.valid = true
>> valid inside checkResult = true

That makes sense.

>> Shouldn't what happens inside the checkResult function set "valid" to
>> true before I get to the "return valid" part?

As Philipp pointed out, checkResult is called asynchronously. So the end
of my_function() is reached before checkResult() is called.

Yes, $.ajax() supports synchronous, see this thread, which also points
out the disadvantage - your browser will lock up waiting:
http://stackoverflow.com/questions/133310/how-can-i-get-jquery-to-perform-a-synchronous-rather-than-asynchronous-ajax-req

Async thinking is harder, but do it wherever you can.


Romeo wrote:
> Just a guess but it looks like you're setting 'var valid = false;' inside a
> function as a local variable. That's what 'var' does in javascript I think.

Yes.

> Then inside your inner checkResult function it looks like you're setting
> 'valid' as a global function by not having any 'var' in front of it. So the
> checkResult's 'valid' variable is a global var and the 'my function()',
> 'valid' var is a local variable. You could try making them both global or
> probably better yet, just pass the value back out of the function.

No. This is the traditional programming language way of thinking.
Javascript uses what they call "closures", which means a function has
the ability to reference all variables in its scope at the point of
declaration.

When you reference a variable called "valid" in checkResult it first
checks the functions local variables it finds none. So it goes up to the
closure scope and finds "valid" there. If it didn't find it there it
would look in the global scope. And if it didn't find it there it would
create a new local (though you might get a warning about not using the
"var" keyword).

This always confuses me too, so my first choice is to find and copy
working code and not think about it. My second choice is to explicitly
pass around the variables I want to use, or use globals. This is less
efficient than doing it the proper Javascript way, but at least I can
understand my code :-).

Darren


-- 
Darren Cook, Software Researcher/Developer

http://dcook.org/gobet/  (Shodan Go Bet - who will win?)
http://dcook.org/work/ (About me and my work)
http://dcook.org/blogs.html (My blogs and articles)


Home | Main Index | Thread Index

Home Page Mailing List Linux and Japan TLUG Members Links