Variable Scope in Modular Javascript?

The problem is that you actually have two different references, the variable string1 within the closure of the anonymous function that you invoke to create namespace. Base and namespace.Base. String1 which is on the object returned from that anonymous function.

Your assignment of the variable string1 to the object property string1 is a one-time set, not a live reference. Further modification of the variable string1 will not affect the object property. Here's what you want.

Up vote 2 down vote favorite share g+ share fb share tw.

Sorry if this has been answered already, but I could not find an appropriate answer on here. I've started writing my javascript code in a modular style lately and I have a question regarding how module variable scope works. The following code gives me a conflicting answer.

I have a module named Base that declares two strings and an array. It also has a function called fetchData that uses the jQuery getJSON shortcut to set these variables with server data. Unfortunately when I ask for Base's string1 or string2, I get undefined.

I understand that this is probably due to the fact that I have it set their values two functions deep (inside the AJAX callback and inside fetchData) and the scope limits it from seeing Base. String1 and Base. String2.

However, when I look at Base. Array1 from outside the module, it's set to the appropriate data I pulled from the server, even though it's set from the same scope as the strings. Here's the code: namespace.

Base = (function(){ var string1, string2, array1 = ; function fetchData(){ $. GetJSON('backendScript. Php', function(data){ string1 = data.

String1; string2 = data. String2; arrayCount = data.arr. Length; for(var I = 0; I Arri; } }) } return{ fetchData: fetchData, string1: string1, string2: string2, array1: array1 } })(); If I change string1 = data.

String1; to namespace.Base. String1 = data. String1; it works like I want.

So my question is, why is array1 set correctly when it's set from the same scope as the strings? Also, what is the remedy for setting module-level variables from within the module's functions without having to give a global path (e.g. Namespace.Base. String1)?

Javascript scope link|improve this question asked Nov 4 '10 at 3:39Dan154.

Remember to upvote all answers which are of help to you. Check the one which best answers your question. If none are "check-worthy" then just do the upvotes for all of the helpful answers.

– Larry K Nov 4 '10 at 15:55 I'm new here, so I'll upvote as soon as I have 15 reputation. – Dan Nov 5 '10 at 0:46 Hmmm, good point. Welcome to Stack Overflow.

– Larry K Nov 6 '10 at 23:53.

The problem is that you actually have two different references, the variable string1 within the closure of the anonymous function that you invoke to create namespace. Base, and namespace.Base. String1, which is on the object returned from that anonymous function.

Your assignment of the variable string1 to the object property string1 is a one-time set, not a live reference. Further modification of the variable string1 will not affect the object property. Here's what you want: namespace.

Base = (function() { var my = { string1: null, string2: null, array1: , fetchData: function () { $. GetJSON('backendScript. Php', function(data){ my.

String1 = data. String1; my. String2 = data.

String2; var arrayCount = data.arr. Length; for (var I = 0; I Arri; } }); } }; return my; })(); Now the local, but public, members of namespace. Base are in the object my.

You can create private variables using var within the anonymous function, or create more public properties by adding them to my.

Thanks! I can understand how my variables were being returned before being set by fetchData. I was incorrectly thinking of them as live references or like properties of an object.

I'm beginning to think that the module pattern isn't worth using versus creating things as objects. I understand the concept of having private variables and choosing which variables to allow access through an API (the return), but it seems that to create dynamic variables I have to use the object pattern anyway. – Dan Nov 4 '10 at 8:41 Also, is creating an object named "my" a standard practice when creating modules?

I seem to remember seeing that before and not completely understanding it. – Dan Nov 4 '10 at 8:42 I often use my for this purpose. Sometimes that or other terms are used.

I think my is a bit clearer. It's true that the module pattern is imperfect, since you still have to use objects to keep local references to public properties. It's up to you whether you use it or not, but the private properties are sometimes handy to have.

– bcherry Nov 4 '10 at 18:29.

I would be a good idea to get familiar with closures and how they work: stackoverflow.com/questions/111102/how-d....

Your "scope" issue is not actually a scope issue. The issue is that arrays are pointers to their data, strings are not. Namespace.

Base is set to the results (returned value) of the anonymous function. -- It is set to be an object containing a function ref (fetchData), two empty strings and an array. If you later call the fetchData function, then it will change the contents of array1.

But it will also create two new strings (from data. String1 and data. String2).

The old values of string1 and string2 (which are namespace.Base. String1 and namespace.Base. String2) are not changed.

So they are left as empty strings (not what you want). Example of this. Try it in Firebug-- s1 = "Hi"; s2 = s1; // s2 => "Hi" s1 = "Bye" alert(s2); // *** s2 is still "Hi", it was not changed!

// But arrays are different: a1 = "Hi"; a2 = a1; a10 = "Bye"; alert(a20); // a20 is now "Bye" Added: Asynch Timing error Also, note that your code is wrong as written since you're not giving the caller any way to know when the Ajax call has completed: namespace.Base.fetchData(); // starts the Ajax call via getJSON method var a = namespace.Base. Array1; // ERROR! The value of namespace.Base.

Array1 is // indeterminate since you don't know if the // the Ajax request has completed yet or not! You appear to be trying to convert the asynchronous Ajax call (which invokes a callback function once the answer has been received from the remote server) into a synchronous call which will not return until the results have been received. This is a really bad idea.

(If you want to know more, ask another question in SO. ).

Thanks! Beginning to understand closures better, but I was also unaware of the fact that arrays work that way... very insightful example. – Dan Nov 4 '10 at 7:35.

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.

Related Questions