I'm wondering which would be better practice. Polluting the global namespace with global variables for intra-session persistence or using localStorage instead?
So in other words set a global variable on launch, change its value in a function when required and reference it in a third function, or use localStorage.setItem then localStorage.removeItem when the value is no longer needed?
Will doing either one increase memory efficiency?
LocalStorage is primarily for persistent data across sessions.
In your case, as your looking for an intra-session persistence, global variables have clear advantages.
I will start with cons of global variables first.
It uses the global namespace, any third party js code can manipulate it
A page refresh can wipe off your data
Well, that's it. If we consider the cons of LocalStorage, the list will raise your eyebrows.
set and get are slow and can be a performance bottleneck for large datasets
only strings are allowed; you may have to serialize your data before setting
I would surely vote up for LocalStorage if your use case involved inter-session storage. However, in your scenario, the only benefit you see is the removeItem function for which you have the delete counterpart for global variables.
This article may be helpful: http://www.sitepoint.com/html5-browser-storage-past-present-future/
As now consider to using DI in frameworks like Angular.
Related
A have a react application using a single page. I call index.html and use ajax(axio) and update the page. I do not use any routing.
I have some global variables and will use in the whole scope of the application. The variables are primitive type integer for example. Some of the variables may be updated during the app lifecycle and some remain constant. But I should be able to reach them from all react components/javascripts. They may contain business related constants or example decimal format mask, keeping them private in each component will not be useful.
There is no need/reason to store it on the disk (localStorage).
Question is: what is the best way (performance etc) storing the global variable foo in the app?
window.foo = 10 or
window.sessionStorage.foo = 10
AFAIK, window.foo is for a single page and sessionStorage allows using within multiple pages within the same origin. What is best in my case when I use a single page? Are there any other drawbacks of window.foo usage? Security is not important, the vales stored are not sensitive. Most critical is the performance.
You probably want to use context rather than either of those. From that documentation:
Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.
Definitely don't use global variables. The global namespace is incredibly crowded, and adding to it is generally not best practice. If you did use a global for this, I'd recommend using just one, and having it refer to an object with properties for the various pieces of information you want to share. Note that they'll be window-specific.
One reason to possibly consider using sessionStorage (or perhaps periodically synchronizing your React context to it) is if you want changes in one window to be reflected in another window. Two windows/tabs from the same origin share the same sessionStorage and can get an event (storage) when the other one changes that storage. So if the global information were an app theme (say, light vs. dark), changing it in one tab could also affect the other tab if you respond to the storage event by updating your React context. Note that sessionStorage (and localStorage) only store strings, so the usual thing is to convert to JSON when storing (JSON.stringify) and from JSON when loading (JSON.parse).
I am trying to make my javascript games as light and smooth as possible, and here is my dilemma : What is worse, too many garbage or too many global variables ?
On one hand, to avoid micro pauses caused by garbage collection, I should avoid using temporary variables in my functions and for loops, those which I create with "var" and which die at the end of the function, because they become garbage.
But on the other hand, if I replace all these temporary variables with as many persistent global variables, won't it make my program heavier to run for the browser's javascript engine ?
What is worse ?
(Judging only on ease of writing and avoiding bugs, I would never get rid of temporary variables. For example, if a function A calls a function B and both have a for(i=...) instead of for(var i=...), function B's for loop will accidently mess up with function A's "i" since it would be the same global variable instead of two different temporary ones belonging to each function, and there will be bugs. The only way to avoid this with global variables is to use longer more explicit names, and that is annoying when you have to write them a lot. But garbage collection micro pauses are annoying in games so I must avoid temporary variables. What a dilemma.)
Javascript has automatic garbage collection. While you don't want to get carried away with throwaway variables, using functions to properly scope your variables and manage your application will make this a non-issue in almost every case.
You should be using for(var i...) for all your iterative loops because, as you said, the other options are either 1) stupid long variable names or 2) namespace collisions.
In general you should use functions to namespace and modularize the components of your game/application. To avoid any real name space collisions you can wrap your entire application in a function to create a private namespace, like:
(function(){
//code goes here
})();
I recommend you read Memory Management and this StackOverflow question on global variables.
Writing Fast, Memory-Efficient JavaScript
By Addy Osmani is also a great article on Garbage Collection in Javascript.
are there any specific disadvantages of defining a global function, as there are for defining global variables?
We are trying to downsize our custom JS file, and quite a bit of code is being used across functionalities.
Namespace collisions are one big issue. If you create a global function, and accidentally use the same name as another global function, you will overwrite that function, which may cause your application to break.
Bear in mind that all global variables are actually properties of the window object. If you accidentally overwrite a built-in property of window, you might produce some really odd glitches that can be hard to track down.
Another reason is just general cleanliness/organization. If you write a dozen functions to do operations on strings, you might want to put them all on an object stringOps, so that you've got them in one place.
The main danger with global references are that you will step on someone elses reference or vice versa. This can make testing extremely difficult as you may have introduced a large dose of non-determinism.
For instance say you define Global.PI as 3.14159 and your functions which ref that work fine, until a user loads a page with a library that defines Global.PI as 'Lemon', now your functions work not quite as expected.
The project I work on has global references due to the strucutre of our application.
To alleviate some of these issues we will attach a single object to window (window.yourObjHere) and place our global references within that object.
The only advantage to Globals are that some things simply can't be done without them. We have an eventBus that must message over seperate AngularJS applications. As the AngularJS native eventBus is per application, we have to register each application on our GLobal object in order to keep track of where messages should go etc. Whenver possible avoid using Globals but there are simply some things which can't be done without them. Just be careful and limit your Global footprint.
The disadvantages are as poeple ahve outlined (basically no namespacing meaning functions/variables can be overwritten) but you could get around this by declaring a global object which has all you need in it - and you can add things to it 'on the fly' :
GLOBAL_myObject = {
variableOne: 1,
variableTwo: "A atring",
getThisAndThat: function(p1,p2) {
//do some stuff
return p1 * p2; /or somthing
}
};
So refer to all your own variables as a property of that object:
alert(GLOBAL_myObject.variableOne);
GLOBAL_myObject.getThisAndThat(1,2);
Effectively you're just namespacing the variables.
to add more to the global GLOBAL_myObject you can just declare it ..
GLOBAL_myObject.anotherThing=1965; // what a year!
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.
If I'm looping and referencing a variable that's kept in localStorage, should I create a locally scoped variable (outside the loop) and set it equal to the localStorage variable for performance reasons?
This may turn a micro-optimization unless you access it REALLY often and it takes the greater part of your loop.
If you are referencing the same local storage value multiple times within a function, then assign it to a local variable for the duration of that function. This is no different than any other value that takes some work to retrieve (like the value of an input field in the DOM). If you need the value multiple times within the same function, then put it's value in a local variable and use it from there. Your code will probably be more compact and execute faster too.
There should be no reason to cache it globally in a persistent global variable as it's already globally accessible from local storage so there's really no reason to add a new global for it. Just retrieve the value in each function that you need it in. The only exception I could imagine to this would be a micro-performance-optimization in a rare circumstance. Generally, it's better not to make your own global copy of things that are already globally available.
No, you won't get that much performance. Ofc if you'r querying too many times, you should.