Advanced Javascript initialisation - javascript

I'm having trouble deciphering the following Javascript initialisation statement:
(function(NAMESPACE) {
NAMESPACE.nav = {};
var nav = NAMESPACE.nav,
_init = false,
_isNavOpen = false,
_inner = document.getElementById('inner-wrap');
// constants
nav.CLASS = 'js-nav-open';
nav.CLASS_READY = 'js-nav';
nav.CONTAINER = '#nav';
nav.DURATION = 400;
nav.HAS_CSSTRANSITIONS = $('html').hasClass('csstransitions') && $('html').hasClass('csstransforms3d');
...
...
// toggle open/close
nav.toggle = function(event) {
event.stopPropagation();
if(_isNavOpen && $('html').hasClass(nav.CLASS)) {
nav.close();
} else {
nav.open();
}
// this is for the links
if(event) {
event.preventDefault();
}
};
}(PROJECT_NAME));
It seems unnecessarily complicated - calling (or setting?) 'nav' 3 times in 2 lines. Can somebody please explain what the point is of flipping it around like this?

This is an example of a JavaScript closure which is commonly used to create private scope and avoid having the objects pollute the global scope.
It is very common to create plugins this way to avoid conflicts with other functionality on the page as a result of variables with the same name etc. Essentially it's a mechanism for managing scope.

This is a common practice when using jQuery:
(function ($) {
var div = $('#my-div');
// Etc
}(jQuery));
Wrapping your script in a closure ensures that certain variables will have the values you expect them to.
For example, jQuery uses the $ for doing just about everything. Most people like to use $('do something') rather than jQuery('do something').
But say that you have another library on the page that also uses the global variable $.
By wrapping your code in the closure, you "reserve" the $ as jQuery's, and jQuery's alone. (When you pass in jQuery as the argument to closure, $ can only mean "jQuery," in the scope of this function.)
Similarly, in your example, you are reserving the NAMESPACE variable. Even if there were another variable called NAMESPACE, causing a racket somewhere else on the page, by passing in a variable at the end of your closure, you will be guaranteed that NAMESPACE will be the object you expect it to be (at least within the closure).
Say that you had a global variable called AbominableSnowman, but you wanted to use AS as a shortcut. By doing this:
var AS = "Apple Soup";
(function (AS) {
AS.tellMeAboutSnowmen();
alert(AS.snowballs);
}(AbominableSnowman));
Your code will still function as you intended. (Proof: http://jsfiddle.net/RUzZH/1/)
As for "flipping it around," it seems like the original programmer wanted to shorten NAMESPACE.nav down to nav. This was probably the best way of doing that.
An alternative (not recommended):
// It's best to limit your assignments to 1-per-line
// This kind of code isn't fun to debug, or even read
var nav = NAMESPACE.nav = {};
It doesn't seem like something worth fretting over. However, since this script interacts with NAMESPACE.nav quite often, it will be slightly, slightly faster to directly reference the .nav property with the nav variable. (This really is a micro-optimization, but in this case it's conveniently justifiable for a different reason [sake of clarity].)

