Yes, this is another topic about global variables. I've searched quite a bit about them. But most of the topics is just about WHY not to use global variables and I'm convinced that I shouldn't, and I am more wondering HOW not to use them, and that I'm still unsure about.
I am working on a project, and it works wonders, but I am using about 50 global variables at the moment and that number keeps rising. Right now I've split things up in multiple .js files. Like load_chunks.js, load_images.js, render_map.js, player_actions.js, input.js, to spread the functions based on what they are for. And I've put all global variables inside settings.js.
Currently I use these global variables for these reasons:
1. Calculation based on some other global variables that doesn't change much or at all after loading. By doing this once, and store it in a global variable, I no longer have to repeat the calculation ever again. If I didn't store it in a (global) variable, Javascript would have to do the calculation many times each second, in some cases even up to few thousand times per second.
2. When the global variable is needed in many functions. Like there's this World-variable, that I use to hold data for the appearance of the world. This variable is a multidimensional array. World[y][x] for example. Load_chunks.js adds more data to this variable, or remove data if you move too far. This variable is also needed in render_map.js, to create the map, and it's also needed in player_action.js, to see if you can step on that particular location.
3. Settings; So a number in a variable that remains the same unless I change them in my script. Instead of going through my scripts, and change the numbers manually after a long search and thinking what the number was, I've put that number in 1 variable and call that variable numerous times in my scripts. These variables are in some cases also needed elsewhere.
Also I like to mention that I don't use classes, and perhaps for that reason I never got around using global variables...?
So how do I get rid of my global variables, or shouldn't I?
I hope you can show me or write for me a script example (or a link to it) of how I should do it. That's the fastest way I learn.
Answer
Put Variables Inside a Function Closure
One common way to eliminate a global is to put is inside a function closure:
(function() {
var declareYourFormerGlobalHere = 0;
// put all code that uses the variable inside this closure
// the variable persists for this code to use, but is not actually global
})();
Here's are some usage examples:
// example keeping track of a running count and a cached DOM element
(function() {
var cntr = 0, obj = document.getElementById("test");
setInterval(function() {
++cntr;
if (obj.value < cntr) {
// do something
} else {
// do something else
}
}, 1000);
})();
// example keeping track of a time of last click
(function() {
var timeOfLastClick = 0;
document.getElementById("run").addEventListener("click", function(e) {
var now = new Date().getTime();
// only process click if more than 2 seconds have passed since last click
if (now - timeOfLastClick > 2000) {
// OK to process the click
}
timeOfLastClick = now;
});
})();
Sometimes, you can actually enclose all your code or nearly all your code in a single closure like this and all your current globals become local variables inside the closure rather than actual globals. jQuery uses this technique to declare lots of persistent variables it uses, none of which are actual globally scoped.
Use a Single Namespace Object
Another common method of reducing the number of globals is to use the namespace concept. In this concept, you declare a single global object and put other persistent variables as properties of this single global object. This still leaves you with a single global variable, you can have as many properties as you want off this single global.
var myNamepaceObject = {};
myNamespaceObject.var1 = "foo";
myNamespaceObject.var2 = "whatever";
This technique is also used by jQuery as all globally accessible functions that jQuery offers are available off the jQuery object such as jQuery.extend()
or jQuery.contains()
. jQuery exposes a single global variable and many other globally accessible functions are then available as properties of that single global object.
Module Pattern
What is commonly known as the "module pattern" uses a combination of these above two techniques, where you have a single module variable that both uses properties and closure variables.
var MODULE = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// ...
};
return my;
}());
You can see a discussion of this design pattern in these references:
JavaScript Module Pattern: In-Depth
Learning Javascript - The Module Pattern
JavaScript module pattern with example
No comments:
Post a Comment