Accessing variables from other functions without using global variables

JavascriptGlobal Variables

Javascript Problem Overview


I've heard from a variety of places that global variables are inherently nasty and evil, but when doing some non-object oriented Javascript, I can't see how to avoid them. Say I have a function which generates a number using a complex algorithm using random numbers and stuff, but I need to keep using that particular number in some other function which is a callback or something and so can't be part of the same function.

If the originally generated number is a local variable, it won't be accessible from, there. If the functions were object methods, I could make the number a property but they're not and it seems somewhat overcomplicated to change the whole program structure to do this. Is a global variable really so bad?

Javascript Solutions


Solution 1 - Javascript

I think your best bet here may be to define a single global-scoped variable, and dumping your variables there:

var MyApp = {}; // Globally scoped object

function foo(){
    MyApp.color = 'green';
}

function bar(){
    alert(MyApp.color); // Alerts 'green'
} 

No one should yell at you for doing something like the above.

Solution 2 - Javascript

To make a variable calculated in function A visible in function B, you have three choices:

  • make it a global,
  • make it an object property, or
  • pass it as a parameter when calling B from A.

If your program is fairly small then globals are not so bad. Otherwise I would consider using the third method:

function A()
{
    var rand_num = calculate_random_number();
    B(rand_num);
}

function B(r)
{
    use_rand_num(r);
}

Solution 3 - Javascript

Consider using namespaces:

(function() {
    var local_var = 'foo';
    global_var = 'bar'; // this.global_var and window.global_var also work
    
    function local_function() {}
    global_function = function() {};
})();

Both local_function and global_function have access to all local and global variables.

Edit: Another common pattern:

var ns = (function() {
    // local stuff
    function foo() {}
    function bar() {}
    function baz() {} // this one stays invisible

    // stuff visible in namespace object
    return {
        foo : foo,
        bar : bar
    };
})();

The returned properties can now be accessed via the namespace object, e.g. ns.foo, while still retaining access to local definitions.

Solution 4 - Javascript

What you're looking for is technically known as currying.

function getMyCallback(randomValue)
{
    return function(otherParam)
    {
        return randomValue * otherParam //or whatever it is you are doing.
    }

}

var myCallback = getMyCallBack(getRand())

alert(myCallBack(1));
alert(myCallBack(2));

The above isn't exactly a curried function but it achieves the result of maintaining an existing value without adding variables to the global namespace or requiring some other object repository for it.

Solution 5 - Javascript

I found this to be extremely helpful in relation to the original question:

Return the value you wish to use in functionOne, then call functionOne within functionTwo, then place the result into a fresh var and reference this new var within functionTwo. This should enable you to use the var declared in functionOne, within functionTwo.

function functionOne() {
  var variableThree = 3;
  return variableThree;
}

function functionTwo() {
  var variableOne = 1;
  var var3 = functionOne();

  var result = var3 - variableOne;

  console.log(variableOne);
  console.log(var3);
  console.log('functional result: ' + result);
}

functionTwo();

Solution 6 - Javascript

If another function needs to use a variable you pass it to the function as an argument.

Also global variables are not inherently nasty and evil. As long as they are used properly there is no problem with them.

Solution 7 - Javascript

If there's a chance that you will reuse this code, then I would probably make the effort to go with an object-oriented perspective. Using the global namespace can be dangerous -- you run the risk of hard to find bugs due to variable names that get reused. Typically I start by using an object-oriented approach for anything more than a simple callback so that I don't have to do the re-write thing. Any time that you have a group of related functions in javascript, I think, it's a candidate for an object-oriented approach.

Solution 8 - Javascript

Another approach is one that I picked up from a Douglas Crockford forum post(http://bytes.com/topic/javascript/answers/512361-array-objects). Here it is...

Douglas Crockford wrote:

Jul 15 '06

"If you want to retrieve objects by id, then you should use an object, not an array. Since functions are also objects, you could store the members in the function itself."

function objFacility(id, name, adr, city, state, zip) {

    return objFacility[id] = {

        id: id,
        name: name,
        adr: adr,
        city: city,
        state: state,
        zip: zip

    }
}

objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);

"The object can be obtained with"

objFacility.wlevine

The objects properties are now accessable from within any other function.

Solution 9 - Javascript

I don't know specifics of your issue, but if the function needs the value then it can be a parameter passed through the call.

Globals are considered bad because globals state and multiple modifiers can create hard to follow code and strange errors. To many actors fiddling with something can create chaos.

Solution 10 - Javascript

You can completely control the execution of javascript functions (and pass variables between them) using custom jQuery events....I was told that this wasn't possible all over these forums, but I got something working that does exactly that (even using an ajax call).

Here's the answer (IMPORTANT: it's not the checked answer but rather the answer by me "Emile"):

https://stackoverflow.com/questions/3531080/how-to-get-a-variable-returned-across-multiple-functions-javascript-jquery

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohn RichardsonView Question on Stackoverflow
Solution 1 - JavascriptKenan BanksView Answer on Stackoverflow
Solution 2 - JavascriptPaul StephensonView Answer on Stackoverflow
Solution 3 - JavascriptChristophView Answer on Stackoverflow
Solution 4 - JavascriptAnthonyWJonesView Answer on Stackoverflow
Solution 5 - Javascriptgav_aus_webView Answer on Stackoverflow
Solution 6 - JavascriptAdam PeckView Answer on Stackoverflow
Solution 7 - JavascripttvanfossonView Answer on Stackoverflow
Solution 8 - JavascriptJoel ErenbergView Answer on Stackoverflow
Solution 9 - JavascriptArthur ThomasView Answer on Stackoverflow
Solution 10 - JavascriptKyle CureauView Answer on Stackoverflow