Make Your JavaScript Better With Self Executing Anonymous Functions
As I have matured my AJAX skills over the past few years I have settled on some standard patterns that seem to be best practices by many. One that I was sort of late in adopting was anonymous self-executing anonymous functions. I had seen them used, especially since if you look at any popular JavaScript library like jQuery's source. Often I found myself wondering what they were at the time, but have since found their value. They not only help you organize your code they can also be a useful defensive coding technique. One thing I found they do offer is a nicer way to encapsulate JavaScript modules.
Like I said I had seen the use of anonymous functions many times, but it did not click why I should use them until I watched Paul Irish's 10 things I learned from the jQuery source code and his follow up of 11 more things. Both of these videos are required watching for any web developer. In those videos he explains how anonymous functions are used in jQuery to initialize variables as well as make sure undefined is exactly that, undefined.
So what does an anonymous enclosure look like?
(function
() {
...
}());
What is going on with the above syntax? First is the outer () set. This is done more for organization than anything else. Anything inside the parenthesis is nicely encapsulated together. Inside the () is an anonymous function. Its anonymous because there is no name assigned to it. The function can have parameters passed in, as we will see in a moment, just like any other function. Inside the function is the actual code you want to execute. After the function definition is another set of parenthesis. This last pair of () causes the function to execute as soon as it is evaluated.
Why is that last set of () so important? Without those parenthesis the variable would need to be called or executed somewhere else in the code. Since this is an anonymous function there is no name or variable to reference and call. Just to illustrate my point lets look at a normal function definition.
function
foo(){
alert("foo"
);
}
This is a pretty basic function definition and creates a JavaScript function named foo. However it does not execute when the code is evaluated by the JavaScript engine. It still needs to be called to cause the alert box to display.
foo();
http://jsfiddle.net/docluv/3qXyp/
But if we used an anonymous self-executing function the alert will automatically display when the code is evaluated.
(function (){
alert("foo");
}());
http://jsfiddle.net/docluv/nY7cC/1/
What if you do not want the alert box to automatically display? This is where these self-executing functions get very useful. You can define objects or variables within the anonymous function and call them from outside the function definition. Typically you will want to define a single object or function within the anonymous enclosure, but in theory you can define multiple objects.
First lets define a function inside the anonymous enclosure.
(function
(){var
foo =function
(){
alert("foo"
);
};
foo();
}());
http://jsfiddle.net/docluv/49pJv/1/
In the above function definition a variable named foo is instantiated inside the anonymous method. It is set to a function that calls the alert method. After the variable is defined it is called, within the anonymous enclosure. I did this to prove a point. If you place the foo() call outside the anonymous function definition you will get an error because foo does not exist outside the enclosure. This is a good thing because it keeps you from polluting the global namespace, etc. Any variable defined within the enclosure is available while the anonymous function is being executed. So I called foo at the end of the enclosure and you will get the alert box displayed.
So how can you access the object(s) defined within an anonymous function? The easiest way is to create a global variable or extend and existing global object, like jQuery. This is what jQuery does. When you extend jQuery with a plugin or extension method you are doing the same thing by extending jQuery.fn. The following example follows the pattern used in the jQuery library.
(function
(){var
foo =function
(){
alert("foo"
);
};return
(window.foo = foo);
}());
foo();
http://jsfiddle.net/docluv/RcALA/2/
Now if you want to create a new JavaScript object you could. Simply add members as needed, and they can be called from you code like the following:
(function
() {var
foo =function
() {
};
foo.fooo =function
() {
alert("foo"
);
};
foo.bar =function
() {
alert("bar"
);
};return
(window.foo = foo);
}());
foo.fooo();
foo.bar();?
http://jsfiddle.net/docluv/ZJJSp/4/
Ok now it gets real doesn't it? I took the previous definition and extended it. The variable foo is extended with two function definitions, fooo and bar. If you look at the foo object in a watch window, like IE's F12 tools, the WebKit Developer Tools or FireBug you will see something like this:
foo: function () {
arguments: null
bar: function () {
caller: null
fooo: function () {
length: 0
name: ""
prototype: Object
__proto__: function Empty() {}
You will notice it contains the two function definitions fooo and bar. This is because the original foo object was extended right after it was defined. Because there is nothing to initialize in foo we can just use the global instance to call the two child methods. Now lets extend the foo object outside the anonymous enclosure with a new method, baar. It will display a confirmation dialog instead of a boring alert box.
(function
() {var
foo =function
() {
};
foo.fooo =function
() {
alert("foo"
);
};
foo.bar =function
() {
alert("bar"
);
};return
(window.foo = foo);
}());
foo.baar =function
() {
confirm("cool huh?"
);
};
foo.fooo();
foo.bar();
foo.baar();?
http://jsfiddle.net/docluv/JhYSr/1/
You can extend the method just like any other JavaScript object, which is how a jQuery plugiin extends jQuery. In fact you can enclose it within its own anonymous method.
(function
() {var
foo =function
() {
};
foo.fooo =function
() {
alert("foo"
);
};
foo.bar =function
() {
alert("bar"
);
};return
(window.foo = foo);
}());
(function
() {
foo.baar =function
() {
confirm("cool huh?"
);
};
}());
foo.fooo();
foo.bar();
foo.baar();?
http://jsfiddle.net/docluv/JhYSr/2/
Why is this important to know or even bother with you may ask? Well a plugin is typically done in its own file, not in the core jQuery file. One of the key benefits of using an anonymous JavaScript enclosure is to provide a little firewall of sorts. If you look at the jQuery source you will notice how variables are passed to the anonymous enclosing method.
(function
( window, undefined ) {//...jQuery goes here
)(window);
First is the window object itself, I am not really clear why this parameter is being passed, but I see this done a lot in various JavaScript libraries. The window object is available inside the anonymous method because it is the global object. But the second parameter is rather ingenious, undefined. Why should you follow this pattern? It is a defensive programing technique. Most of us use a lot of third party libraries, many of which are just free things we find online. Very few of us takes the time to review each line of code in these libraries, seriously no one does. Plus once they are minimized it makes it extremely difficult to do. Who's to say someone does not put the following line in their code:
undefined = function(){ //The Brain's code to take over the world};
By defining a variable named undefined, but not passing anything for that variable it is automatically defined as the undefined we know and love.
But wait there is more. You can pass any variables you want to an anonymous enclosure to make sure they are what you want them to be. A common example is jQuery is commonly referred to using the $ variable instead of jQuery. So the following enclosure will ensure $ is jQuery and not something else.
(function
( window, $, undefined ) {//...your code goes here
)(window, jQuery);
Now of course someone could rename jQuery to whatever they would like, but you should get the point by now. I use this technique to initialize or create objects for parameters that do not exist. In the following example I use a coalesce technique to create an empty object to represent foo if it does not exist.
(function
( window, foo, undefined ) {//...jQuery goes here
)(window, foo || {});
Conclusion
Anonymous self-executing functions are very important coding patterns every JavaScript programmer should learn to use on a daily basis. They provide a nice way to organize your code, allow it to be extended and give a simple layer of variable defense.