Here's a line-by-line explanation (with headers just to break it up):
Setup:
// Create an anonymous function expression taking `NAMESPACE` as a parameter.
// Likely the *real* namespace will be passed to the function at the end
// with ... })(realnamespacetomodify);
(function(NAMESPACE) {
// Create the new part of the namespace. Note that we are editing a reference
// so really this change happens on whatever object was passed in.
NAMESPACE.nav = {};
// Create a local pointing to this new sub-namespace. Probably just for
// convenience, also possibly for portability (if the name is used in closures,
// then those closures don't need to refer to NAMESPACE directly).
var nav = NAMESPACE.nav,
Module definition:
// While nav refers to an object likely in global scope, nav itself can
// never be referred to from global scope because it is a local here.
// These variables are local here. They can never be referred to by global scope.
_isNavOpen = false,
_inner = document.getElementById('inner-wrap');
// These variables, added to nav, can be accessed using the object that
// nav refers to in global scope (see the end).
nav.CLASS = 'js-nav-open';
...
// This function is also added to nav, therefore it can be accessed outside
nav.toggle = function(event) {
...
// This reference to _isNavOpen resolves because this function
// is a closure, and binds variables outside its scope
// to the function itself. So even though _isNavOpen can't be
// accessed globally, it can be accessed here, making it like
// a private member of this namespace.
if(_isNavOpen && $('html').hasClass(nav.CLASS)) {
// nav is also bound by the closure and can be accessed here
nav.close();
} ...
};
Use in global space:
}(PROJECT_NAME));
console.log(PROJECT_NAME.nav.CLASS); // "js-nav-open"
console.log(PROJECT_NAME.nav.toggle); // Function object
This is a module pattern. It is used for several reasons:
Code portability (not referring to global objects inside the module)
Scoping (avoiding assigning unnecessary vars to global namespace)
Visibility (hiding private access variables)
As for the first three lines themselves (your original question), they could refer to PROJECT_NAME directly, but it looks like it's been set up to aid code portability. You'll notice that the anonymous function itself never points to the real object (PROJECT_NAME). That means that you can copy and paste this part around and only change that reference in one place.
The other answer mentions scope, and while that's important too, it doesn't explain all benefits of this code, such as why it doesn't just directly refer to existing global variables. The scope-hiding benefits themselves are achieved with this part of the pattern:
(function() {
... // Anything set here is local, not global.
})();

Related

