I'm trying to be good, I really am, but I can't see how to do it :)
Any advice on how to not use a global here would be greatly appreciated. Let's call the global G.
Function A
Builds G by AJAX
Function B
Uses G
Function C
Calls B
Called by numerous event handlers attached to DOM elements (type 1)
Function D
Calls B
Called by numerous event handlers attached to DOM elements (type 2)
I can't see how I can get around using a global here. The DOM elements (types 1 & 2) are created in other functions (E&F) which are unconnected with A. I don't want to add G to each event handler (because it's large and there's lots of these event handlers), and doing so would require the same kind of solution as I'm seeking here (i.e., getting G to E&F).
The global G, BTW, is an array that is necessary to build other elements as they, in turn, are built by AJAX.
I'm not convinced that a singleton is real solution, either.
Thanks.
Stick everything in one big immediately-executing function, of course!
(function() {
// Your code goes here
})(); // Called right away
You can put anything in there and it will be accessible to anything in a narrower scope, but they still won't be global.
Also, if yours is the only file, stop avoiding globals because there's really no harm unless you're making some kind of reusable component.
I dunno if this is an option?
Function Everything() {
var G
Function A
Builds G by AJAX
Function B
Uses G
Function C
Calls B
Called by numerous event handlers attached to DOM elements (type 1)
Function D
Calls B
Called by numerous event handlers attached to DOM elements (type 2)
}();
Don't worry about passing G in the event. It's just a reference to the actual object, not a copy, so it wouldn't cause memory issues. Functions, objects, and arrays are passed as references.
What happens if one of the event handlers (that relies on G) is fired before you've received the AJAX response? To solve this problem, and to bind G to B by closure, you could try rigging up the event handlers in the AJAX callback:
function A() {
ajaxLoad(function(G) {
attachEvents1(C);
attachEvents2(D);
function B() {
G.use();
}
function C() {
B();
}
function D() {
B();
}
});
}
You're not giving us a lot of information to know what the best alternatives are, but here are some general types of options:
Ajax Results Passed as Function Argument
Function A() {
Builds G by AJAX
B(G)
}
Function B(g) {
Uses g
}
Since, the timing of G is such that it can't be used until the success handler in A is called anyway, then perhaps you just pass it to B as a parameter and don't need it as a global.
DOM Elements Retrieved Upon Demand
For the DOM elements, there is typically no requirement to store DOM element references in javascript variables. If you give them appropriate IDs, then you can fetch them upon demand whenever needed with document.getElementById("idName")
.
If you really need persistent variables available across numerous events and functions, then you have two options:
Self Executing Function Closure to Share Persistent Data without Globals
You can store them inside a self executing function closure:
(function() {
var G = [];
Function A
Builds G by AJAX
Function B
Uses G
})();
Single Global Object
Create a single true global that you then store your other data off as properites:
var myMainGlobal = {};
myMainGlobal.G = [];
myMainGlobal.A = function() {
Builds myMainGlobal.G by AJAX
}
myMainGlobal.B = function() {
Uses myMainGlobal.G
}
This, at least only creates one actual top level global symbol, while letting you have as much global data as you need.