With the code you have provided test will still be in scope inside the callback xhr will not be, (other than xhr. ResponseText being passed in as data Updated from comment : Assuming your code looks something like this: for (var test in testers) getFileContents("hello"+test+". Js", function(data) { alert(test); }); } As this script runs test will be assigned the values of the keys in testers getFileContents is called each time, which starts a request in the background.As the request finishes, it calls the callback test is going to contain the FINAL VALUE from the loop, as that loop has already finished executing There is a technique you can use called a closure that will fix this sort of problem.
You can create a function that returns your callback function, creating a new scope you can hold onto your variables with: for (var test in testers) { getFileContents("hello"+test+". Js", (function(test) { // lets create a function who has a single argument "test" // inside this function test will refer to the functions argument return function(data) { // test still refers to the closure functions argument alert(test); }; })(test) // immediately call the closure with the current value of test ); } This will basically create a new scope (along with our new function) that will "hold on" to the value of test Another way of writing the same sort of thing: for (var test in testers) { (function(test) { // lets create a function who has a single argument "test" // inside this function test will refer to the functions argument // not the var test from the loop above getFileContents("hello"+test+". Js", function(data) { // test still refers to the closure functions argument alert(test); }); })(test); // immediately call the closure with the value of `test` from `testers` }.
With the code you have provided test will still be in scope inside the callback. Xhr will not be, (other than xhr. ResponseText being passed in as data.
Updated from comment: Assuming your code looks something like this: for (var test in testers) getFileContents("hello"+test+". Js", function(data) { alert(test); }); } As this script runs, test will be assigned the values of the keys in testers - getFileContents is called each time, which starts a request in the background. As the request finishes, it calls the callback.
Test is going to contain the FINAL VALUE from the loop, as that loop has already finished executing. There is a technique you can use called a closure that will fix this sort of problem. You can create a function that returns your callback function, creating a new scope you can hold onto your variables with: for (var test in testers) { getFileContents("hello"+test+".
Js", (function(test) { // lets create a function who has a single argument "test" // inside this function test will refer to the functions argument return function(data) { // test still refers to the closure functions argument alert(test); }; })(test) // immediately call the closure with the current value of test ); } This will basically create a new scope (along with our new function) that will "hold on" to the value of test. Another way of writing the same sort of thing: for (var test in testers) { (function(test) { // lets create a function who has a single argument "test" // inside this function test will refer to the functions argument // not the var test from the loop above getFileContents("hello"+test+". Js", function(data) { // test still refers to the closure functions argument alert(test); }); })(test); // immediately call the closure with the value of `test` from `testers` }.
What if the first block of code is in another . Js file, included using the tag? Would it still work?
– Chetan May 24 '10 at 22:56 Yes. "Enclosing Function Scope" means that your callback function extends its scope from the function it is declared in (which has the test variable). If the variables are not declared inside of any function, they will be in the "global scope".
– gnarf May 24 '10 at 23:00 Final question: If test is changing value inside of a for each loop, how come the last value of test is the only value that is printed by the alert(test); code? And how do I fix it so that it prints the value of test that was set during the call to getFileContents? – Chetan May 24 '10 at 23:05 Please refer to the question edits for more clarification on the above question.
– Chetan May 24 '10 at 23:13 @Chetan - updated with notes on using a closure to solve your loop issue. – gnarf May 24 '10 at 23:18.
JavaScript uses lexical scoping, which basically means that your second code example will work just like how you intend it to work. Consider the following example, borrowed from David Flanagan's Definitive Guide1: var x = "global"; function f() { var x = "local"; function g() { alert(x); } g(); } f(); // Calling this function displays "local" Also keep in mind that unlike C, C++ and Java, JavaScript does not have block-level scope. In addition, you may also be interested in checking out the following article, which I highly recommend: Mozilla Developer Center: Working with Closures 1 David Flanagan: JavaScript - The Definitive Guide, Fourth Edition, Page 48.
In this scenario, test will be resolved as you'd expect it, but the value of this might be different. Normally, to preserve the scope, you would make it a parameter to the asynchronous function like so: function getFileContents(filePath, callbackFn, scope) { var xhr = new XMLHttpRequest(); xhr. Onreadystatechange = function() { if (xhr.
ReadyState == 4) { callbackFn. Call(scope, xhr. ResponseText); } } xhr.
Open("GET", chrome.extension. GetURL(filePath), true); xhr.send(); } //then to call it: var test = "lol"; getFileContents("hello. Js", function(data) { alert(test); }, this).
Javascript callback is structured (without quotes):. Structure javascript callback.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.