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.
Related
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 6 years ago.
Improve this question
I learnt programming with C/C++, so memory management in Javascript is never intuitive to me.
I know that all variables are located in heap memory rather than in stack memory, so memory operations are quite expensive. If all references to a variable are not accessible anymore, it can be garbage collected, but it looks like V8 won't immediately do garbage collection? (Observed with --trace_gc)
To free memory of a global array object, this can be done by array = null, will array = [] have the same effect? (I need the variable to behave like an array even after I clear it).
From my experience, String and Number are passed to functions by value while Object and Array are passed to functions by reference. If String is very large and the function actually allows it to be passed by reference safely (only read the string), will V8 optimizes like that?
ES6 introduces let keyword for block-scope declaration, but a single use of let makes the whole function becomes slower, so I still stick to var even though let/const are closer to C/C++ which I am familiar with. (Tested using d8 built right from master branch, I am aware that V8 developers are actively working on this bug).
Trying to use Chrome DevTools to learn my code's memory management, but couldn't figure what those graphs and charts from profiler actually mean.
Basically, you do c++ when you want to manage your memory and a whole bunch of quite technical stuff yourself.
If you don't want you go for c#/Java because there is a virtual machine managing the memory.
Same goes for JavaScript the browser manage the memory, and unless you're loading a page with thousands of elements or writing a library to display / compute over thousands of data you won't have any memory problem.
Note that array = [] will affect the reference of a new empty array when array = null will dereference the existing array. Since it's null, if you try to use it won't work, so go for the array=[].
If you're still not convinced, then just use an appropriate library to do the work for you.
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 7 years ago.
Improve this question
I have been reading about some good practices in JavaScript and one of them was Unobtrusive JavaScript. The first point caught my attention
Separation of functionality (the "behavior layer") from a Web page's structure/content and presentation
On the wiki page, one of the examples is that you should bind actions to events in JS files instead of in the HTML. This example
<input type="text" name="date" id="date" />
...
window.onload = function() {
document.getElementById('date').onchange = validateDate;
};
is favored over
<input type="text" name="date" onchange="validateDate()" />
However, I would say I'd prefer the second code with onchange attribute over the first one. My reasons for this are
It is easily readable and immediately clear what will happen on change (or any other event) on that element.
I don't have to got through JavaScript files and look where (and whether) the onchange event is bind and whether there are some other events such as click defined for #date.
Frameworks such as AngularJS have ng-click and is mixing up HTML structure with JS. Why shouldn't I?
The disadvantages of not using unobtrusive javascript that I have read about are
Polluting global namespace.
Creating long and unreadable inline code.
If the code for an event changes, you have to change it only in one place - that is in a JS file.
But I think that the disadvantages can be solved.
Instead of polluting namespace, create the app in one variable so the code would look like onchange="app.validateDate()" and no polluting would happen.
Inline code would not be written and would be separated in a function in JS file, then it'd be called like onclick="app.action();".
Isn't it the same as using a function in onclick attribute? Because in the end you have to make a change just in one function in both approaches whether it is $('input').change(function () {/* ... change ... */}); or app.action = function () {/* ... change ... */}.
So is it actually still considered a good practice?
This is a very broad topic and heavily opinion based. There is no one answer to everything. However, here are some observations:
You are polluting the namespace whatever you do. app.validateDate pollutes the namespace just as validateDate does, just by virtue of needing to have a globally accessible function name. In complex modern sites, there are tons of scripts competing for global names. Ideally you're never exposing any name globally, not even a namespace name.
.onclick = handler is not great either. You'd want:
document.getElementById('date').addEventListener('change', function () { .. });
This is even less obtrusive and allows several scripts to bind event listeners to the same element. Again, in complex modern sites one of the highest priorities you can have is to ensure nobody is stepping on anyone else's feet. You never know who else might be interested in the change event of that element in the future.
It is still more code to write it inline than elsewhere. Longer HTML code that is. HTML can already be very verbose. Anything you can move elsewhere you should. Reducing the amount of code in any one particular file is an art in itself and important for readability. Yeah, it's "just one more attribute"... on top of all the other attributes and elements and inline declarations you're also not avoiding. It's just piling up, and that's how code gets messy and unreadable and unmaintainable.
Reusability: document.getElementById(..).addEventListener can be written once in an external file and automagically reused across many different pages. <.. onclick=".."> needs to be repeatedly written every single time. DRY your code.
For tiny projects it often hardly matters. But again, sites are getting more and more complex. Business needs demand constant changes. Just one more analytics script, just one more Javascript based social widget, now change it all back, now keep all the versions of dependencies in sync, now rip it all out again and redesign for our 2.0 launch next week. Do it all with 10 other people in parallel without nuking each others code on every build or needing long sessions of resolving git-merge conflicts. In such an environment, every little bit of decoupling and indirection and flexibility helps.
Since you mention Angular:
Angular avoids some of these issues by employing a completely different template parsing model. When you write onclick=foo, then you need to bind to a global function name. However, when Angular does ng-click=foo, foo is a locally scoped entity in an ng-scope. It's not a global name. Angular separates between a controller and a view, where the controller essentially exposes a specific API on the $scope object which the view can use; both the controller and the view are still interchangeable as long as the specified API contract is kept (meaning as long as the $scope object keeps the same attributes).
All ng directives are evaluated against a custom scoping and evaluation engine which does not have much to do with Javascript's default modus operandi.
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.
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.
This question already has answers here:
What is the advantage of initializing multiple javascript variables with the same var keyword?
(5 answers)
Closed 8 years ago.
When declaring variables at the top of a function, is there a difference between those two ways to do so?
var firstvar;
var secondvar;
var thirdvar;
and
var firstvar,
secondvar,
thirdvar;
Here there is a very well written blog post about multiple var statements vs single ones. I have to say that I mostly agree with Ben Alman: when I started with JS years ago, I used single statement but I switched to multiple statement for maintenance and readability reasons. Of course, I'm still using single var statement where it makes sense (e.g. when I don't have to assign values to those variables and where they are all logically related).
The commonly used static code analysis tool JSLint would tell you to combine them all into a single var statement. There is a fair explanation of why this is a good idea in the answer to this question.
Try to keep one style the whole code through. It doesn't matter which one.
It's purely a matter of personal preference. Most people seem to use the var x, y, z way (with one variable per line) though.
JSLint also suggests to use only one var statement, but the rules of that tool were obviously influenced by its developer's preferences, too.
However, I've seen quite a few auto-indent tools (for example, every single one that is available for Vim) to break in some cases when using multi-variable var statements so if that's the case for you, too, you better use separate var statements.