Need advise/help on getting rid of global variables

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.
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
Mastering the Module Pattern
JavaScript module pattern with example
I'm convinced that I shouldn't, and I am more wondering HOW not to use them, and that I'm still unsure about.
load_chunks.js, load_images.js, render_map.js, player_actions.js, input.js, strongly hint to a procedural implementation, that is your architecture probably has several functional pieces and you pass data around between these functions. That's where your global variables are coming from.
So how do I get rid of my global variables (...)
To change that, you need to structure your system in an object or component based approach, that is:
encapsulate data + respective functions by objects in your problem domain, e.g. have a World object that contains Avatar, Buildings, Airborne objects etc. (or whatever your project is about).
separate the problem domain's logic from view logic (e.g. use a MVC architecture)
then your project organises the interactions between view and model objects by essentially exchanging messages between them.
To facilitate this, I suggest these fine frameworks, or some equivalents suitable for your run-time environment:
requirejs - to encapsulate modules into globally managed components
backbonejs - to have an efficient, proven model/view, class/object model (actually built for use with a REST-style backend, but that's not a strict requirement)
Code structure
Typically, I structure my applications such that there is one .js file per each object component/module. A module in this sense contains both the class definition and the corresponding collection. The modules are managed by requirejs and the class definitions are done using backbonejs.
I hope you can show me or write for me a script example
/* define a class e.g. in someclass.js */
define(['backbone'], function($B) {
var SomeClass = $B.Model.extend({
// all instance variables, methods etc. follow
someVar : value,
someMethod : function() { ... },
});
return SomeClass;
});
/* use the class, e.g. in app.js */
require(['someclass'], function(SomeClass) {
var instance = new SomeClass({ initial model attributes });
var value = instance.get('attribute');
instance.someMethod();
...
});
i had the same problem before but it was a big problem as we had a third party javascript code and our code live in clients websites so we should find a way to omit the appearance of global variable so to be short:
Use 1 global variable namespace and make all other to be properities for it:
GlobalVariable = {}
GlobalVariable.var1 = "var1"
GlobalVariable.var2 = "var2"
You can also make it more useful and divide it into groups:
GlobalVariable.helper = {}
GlobalVariable.helper.var1 = "var1"
GlobalVariable.helper.var2 = "var2"
so you can use same names under different groups.
and if you want to Omit it totally you can use:
(function(document, window) {
// all variables here is global only inside the scope
}(document, window));

Should I encapsulate blocks of functionality in anonymous JavaScript functions?

My intuition is that it's a good idea to encapsulate blocks of code in anonymous functions like this:
(function() {
var aVar;
aVar.func = function() { alert('ronk'); };
aVar.mem = 5;
})();
Because I'm not going to need aVar again, so I assume that the garbage collector will then delete aVar when it goes out of scope. Is this right? Or are interpreters smart enough to see that I don't use the variable again and clean it up immediately? Are there any reasons such as style or readability that I should not use anonymous functions this way?
Also, if I name the function, like this:
var operations = function() {
var aVar;
aVar.func = function() { alert('ronk'); };
aVar.mem = 5;
};
operations();
does operations then necessarily stick around until it goes out of scope? Or can the interpreter immediately tell when it's no longer needed?
A Better Example
I'd also like to clarify that I'm not necessarily talking about global scope. Consider a block that looks like
(function() {
var date = new Date(); // I want to keep this around indefinitely
// And even thought date is private, it will be accessible via this HTML node
// to other scripts.
document.getElementById('someNode').date = date;
// This function is private
function someFunction() {
var someFuncMember;
}
// I can still call this because I named it. someFunction remains available.
// It has a someFuncMember that is instantiated whenever someFunction is
// called, but then goes out of scope and is deleted.
someFunction();
// This function is anonymous, and its members should go out of scope and be
// deleted
(function() {
var member;
})(); // member is immediately deleted
// ...and the function is also deleted, right? Because I never assigned it to a
// variable. So for performance, this is preferrable to the someFunction
// example as long as I don't need to call the code again.
})();
Are my assumptions and conclusions in there correct? Whenever I'm not going to reuse a block, I should not only encapsulate it in a function, but encapsulate it in an anonymous function so that the function has no references and is deleted after it's called, right?
You're right that sticking variables inside an anonymous function is a good practice to avoid cluttering up the global object.
To answer your latter two questions: It's completely impossible for the interpreter to know that an object won't be used again as long as there's a globally visible reference to it. For all the interpreter knows, you could eval some code that depends on window['aVar'] or window['operation'] at any moment.
Essentially, remember two things:
As long as an object is around, none of its slots will be magically freed without your say-so.
Variables declared in the global context are slots of the global object (window in client-side Javascript).
Combined, these mean that objects in global variables last for the lifetime of your script (unless the variable is reassigned). This is why we declare anonymous functions — the variables get a new context object that disappears as soon as the function finishes execution. In addition to the efficiency wins, it also reduces the chance of name collisions.
Your second example (with the inner anonymous function) might be a little overzealous, though. I wouldn't worry about "helping the garbage collector" there — GC probably isn't going to run in the middle that function anyway. Worry about things that will be kept around persistently, not just slightly longer than they otherwise would be. These self-executing anonymous functions are basically modules of code that naturally belong together, so a good guide is to think about whether that describes what you're doing.
There are reasons to use anonymous functions inside anonymous functions, though. For example, in this case:
(function () {
var bfa = new Array(24 * 1024*1024);
var calculation = calculationFor(bfa);
$('.resultShowButton').click( function () {
var text = "Result is " + eval(calculation);
alert(text);
} );
})();
This results in that gigantic array being captured by the click callback so that it never goes away. You could avoid this by quarantining the array inside its own function.
Anything that you add to the global scope will stay there until the page is unloaded (unless you specifically remove it).
It's generally a good idea to put variables and function that belong together either in a local scope or in an object, so that they add as little as possible to the global namespace. That way it's a lot easier to reuse code, as you can combine different scripts in a page with minimal risks for naming collisions.

What is the purpose of an anonymous JavaScript function wrapped in parentheses? [duplicate]

(function() {})() and its jQuery-specific cousin (function($) {})(jQuery) pop up all the time in Javascript code.
How do these constructs work, and what problems do they solve?
Examples appreciated
With the increasing popularity of JavaScript frameworks, the $ sign was used in many different occasions. So, to alleviate possible clashes, you can use those constructs:
(function ($){
// Your code using $ here.
})(jQuery);
Specifically, that's an anonymous function declaration which gets executed immediately passing the main jQuery object as parameter. Inside that function, you can use $ to refer to that object, without worrying about other frameworks being in scope as well.
This is a technique used to limit variable scope; it's the only way to prevent variables from polluting the global namespace.
var bar = 1; // bar is now part of the global namespace
alert(bar);
(function () {
var foo = 1; // foo has function scope
alert(foo);
// code to be executed goes here
})();
1) It defines an anonymous function and executes it straight away.
2) It's usually done so as not to pollute the global namespace with unwanted code.
3) You need to expose some methods from it, anything declared inside will be "private", for example:
MyLib = (function(){
// other private stuff here
return {
init: function(){
}
};
})();
Or, alternatively:
MyLib = {};
(function({
MyLib.foo = function(){
}
}));
The point is, there are many ways you can use it, but the result stays the same.
It's just an anonymous function that is called immediately. You could first create the function and then call it, and you get the same effect:
(function(){ ... })();
works as:
temp = function(){ ... };
temp();
You can also do the same with a named function:
function temp() { ... }
temp();
The code that you call jQuery-specific is only that in the sense that you use the jQuery object in it. It's just an anonymous function with a parameter, that is called immediately.
You can do the same thing in two steps, and you can do it with any parameters you like:
temp = function(answer){ ... };
temp(42);
The problem that this solves is that it creates a closuse for the code in the function. You can declare variables in it without polluting the global namespace, thus reducing the risk of conflicts when using one script along with another.
In the specific case for jQuery you use it in compatibility mode where it doesn't declare the name $ as an alias for jQuery. By sending in the jQuery object into the closure and naming the parameter $ you can still use the same syntax as without compatibility mode.
It explains here that your first construct provides scope for variables.
Variables are scoped at the function level in javascript. This is different to what you might be used to in a language like C# or Java where the variables are scoped to the block. What this means is if you declare a variable inside a loop or an if statement, it will be available to the entire function.
If you ever find yourself needing to explicitly scope a variable inside a function you can use an anonymous function to do this. You can actually create an anonymous function and then execute it straight away and all the variables inside will be scoped to the anonymous function:
(function() {
var myProperty = "hello world";
alert(myProperty);
})();
alert(typeof(myProperty)); // undefined
Another reason to do this is to remove any confusion over which framework's $ operator you are using. To force jQuery, for instance, you can do:
;(function($){
... your jQuery code here...
})(jQuery);
By passing in the $ operator as a parameter and invoking it on jQuery, the $ operator within the function is locked to jQuery even if you have other frameworks loaded.
Another use for this construct is to "capture" the values of local variables that will be used in a closure. For example:
for (var i = 0; i < 3; i++) {
$("#button"+i).click(function() {
alert(i);
});
}
The above code will make all three buttons pop up "3". On the other hand:
for (var i = 0; i < 3; i++) {
(function(i) {
$("#button"+i).click(function() {
alert(i);
});
})(i);
}
This will make the three buttons pop up "0", "1", and "2" as expected.
The reason for this is that a closure keeps a reference to its enclosing stack frame, which holds the current values of its variables. If those variables change before the closure executes, then the closure will see only the latest values, not the values as they were at the time the closure was created. By wrapping the closure creation inside another function as in the second example above, the current value of the variable i is saved in the stack frame of the anonymous function.
This is considered a closure. It means the code contained will run within its own lexical scope. This means you can define new variables and functions and they won't collide with the namespace used in code outside of the closure.
var i = 0;
alert("The magic number is " + i);
(function() {
var i = 99;
alert("The magic number inside the closure is " + i);
})();
alert("The magic number is still " + i);
This will generate three popups, demonstrating that the i in the closure does not alter the pre-existing variable of the same name:
The magic number is 0
The magic number inside the closure is 99
The magic number is still 0
They are often used in jQuery plugins. As explained in the jQuery Plugins Authoring Guide all variables declared inside { } are private and are not visible to the outside which allows for better encapsulation.
As others have said, they both define anonymous functions that are invoked immediately. I generally wrap my JavaScript class declarations in this structure in order to create a static private scope for the class. I can then place constant data, static methods, event handlers, or anything else in that scope and it will only be visible to instances of the class:
// Declare a namespace object.
window.MyLibrary = {};
// Wrap class declaration to create a private static scope.
(function() {
var incrementingID = 0;
function somePrivateStaticMethod() {
// ...
}
// Declare the MyObject class under the MyLibrary namespace.
MyLibrary.MyObject = function() {
this.id = incrementingID++;
};
// ...MyObject's prototype declaration goes here, etc...
MyLibrary.MyObject.prototype = {
memberMethod: function() {
// Do some stuff
// Maybe call a static private method!
somePrivateStaticMethod();
}
};
})();
In this example, the MyObject class is assigned to the MyLibrary namespace, so it is accessible. incrementingID and somePrivateStaticMethod() are not directly accessible outside of the anonymous function scope.
That is basically to namespace your JavaScript code.
For example, you can place any variables or functions within there, and from the outside, they don't exist in that scope. So when you encapsulate everything in there, you don't have to worry about clashes.
The () at the end means to self invoke. You can also add an argument there that will become the argument of your anonymous function. I do this with jQuery often, and you can see why...
(function($) {
// Now I can use $, but it won't affect any other library like Prototype
})(jQuery);
Evan Trimboli covers the rest in his answer.
It's a self-invoking function. Kind of like shorthand for writing
function DoSomeStuff($)
{
}
DoSomeStuff(jQuery);
What the above code is doing is creating an anonymous function on line 1, and then calling it on line 3 with 0 arguments. This effectively encapsulates all functions and variables defined within that library, because all of the functions will be accessible only inside that anonymous function.
This is good practice, and the reasoning behind it is to avoid polluting the global namespace with variables and functions, which could be clobbered by other pieces of Javascript throughout the site.
To clarify how the function is called, consider the simple example:
If you have this single line of Javascript included, it will invoke automatically without explicitly calling it:
alert('hello');
So, take that idea, and apply it to this example:
(function() {
alert('hello')
//anything I define in here is scoped to this function only
}) (); //here, the anonymous function is invoked
The end result is similar, because the anonymous function is invoked just like the previous example.
Because the good code answers are already taken :) I'll throw in a suggestion to watch some John Resig videos video 1 , video 2 (inventor of jQuery & master at JavaScript).
Some really good insights and answers provided in the videos.
That is what I happened to be doing at the moment when I saw your question.
function(){ // some code here }
is the way to define an anonymous function in javascript. They can give you the ability to execute a function in the context of another function (where you might not have that ability otherwise).

I've Heard Global Variables Are Bad, What Alternative Solution Should I Use?

I've read all over the place that global variables are bad and alternatives should be used. In Javascript specifically, what solution should I choose.
I'm thinking of a function, that when fed two arguments (function globalVariables(Variable,Value)) looks if Variable exists in a local array and if it does set it's value to Value, else, Variable and Value are appended. If the function is called without arguments (function globalVariables()) it returns the array. Perhaps if the function is fired with just one argument (function globalVariables(Variable)) it returns the value of Variable in the array.
What do you think? I'd like to hear your alternative solutions and arguments for using global variables.
How you would use globalVariables();
function append(){
globalVariables("variable1","value1"); //globalVariables() would append variable1 to it's local array.
};
function retrieve(){
var localVariable1 = globalVariables("variable1"); //globalVariables() would return "value1".
};
function retrieveAll(){
var localVariable1 = globalVariables(); //globalVariables() would return the globalVariable()'s entire, local [persistently stored between calls] array.
};
function set(){
globalVariables("variable1","value2"); //globalVariables() would set variable1 to "value2".
};
Is this a Singleton Pattern BTW?
In this specific scenario a function may set a variable at one point in time, and much later another function, maybe when a user submits a form, will need to get that variable. Therefore the first function couldn't pass the variable as an argument to the later function as it would never be called from the first.
Thank you, I appreciate all your help!
The primary reason why global variables are discouraged in javascript is because, in javascript all code share a single global namespace, also javascript has implied global variables ie. variables which are not explicitly declared in local scope are automatically added to global namespace. Relying too much on global variables can result in collisions between various scripts on the same page (read Douglas Crockford's articles).
One way to reduce global variables is to use the YUI module pattern. The basic idea is to wrap all your code in a function that returns an object which contains functions that needs to be accessed outside your module and assign the return value to a single global variable.
var FOO = (function() {
var my_var = 10; //shared variable available only inside your module
function bar() { // this function not available outside your module
alert(my_var); // this function can access my_var
}
return {
a_func: function() {
alert(my_var); // this function can access my_var
},
b_func: function() {
alert(my_var); // this function can also access my_var
}
};
})();
now to use functions in your module elsewhere, use FOO.a_func(). This way to resolve global namespace conflicts you only need to change the name of FOO.
Semantics my boy. Semantics.
Start with one global: myApp = {};
Everything should be in that. The only exception would be your AJAX library (there are some extreme exceptions like working with JSONP callbacks).
There should be very few properties in myApp. You'll want to hold your application properties in containers such as config or settings.
myApp = {
config:{
prop:1
},
settings:{
prop:2
},
widgets:{
List: function(props){},
Item: function(props){}
}
}
Then you may have more properties in lower modules, components, singletons and Class constructors (widgets).
This setup gives you the added benefit of being able to access any property from any other location since you can get it with the myApp global. However, you should use "this" whenever possible because the lookup is faster. And just set the property directly, don't bother with the pseudo getter/setter stuff. If you really need a getter/setter, code it for that specific use.
The reason your example doesn't work is it's too generic and you seem to be looking for an excuse to work in the global space.
And don't get clever with private variables. They're bad too:
http://clubajax.org/javascript-private-variables-are-evil/
Global state causes problems in several areas. One is code reuse. When you access some global state that means the component must be aware of it's environment(something outside of itself). You should avoid this as much as possible, because it makes the component unpredictable.
Say I have an object that accesses your globalVariables function and I want to use it in another page. How do I know to define the globalVariables object or even how to define it? However if you can pass the information into a constructor or as an argument to a function then I can easily determine what is required by the object.
Also when you access or modify the global scope then you risk affecting other objects. This is why libraries like jquery use only a single name on the global scope(the least possible). It lessens the possibility of conflict with other libraries. In other words the global scope is out of your control, so it is dangerous.
Using global variables is generaly speaking a bad practice, regardless of the language of choice. They are not even (easily) allowed to use when at strict mode, which I highly recommend.
Consider this piece of code I found:
if (typeof session != 'undefined' && !data.cart.request_status)
data.input_definitions.passengers =
inflate_passenger(session, data.input_definitions.passengers);
I needed to turn around and ask a felow programmer where did this session variable came from, as no code search showed up where was set.
I turned out another package from the company sets the global variable.
Code it's like a joke: if you need to explain it it's probably not that good.
Workaround using ES6:
If at Node, use import or require to bring the desired stuff into lexical scope, don't let people touch your global environment without you knowing it.
import {Sesssion} from 'api-core';
const Session = require('api-core').session;
If you are at the frontend delivering code for the browser you can't use import unless you transpile your ES6 code using Babel.
Example transpiling using Gulp.js:
// $ npm install --save-dev gulp-babel babel-preset-es2015
// gulpfile.js
const gulp = require('gulp');
const babel = require('gulp-babel');
gulp.task('transpile', () => {
return gulp.src('src/app.js')
.pipe(babel({presets: ['es2015']}))
.pipe(gulp.dest('dist'));
});
// $ gulp transpile
Legacy workaround:
When using ES6 features is not an option the only workaround to using a bunch of global variables, is using only one, and have hope:
// scripts/app.js
var MyApp = {
globals: {
foo: "bar",
fizz: "buzz"
}
};
var ASHIVA_HandsOffNHS = (function() {
// VARIABLES
var my_var = 10;
// PRIVATE FUNCTIONS
function bar() {
console.log(my_var + 5);
}
// PUBLIC OBJECT
myObject = {};
myObject['a_func'] = function() {
my_var += 10;
console.log(my_var);
};
myObject['b_func'] = function() {
my_var = 0;
console.log(my_var);
};
return myObject;
})();
ASHIVA_HandsOffNHS.a_func();
ASHIVA_HandsOffNHS.b_func();
ASHIVA_HandsOffNHS.a_func();
The issue with your solution is that it just makes you code harder to understand while still keeping all the downsides of global variables. The page you linked to covers the problems. The only problem your proposed solution really solves is namespace pollution but at the cost of not being able to see what global variables are declared as easily as the declaration is a function call).
The solution is to write code without global variables. If a function needs a value pass it as a argument.
You really don't want to do this.
As to why see e.g. the top post here: What is the most EVIL code you have ever seen in a production enterprise environment?
As a side note, one can always execute "global" code without littering the place with globals:
(function() {
var notaglobal = 1;
alert(notaglobal);
})();
//notaglobal is not defined in this scope
Other answer most explain with anonymous function as this article mention,
Anonymous functions are difficult to debug, maintain, test, or reuse.
Here are example with normal function. It's easier to read and understand.
/* global variable example */
var a= 3, b= 6;
function fwithglobal(){
console.log(a, b); // 3 6 expected
}
fwithglobal(); // first call
function swithglobal(){
var a=9;
console.log(a, b); // not 3 6 but 9 6
}
swithglobal(); // second call
/* global variable alternative(function parameter) */
function altern(){
var a= 3, b= 6; // var keyword needed
f_func(a,b);
s_func(a,b);
}
function f_func(n, m){
console.log(n, m); // 3 6 expected
}
function s_func(n, m){
var a=9;
console.log(n, m); // 3 6 expected
}
altern(); // only once
Global variables are bad... if left unmanaged!
The potential risks of global variables is as high as the pleasure and productivity gains of having frequently used objects ready to use.
I don't believe one should seek a single alternative. Instead I advocate for one object in charge of managing those globals and as the code base/component matures, refactor them out
One thing not mentioned in the current answers which I think is critical is an understanding of DI and IoC containers. These address many of the problems people try to solve with global variables, but covering related concerns that plain globals can't, like object life cycles.

How does the (function() {})() construct work and why do people use it?

(function() {})() and its jQuery-specific cousin (function($) {})(jQuery) pop up all the time in Javascript code.
How do these constructs work, and what problems do they solve?
Examples appreciated
With the increasing popularity of JavaScript frameworks, the $ sign was used in many different occasions. So, to alleviate possible clashes, you can use those constructs:
(function ($){
// Your code using $ here.
})(jQuery);
Specifically, that's an anonymous function declaration which gets executed immediately passing the main jQuery object as parameter. Inside that function, you can use $ to refer to that object, without worrying about other frameworks being in scope as well.
This is a technique used to limit variable scope; it's the only way to prevent variables from polluting the global namespace.
var bar = 1; // bar is now part of the global namespace
alert(bar);
(function () {
var foo = 1; // foo has function scope
alert(foo);
// code to be executed goes here
})();
1) It defines an anonymous function and executes it straight away.
2) It's usually done so as not to pollute the global namespace with unwanted code.
3) You need to expose some methods from it, anything declared inside will be "private", for example:
MyLib = (function(){
// other private stuff here
return {
init: function(){
}
};
})();
Or, alternatively:
MyLib = {};
(function({
MyLib.foo = function(){
}
}));
The point is, there are many ways you can use it, but the result stays the same.
It's just an anonymous function that is called immediately. You could first create the function and then call it, and you get the same effect:
(function(){ ... })();
works as:
temp = function(){ ... };
temp();
You can also do the same with a named function:
function temp() { ... }
temp();
The code that you call jQuery-specific is only that in the sense that you use the jQuery object in it. It's just an anonymous function with a parameter, that is called immediately.
You can do the same thing in two steps, and you can do it with any parameters you like:
temp = function(answer){ ... };
temp(42);
The problem that this solves is that it creates a closuse for the code in the function. You can declare variables in it without polluting the global namespace, thus reducing the risk of conflicts when using one script along with another.
In the specific case for jQuery you use it in compatibility mode where it doesn't declare the name $ as an alias for jQuery. By sending in the jQuery object into the closure and naming the parameter $ you can still use the same syntax as without compatibility mode.
It explains here that your first construct provides scope for variables.
Variables are scoped at the function level in javascript. This is different to what you might be used to in a language like C# or Java where the variables are scoped to the block. What this means is if you declare a variable inside a loop or an if statement, it will be available to the entire function.
If you ever find yourself needing to explicitly scope a variable inside a function you can use an anonymous function to do this. You can actually create an anonymous function and then execute it straight away and all the variables inside will be scoped to the anonymous function:
(function() {
var myProperty = "hello world";
alert(myProperty);
})();
alert(typeof(myProperty)); // undefined
Another reason to do this is to remove any confusion over which framework's $ operator you are using. To force jQuery, for instance, you can do:
;(function($){
... your jQuery code here...
})(jQuery);
By passing in the $ operator as a parameter and invoking it on jQuery, the $ operator within the function is locked to jQuery even if you have other frameworks loaded.
Another use for this construct is to "capture" the values of local variables that will be used in a closure. For example:
for (var i = 0; i < 3; i++) {
$("#button"+i).click(function() {
alert(i);
});
}
The above code will make all three buttons pop up "3". On the other hand:
for (var i = 0; i < 3; i++) {
(function(i) {
$("#button"+i).click(function() {
alert(i);
});
})(i);
}
This will make the three buttons pop up "0", "1", and "2" as expected.
The reason for this is that a closure keeps a reference to its enclosing stack frame, which holds the current values of its variables. If those variables change before the closure executes, then the closure will see only the latest values, not the values as they were at the time the closure was created. By wrapping the closure creation inside another function as in the second example above, the current value of the variable i is saved in the stack frame of the anonymous function.
This is considered a closure. It means the code contained will run within its own lexical scope. This means you can define new variables and functions and they won't collide with the namespace used in code outside of the closure.
var i = 0;
alert("The magic number is " + i);
(function() {
var i = 99;
alert("The magic number inside the closure is " + i);
})();
alert("The magic number is still " + i);
This will generate three popups, demonstrating that the i in the closure does not alter the pre-existing variable of the same name:
The magic number is 0
The magic number inside the closure is 99
The magic number is still 0
They are often used in jQuery plugins. As explained in the jQuery Plugins Authoring Guide all variables declared inside { } are private and are not visible to the outside which allows for better encapsulation.
As others have said, they both define anonymous functions that are invoked immediately. I generally wrap my JavaScript class declarations in this structure in order to create a static private scope for the class. I can then place constant data, static methods, event handlers, or anything else in that scope and it will only be visible to instances of the class:
// Declare a namespace object.
window.MyLibrary = {};
// Wrap class declaration to create a private static scope.
(function() {
var incrementingID = 0;
function somePrivateStaticMethod() {
// ...
}
// Declare the MyObject class under the MyLibrary namespace.
MyLibrary.MyObject = function() {
this.id = incrementingID++;
};
// ...MyObject's prototype declaration goes here, etc...
MyLibrary.MyObject.prototype = {
memberMethod: function() {
// Do some stuff
// Maybe call a static private method!
somePrivateStaticMethod();
}
};
})();
In this example, the MyObject class is assigned to the MyLibrary namespace, so it is accessible. incrementingID and somePrivateStaticMethod() are not directly accessible outside of the anonymous function scope.
That is basically to namespace your JavaScript code.
For example, you can place any variables or functions within there, and from the outside, they don't exist in that scope. So when you encapsulate everything in there, you don't have to worry about clashes.
The () at the end means to self invoke. You can also add an argument there that will become the argument of your anonymous function. I do this with jQuery often, and you can see why...
(function($) {
// Now I can use $, but it won't affect any other library like Prototype
})(jQuery);
Evan Trimboli covers the rest in his answer.
It's a self-invoking function. Kind of like shorthand for writing
function DoSomeStuff($)
{
}
DoSomeStuff(jQuery);
What the above code is doing is creating an anonymous function on line 1, and then calling it on line 3 with 0 arguments. This effectively encapsulates all functions and variables defined within that library, because all of the functions will be accessible only inside that anonymous function.
This is good practice, and the reasoning behind it is to avoid polluting the global namespace with variables and functions, which could be clobbered by other pieces of Javascript throughout the site.
To clarify how the function is called, consider the simple example:
If you have this single line of Javascript included, it will invoke automatically without explicitly calling it:
alert('hello');
So, take that idea, and apply it to this example:
(function() {
alert('hello')
//anything I define in here is scoped to this function only
}) (); //here, the anonymous function is invoked
The end result is similar, because the anonymous function is invoked just like the previous example.
Because the good code answers are already taken :) I'll throw in a suggestion to watch some John Resig videos video 1 , video 2 (inventor of jQuery & master at JavaScript).
Some really good insights and answers provided in the videos.
That is what I happened to be doing at the moment when I saw your question.
function(){ // some code here }
is the way to define an anonymous function in javascript. They can give you the ability to execute a function in the context of another function (where you might not have that ability otherwise).

Categories

Resources