I have about 80 variables that I need to be accessible in multiple javascript functions. I know that using global variables is a bad practice, so what is the best way of avoiding using global variables? Should I just pass them as parameters every time I pass a function? That might be even worse declaring them as global variables, what should I do?
Asked
Active
Viewed 968 times
0
-
1There isn't enough information here to actually answer your question. Can you post your code? – Blender Jun 28 '13 at 03:01
-
2Create one big `Object`, and make them properties of that. For example: `var App = { property1: "whatever", property2: "whatever2" };`. Then, whenever you need them, you access them from anywhere like `App.property1 – Ian Jun 28 '13 at 03:04
-
1using [closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope#Nested_functions_and_closures) variables are a good idea – Arun P Johny Jun 28 '13 at 03:08
-
So the variables would all be initialized as fields in an object. I never thought about that. I will try that out. – Dylan Vander Berg Jun 28 '13 at 03:09
-
@user2297366 Yep, and there ends up being only **one** global item created. – Ian Jun 28 '13 at 03:11
-
@ArunPJohny So I should create one giant function that encloses my 20 other functions so that I will have one parent function that declares my variables and my current functions will be child functions that have access to the variables in the parent function? – Dylan Vander Berg Jun 28 '13 at 03:14
-
@user2297366 yes, if you are planning to use closure, you can use a iife model like `(function(){})();` and put all your code inside it, one drawback of this model is, even your functions will be in the local scope and then will be available in the global scope like in add a `onclick` handler to a element using the `onclick` attribure – Arun P Johny Jun 28 '13 at 03:16
-
@ArunPJohny So would it still work for one of the child functions to be called from an `onClick` in my html button? – Dylan Vander Berg Jun 28 '13 at 03:22
-
1@user2297366 Here's an example of both of our suggestions. Mine: http://jsfiddle.net/PE7K9/ . And ArunPJohny's: http://jsfiddle.net/yjU9X/ . Note that if you didn't declare `window.myFunc` with the `window.` part, it wouldn't be accessible by the click handler (and the second `alert` would show `undefined`) – Ian Jun 28 '13 at 03:23
-
@user2297366 still you can declare a function inside the closure scope using `window.myfunction` to make it available in the global scope and then you can use it as a handler in attributes like `onclick` – Arun P Johny Jun 28 '13 at 03:25
-
@ArunPJohny No problem, hopefully I captured what you meant correctly :) I was hoping this was a simple enough situation that I could show simple examples – Ian Jun 28 '13 at 03:30
-
@Ian I don't think that @ArunPJohny s code is working in your demo because `prop1` is returning `undefined` in the alert box. – Dylan Vander Berg Jun 28 '13 at 03:32
-
@user2297366 it is working that is why it is returning `undefined`, if you click on the text you can see the value – Arun P Johny Jun 28 '13 at 03:33
-
@user2297366 Well that was the point. The variables declared inside that closure are **not** accessible outside of the closure, **unless** you use `window.whatever` to declare them. That's why `myFunc` is accessible outside of it, and `prop1` is not. But within the closure, everything declared there is accessible inside. And when you click the div, it calls the `myFunc` function, which has access to `prop1`, so it correctly alerts it there – Ian Jun 28 '13 at 03:33
-
@Ian probably you should add these two as an answer with the demos.... – Arun P Johny Jun 28 '13 at 03:35
-
@ArunPJohny Well, HMR basically has already said both of our ideas in their answer, so I don't want to duplicate. I appreciate that though. Hopefully this helps the OP at least – Ian Jun 28 '13 at 03:36
-
@Ian so with your solution, when you reference the variable, you have to use `typeof` and with @ArunPJohny 's solution, I have to use `ObjName.var`. Are there any other key differences, as far as the functionality of the variables? – Dylan Vander Berg Jun 28 '13 at 03:40
-
@user2297366 Sorry, my use of `typeof` was only to demonstrate where/how the values are accessible. If `typeof` shows `undefined`, it means it's not accessible (in the example). If it shows the value, that means it's available in that place. Instead of referencing them as "Ian's solution" and "ArunPJohny's solution", just reference them as "god object solution" (the one that has `var App = {};`), and "closure solution" (the one that has `(function () { }());` – Ian Jun 28 '13 at 03:43
-
So if I would use the god object solution, I wouldn't even need to change the way that I reference my variables, I could just put my variables in an object and I don't need to touch the rest? – Dylan Vander Berg Jun 28 '13 at 03:58
-
@user2297366 There are several scenarios. With the god object solution, you have to reference the variables as properties, like `App.prop1`, instead of just using `prop1`. If you use the closure solution, you can use `prop1` **inside** of the closure...if you need access to it **outside** of the closure, you can declare it like `window.prop1 = "whatever";` and you'll have access to it **anywhere** using just `prop1`. The point is that you **shouldn't** need access to the stuff outside of the closure, so you should always be able to access it like `prop1` inside – Ian Jun 28 '13 at 04:10
-
@user2297366 variabe reference won't change when you wrap all your code in an anonymous function and create one big closure of your code: `(function(window,undefined){your code})(window)` If you have `onclick='myfunction'` in your html then you should export these funcitons with `window.myfunction=function(...` It would be better no not have any event handling defs in your html as they belong in your JavaScript code but that's another story. – HMR Jun 28 '13 at 04:10
-
@user2297366 Using the closure solution, it encapsulates all of your JavaScript in one place, allowing for local access to things inside and not leaking anything globally (unless you want to). Maybe it's just me, but I've been able to completely separate my JavaScript from my HTML and put it in a closure like this, therefore rarely needing access globally – Ian Jun 28 '13 at 04:13
-
@Ian I think I will go with the god object solution. If you put it in an answer, I would be happy to accept it as the correct answer. Thanks for all of your help. – Dylan Vander Berg Jun 28 '13 at 22:48
2 Answers
1
You can use namespaces:
myapp=myapp||{};
myapp.validators=myapp.validators||{};
myapp.validators.isNumber=function(){...
Try to create objects or object instances that have their variables and functions (properties and methods) declared in the object.
You can use object literal where there would be only one instance:
myapp.validators={
isNumber:function(){},
isDate:function(){}
}
Or when you need to create more than one instance you can use constructor functions:
myapp.controls.myButton=funciton(){
this.caption="hello world";
}
myapp.constrols.myButton.prototype.addEventHandler=function(){};
Declaring 80 variables in the global scope is usually a sign of bad design and your code would not play well with other code because you can have a conflict in variable names.
Something with a very low impact on your current code could be wrapping your code in a function (like jquery does) and create one big closure (like Arun mentioned):
(function(window,undefined){
//your code
})(window);
-
1
-
@Ian I seem to always get that wrong, either write myvar=value, or myvar:value; I have corrected the code. – HMR Jun 28 '13 at 03:17
-
I know you know the syntax, and I know you would've figured it out if this were real code, so I was just pointing it out :) I do the same thing sometimes – Ian Jun 28 '13 at 03:19
-
I get the functions nested inside an object part, but I am a little confused about the namespaces part. – Dylan Vander Berg Jun 28 '13 at 03:25
-
@user2297366 I'm pretty sure HMR is just referring to "nesting" (which is basically namespacing here...at least I think)...something like: http://jsfiddle.net/US4u7/ – Ian Jun 28 '13 at 03:29
-
@user2297366 Namespacing is a term used (in this case) for organizing your "code" in namespaces (putting them in objects in JavaScript). You could call it package if you're a Java developer. The reason my code checks if myapp exist and only creates it if it doesn't is because code can be arranged in several files so if validators create myapp and controls create a new one then myapp.validators would be gone. With the check it doesn't matter what file loads first. – HMR Jun 28 '13 at 03:38
-
So should my whole code be in the object field initializers? Sorry if I am not using correct terminology, I am a java developer. – Dylan Vander Berg Jun 28 '13 at 03:55
-
@user2297366 If your code works then try putting it in an anonymous function as suggested by Arun and under "low impact" in my answer. If you need to maintain the code or your code isn't finished yet try to use a more structured approach. Group your variables and functions and put them in objects (namespace them) If it's a lot of code then maybe put them in multiple files. You could look into typescript or closure compiler but that means a lot of learning time and I'm not sure if your JavaScript project is complex enough for you to spent so much time on it. – HMR Jun 28 '13 at 04:05
1
some ideas:
- Organize(encapsulate) those variables as some objects(functions) with namespace.
- Use closure. A closure is the local(private) variables for a function - kept alive after the function has returned.
- Write a method and take advantage of return value.

Anderson
- 2,496
- 1
- 27
- 41