Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
When is it GOOD to declare a global variable in JavaScript? Typical advice concerning global variables includes:
I sometimes encounter situations where it is critical that the value of a variable is available for the duration of the activity of the user. For example, knowing the state of which page is open. Another situation is when there is a long process with lots of smaller functions, but some value needs to be maintained throughout the process. Rather than passing an argument from function to function to function, and hope it doesn't get to confusing, just create a global variable.
In general, it's bad practice to declare global variables.
Can cause problems with "Namespace Pollution".
Duplicate variable declarations of the same name inside and outside of a function.
Global variables are slower to look up than local variables.
It's easy to forget that you declared the global variable, because it's out of site from the current code you are working on.
Tracking and debugging a global variable is hard.
Asynchronous use of the global variable could cause concurrency issues.
Situations where it would be good to declare a global variable?
A constant that has a lot of characters in it, that is used a lot. Reduce the size of overall code.
Saving the state of the current condition of something that must be monitored, and available at all times to more than one function.
It seems to me that the requirements would be:
High usage and/or
Required by at least two different functions that are outside the scope of each other.
Examples:
Object with many characters:
var dc = document;
var isTheMenuDisplayed = dc.getElementById('MainMenu').style.display;
Monitor Current State:
What page is currently displayed:
/* The state of what page is currently display, must be available to
the entire application at all times.
Variable is declared outside of a function enclosure.
*/
var whichPageDisplayed = '';
function changePage(pageNameToOpen) {
if (whichPageDisplayed === 'home') {
close the home page;
open the new page;
//Make sure to record what the new current open page is
whichPageDisplayed = pageNameToOpen;
};
I'm looking for reasons about when it's GOOD to use a global variable.
If global variables are considered always bad, then how do I deal with the above two situations without a global variable?
The "Asynchronous use of the global variable could cause concurrency issues" reason shouldn't be exclusive to global variables. Asynchronous use of anything could cause concurrency issues, so I don't see how that is an argument against global variables.
The "It's easy to forget that you declared the global variable, because it's out of site from the current code you are working on" reason seems like a coding discipline issue. If I saw that there was no var = thisVar statement anywhere to be found in that section of code, I'd think to myself, "Maybe I declared it as a global variable?". Then I'd do a search to find it.
"Tracking and debugging a global variable is hard" I have a "Search All Files" option in my code editor. It searches all the files, and shows me every line of code where the search found a match. It's not that hard. Depending on what browser and what developer tools I'm using, an error msg may show me the exact line of code where the error came from.
Reducing the overall code size isn't a valid reason. Minifiers will knock it down. Besides, if you have something like your example of dc.getElementById('MainMenu').style.display, you want a method to help you. Such as getDisplayStyle('MainMenu'). Doing that is just good practice, as it allows you to keep the logic in one spot.
Saving state isn't really a valid reason either. Keep your code in modules. For example, your code turned into something a bit "better":
PageState = {
changePage: function (pageNameToOpen) {
if(this._currentPage == 'home') {
/*******/
}
this._currentPage = pageNameToOpen;
},
getCurrentPage: function () {
return this._currentPage;
}
};
PageState.changePage(pageNameToOpen);
The only times you should consider a global variable is if a library requires it, or if you need to setup configuration options on something before that "something" exists (and you are not using AMD type modules). For example, one of the popular WYSIWYG editors out there looks specifically for a global variable that defines some constants for setup.
Basically, for almost every possible usage of global variables, there is counter argument for wrapping it in a module of some sort.
Related
How do I create a variable to use in my text using a Qualtrics survey in multiple questions? I am not using any embedded data or making variations. The variable would be for the sole purpose of editing future drafts of my survey more efficiently. For example I want something like:
myvar = 100
Q1. If you have %myvar% and I take away 50 how much is left?
Q2. If you have %myvar% and I give you 70 how much do you get?
...
The more thorough the explanation the better!
You don't need any JavaScript for this. What you want to do is very easy in Qualtrics.
First, at the beginning of your survey flow assign a value to an embedded data field:
myvar = 100
Then pipe the value into your question text like:
Q1. If you have ${e://Field/myvar} and I take away 50 how much is left?
This Qualtrics Community answer might help you:
Add a function to the Look & Feel header that sets and returns the variable. Call the function from the JS in your questions.
This support article implies you can add JavaScript to any question that can set global variables, however it isn't recommended:
As with any implementation of JavaScript, we recommend abstaining from global variable creation as it can collide with existing functionality on the page.
Here's the workflow they describe (the below images are from the article):
Click "Add JavaScript" in the settings dropdown on a question, and enter your (global variable assignment) code in one of these functions:
addOnload() – Executed when the page is loaded.
addOnReady() – Executed when the page is fully displayed.
addOnUnload() – Executed when a page is unloaded (when the page is left).
As an aside, here's a good answer from Brian Rasmussen explaining the problems with global variables:
The problem with global variables is that since every function has access to these, it becomes increasingly hard to figure out which functions actually read and write these variables.
To understand how the application works, you pretty much have to take into account every function which modifies the global state. That can be done, but as the application grows it will get harder to the point of being virtually impossible (or at least a complete waste of time).
If you don't rely on global variables, you can pass state around between different functions as needed. That way you stand a much better chance of understanding what each function does, as you don't need to take the global state into account.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I want to create a globally-accessible library myLib in Javascript. My library should do the following
Keep a somewhat persistent variable myLib.tax.
-- It should survive through the handling of a typical browser user event, at least in simple cases. I don't care if it survives longer than that or not.
-- external code should be able to set the value of this variable, either through a setter or otherwise.
Has a function myLib.applyTax(var price).
-- return value is price + myLib.tax.
-- I don't care what it does if either price or tax is not a number.
Lastly, a brief example of how to call this from another file, in such a way that:
-- for example, file A might set the value of the tax, then file B might apply the.
-- this works even though files A and B are unrelated.
The purpose of this question is for me to understand code and state encapsulation and how to use them from elsewhere.
EDIT: For the benefit of anyone seeing this later, what I did not understand when asking this question is that referring from javascript file A.js to javascript file B.js is a difficult problem unless that is enabled externally, for example in the html. For more detail, see How do I include a JavaScript file in another JavaScript file?
From your comments I see you would implement a Singleton Pattern in C# through static methods and data.
In Javascript you can do the same by managing the closures and putting that data into the outermost one, which would then be accessible to all code due to lexical scoping.
But I'd rather avoid singletons every day. Instead, use dependency injection as follows. This is just an example to show the technique, you'll have to code an actual solution yourself.
var lex = (function () {
var privatedata;
function privatemethod()
{
}
return {
publicmethod1: function (arg1, arg2) { ... },
publicmethod2: function (arg1, arg2) { ... },
getPublicData: function () { ... }
};
}());
This incapsulated object is then injected wherever you need it:
function consumerCode(lexicon)
{
...
}
consumerCode(lex); // injects the lex instance into the consumer code
By having only one instance and passing that same instance around wherever you need it, you will have pretty much what you were asking for.
This technique is not limited Javascript but also useful in C#. But in Javascript with loose typing it is especially powerful.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have a page I am building, and our solution to a problem involved wrapping some code inside a function then calling that when required.
Now the page is growing, and each item has its own function. According to D. Crockford each function is put in a VAR anyway so:
function functionName(){}
is equivalent to:
var var1 = functionName(){}
So now we have LOTS of vars in the page (I have also written them specifically in the latter format as Mr. Crockford promotes) and I am getting worried this creates too many variables (not sure this will cause any issues, performance or otherwise). I am thinking of making a single Object Literal and adding each function as a value to a key. This I think will reduce all these vars into a single manageable unit and reduce the amount of variables I am using (and avoid any potential issues) - or will it?
Thanks!
var keyword is actually being used in order to manage variable scope.
Not using var keyword makes the variable a global one. The memory occupied by the variables are cleared when the variable isn't used anymore. Most of the modern browsers contains a garbage collector responsible for freeing up the unused spaces. So it's suggested that using var keyword in blocks would make your js interpreter search less for the variable, otherwise it will search the whole document in order to get the value.
In performance terms it doesn't matter, you can use as many variables as you want, the performance only will be affected by the tasks performed in the function.
As you keep increasing the variables, the heap limit set by the relevant JS engine will come into play.
For eg - V8 engine seems to have it set to 1.4 GB
If you do ever run out of that, it's high time you recheck the code & stop blaming JS.
On a serious note, from a practical point of view, that's an enormous limit, which tells you that you don't need to worry about it so much.
Besides your friendly neighborhood GC will always keep cleaning up & ensure you live lavishly with variables.
Encapsulating your code in a namespace is a good idea but you won't save memory or get a performance boost that way. From performance perspective both ways you've shown are the same.
There is a convention to avoid nameclashing however based on reverted domain - imagine a JS lib made for SO:
// The following two lines are to protect namespace from overwriting and allow to
// extend them easily
if (!com) var com = {};
if (!com.stackoverflow) com.stackoverflow = {};
com.stackoverflow.renderSomething = function(){
// Some very clever code here
};
There is nothing else you can gain this way but it's worth to organize your code this way.
And just to clarify:
function functionName(){};
is almost the same as
var functionName = function(){};
Almost because in the first form functionName is defined at parse-time and the latter form defines functionName at run-time.
This question already has answers here:
What is the purpose of the var keyword and when should I use it (or omit it)?
(19 answers)
Closed 8 years ago.
When I want to import a 'class' in node.js I do this at the beginning of the file:
var MyClass = require('./MyClass.js');
what if I do this:
MyClass = require('./MyClass.js');
without var?
Is there a downside by not using var and placing this variable in global context?
if you declare a variable in a global scope, putting var or not has no difference
if you declare a variable with a var in a function then you create a local variable inside that function
if you create a variable without a var inside a function, it will look up the scope chain until it finds the variable or hits the global scope
Is there a downside by not using var and placing this variable in
global context?
the biggest downside is you will clutter the global namespace that makes the code hard to maintain. there are a lot of things you must consider on declaring global variables especially in javascript you can have a further reading on this article http://c2.com/cgi/wiki?GlobalVariablesAreBad
another thing is you can stil refer to javascript resources when your concern is about node.js because node.js's primary language is javascript
To answer your question "is there a downside?", yes, there are downsides and there are upsides to using global scope... despite the ubiquitous warnings about global scope, you can use it effectively under some circumstances in some languages in some contexts if you plan accordingly, have enough information about your application and the various components that make it up, etc etc etc...
In my experience, node doesn't provide any compelling reasons to use global scope, so you're opening yourself up to the dangers without experiencing any of the potential benefits. You have to be mindful about passing your variables around, but that's the "node way", it's designed specifically to work that way and javascript in particular is very good about allowing you to do that in ridiculously powerful ways.
The short answer is that, if this is a module for inclusion in other projects, then you're courting disaster by introducing your variable into the global scope of projects where you couldn't hope to understand how that could effect things. If this is a standalone application, so long as it remains trivial and will not grow and evolve over time, you're probably OK using the global scope as a shortcut. The more your application grows and changes, the more likely you are to run into problems by not properly limiting scope.
Putting var in front of the variable definition defiles the variables in the local scope of the function you are in.
With no var the variable automatically goes into the global scope.
For more help see here.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
According to this article
http://www.mediaevent.de/javascript/globale-lokale-variablen.html
Global variables are in JS pretty dangerous.
I'm sorry that it's in German, but I'm gonna point out out the 2 main statements of the article.
The first is already in the 2nd paragraph of the head statement.
It says something like "In JS global var's are dangerous as they can get accessed by other scripts over the name" That's fine so far, as that's mostly the way why I want to use global var's don't I?
But in the article it sounds as this could happen randomly. and that's for sure not the expected behaving, is it?
But what is much more frightening me is the second last sentence. It forecasts that memory leaks will generated if a function that declares a
global variable is called multiple times.
But how could this happen if the name is still the same? how there can be multiple vars declared global with the same name?
Or is this article probably written by some one just "half-knowledge"? Or maybe just addressed to some one who isn't used to the difference between global and local at all?
Or is JS really behaving in this way?
Now a concrete example:
I want some one who logs in to my page to create a Random generated token and submit it by clicking login.
on each other button I want that this token is accessed by a different function and just submit it, so that just for a new login the key will be regenerated.
For that key I was thinking about using a global variable, which gets declared by one function and gets returned by another.
But as I will generate/regenerate the key possibly more then once, would this generate memory leaks? Or is this article I'm referring to probably just dramatizing?
If this is really the way JS is behaving, what would be a good way to make a variable accessable from different functions in my case?
The problem with globals is not memory, and it's not performance.
The problems with globals is entirely different. The problems are that they introduce global state and that scripts are not bound to a namespace.
Let's go through these problems one by one.
Having global state
This is the biggest issue here. Coding necessitates that the dependencies of a module be explicit and that communication between pieces of code is very clear.
When you have global variables which part of the code uses the variable is not nearly as clear and you can't be sure what part of the code needs it and what does not.
Let's say I have a Zoo project and I have a Bathe service that cleans an animal. Instead of passing Bathe around to each animal that needs it I have it on a global namespace and I just call Bathe(myAnimal).
Now I want to restructure my zoo and I want to know which animals need bathing because I want to optimize that. I have no way of knowing that other than going through my whole code. In order to see if my Giraffe needs bathing I have to read the entire code of the Giraffe class. If instead I passed Bathe to the constructor of Giraffe instead of using it or creating it inside giraffe (a concept called dependency injection) I can see that a Giraffe needs bathing just by reading the signature.
Now this can get way worse, what if I have state? If I'm actually changing a global variable in multiple places it becomes extremely hard to track. In a more than a few lines code base this means that you have state changing all around and no clear indication of who is changing it.
This is the main reason you should avoid globals altogether .
Scripts are not bound to a namespace
If I have two scripts on a page and my first script declares a A variable on the global namespace, the second script can access that variable. This is useful because scripts can interact this way but it's very harmful because it means that scripts can override each other's code, and communicate in an unclear way.
This of course is completely mitigated if you use a module loader like browserify or RequireJS which means your whole script only exposes two globals - require and define and then script loading is done through the loader.
This way the way independent pieces of code interact is well defined. That doesn't prevent you from creating variables on the global object, but it helps mitigating the need to do so in a uniform manner.
A note on security
Of course, anything on the client side is compromised, you can't do security or anything like that in client side JavaScript on an insecure browser (that is, you didn't prevent anything external on) because the client can just run arbitrary code on your code and read it.
There are three big problems with global variables:
name collisions
code complexity
garbage collection
Name collision
The problem with having variables in global scope is that you have less control over what else is in that scope. Your code uses a ga_ variable globally and works fine, but when you add a Google Analytics snippet that uses the same variable things unexpectedly fail and it can be quite hard to see why your shopping cart fails 2 out of 3 page loads.
If you can wrap your code in an IIFE to prevent having any variables in global scope, you should do that. Obviously there are cases where you actually want to have your code accessible globally (ex: jQuery library). In those cases, it is best practice to keep all your stuff in a single namespace (jQuery) with a relevant name.
Code complexity
It is usually a good idea to partition your code so that individual pieces have minimal interactions with each other. The more pieces interact the harder it is to make changes and to track down where bugs come from. Obviously a global variable can be accessed anywhere so when you have a problem with some code that accesses a global variable, you have to inspect every usage of that variable which can be quite a big pain. The thing to do to avoid these pains is to keep variables as local as they can be and encapsulate pieces of code so they can't interact with each other except through specific interfaces.
Memory leaks
In JavaScript you have little control over the garbage collection process. All that is guaranteed is that if you can access a variable it will not be garbage collected. This means that if you want something to be garbage collected, then you must make sure you can't access it anymore. While a global i variable which keeps a number won't be a big deal, as #Boluc Papuaccoglu mentioned when your global variable keeps more and more properties over time (an array of XHR requests for example, or array of created DOM objects), the memory consumption turn into a big deal.
All of these situations are worst case scenarios and you probably won't have issues with a small application. These recomendations have most value when you're starting to learn programming because they develop good habits and when you're working on complex applications when they save you time and money wasted on debug or difficult to do improvements.
Regarding memory leaks: Let's say you have a function, and within it you define a var, and use it for some purpose then return from the function. In this case, the memory used by the variable will be freed. However, if you relied on a global variable to do the same thing, then the memory would continue to be allocated long after your function exited. Extending the same scenario, imagine that your function adds properties to this variable with names that depend on the data the function is processing (like Order ID, Customer Name, etc.) Now, each time your function gets called, more and more properties will be appended to this variable and it will grow and grow.