views:

1616

answers:

8

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?

+2  A: 

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.

Adam Peck
Global variables are extremely evil in Javascript. -1.
Triptych
extremely extreme -1
annakata
+6  A: 

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);
}
Paul Stephenson
do not pollute the global namespace! your worst case fallback should be no more than creating an object property using a single custom global object
annakata
a 4th option I came up with, when all 3 of those didn't work for me. http://stackoverflow.com/questions/3531080/how-to-get-a-variable-returned-across-multiple-functions-javascript-jquery (see answer by Emile)
Emile
ps. pm on the link above, look for an unchecked answer by "Emile"
Emile
+1  A: 

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.

tvanfosson
A: 

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.

AnthonyWJones
aka: closures +1
annakata
-1. Not only is this not an example of currying, it's way too complicated an answer for the problem.
Triptych
@triptych: I disagree. this is a perfectly valid and interesting solution to this kind of problem, and is exactly currying (http://www.dustindiaz.com/javascript-curry/)
annakata
A: 

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.

Arthur Thomas
A: 

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 var(){
    alert(MyApp.color); // Alerts 'green'
}

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

Triptych
A: 

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.

Christoph
A: 

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"):

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

Emile