I see this all the time in javascript sources but i've never really found out the real reason this construct is used. Why is this needed?
(function() { //stuff })();
Why is this written like this? Why not just use stuff
by itself and not in a function?
EDIT: i know this is defining an anonymous function and then calling it, but why?
The parentheses encapsulating the function declaration tell the JavaScript engine to execute the code immediately after it's parsed.
Closures are useful because they let you associate data (the lexical environment) with a function that operates on that data. This has obvious parallels to object-oriented programming, where objects allow you to associate data (the object's properties) with one or more methods.
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function.
This is used to create a function closure with private functionality and variables that aren't globally visible.
Consider the following code:
(function(){ var test = true; })();
variable test
is not visible anywhere else but within the function closure where it's defined.
Function closures make it possible for various scripts not to interfere with each other even though they define similarly named variables or private functions. Those privates are visible and accessible only within closure itself and not outside of it.
Check this code and read comments along with it:
// public part var publicVar = 111; var publicFunc = function(value) { alert(value); }; var publicObject = { // no functions whatsoever }; // closure part (function(pubObj){ // private variables and functions var closureVar = 222; var closureFunc = function(value){ // call public func publicFunc(value); // alert private variable alert(closureVar); }; // add function to public object that accesses private functionality pubObj.alertValues = closureFunc; // mind the missing "var" which makes it a public variable anotherPublic = 333; })(publicObject); // alert 111 & alert 222 publicObject.alertValues(publicVar); // try to access varaibles alert(publicVar); // alert 111 alert(anotherPublic); // alert 333 alert(typeof(closureVar)); // alert "undefined"
Here's a JSFiddle running code that displays data as indicated by comments in the upper code.
As you already know this
creates a function:
function() { ... }
and immediately executes it:
(func)();
this function may or may not accept additional parameters.
jQuery plugins are usually defined this way, by defining a function with one parameter that plugin manipulates within:
(function(paramName){ ... })(jQuery);
But the main idea is still the same: define a function closure with private definitions that can't directly be used outside of it.
That construct is known as a self-executing anonymous function, which is actually not a very good name for it, here is what happens (and why the name is not a good one). This:
function abc() { //stuff }
Defines a function called abc
, if we wanted an anonymous function (which is a very common pattern in javascript), it would be something along the lines of:
function() { //stuff }
But, if you have this you either need to associate it with a variable so you can call it (which would make it not-so-anonymous) or you need to execute it straight away. We can try to execute it straight away by doing this:
function() { //stuff }();
But this won't work as it will give you a syntax error. The reason you get a syntax error is as follows. When you create a function with a name (such as abc above), that name becomes a reference to a function expression, you can then execute the expression by putting () after the name e.g.: abc()
. The act of declaring a function does not create an expression, the function declaration is infact a statement rather than an expression. Essentially, expression are executable and statements are not (as you may have guessed). So in order to execute an anonymous function you need to tell the parser that it is an expression rather than a statement. One way of doing this (not the only way, but it has become convention), is to wrap your anonymous function in a set of ()
and so you get your construct:
(function() { //stuff })();
An anonymous function which is immediately executed (you can see how the name of the construct is a little off since it's not really an anonymous function that executes itself but is rather an anonymous function that is executed straight away).
Ok, so why is all this useful, one reason is the fact that it lets you stop your code from polluting the global namespace. Because functions in javascript have their own scope any variable inside a function is not visible globally, so if we could somehow write all our code inside a function the global scope would be safe, well our self-executing anonymous function allows us to do just that. Let me borrow an example from John Resig's old book:
// Create a new anonymous function, to use as a wrapper (function(){ // The variable that would, normally, be global var msg = "Thanks for visiting!"; // Binding a new function to a global object window.onunload = function(){ // Which uses the 'hidden' variable alert( msg ); }; // Close off the anonymous function and execute it })();
All our variables and functions are written within our self-executing anonymous function, our code is executed in the first place because it is inside a self-executing anonymous function. And due to the fact that javascript allows closures, i.e. essentially allows functions to access variables that are defined in an outer function, we can pretty much write whatever code we like inside the self-executing anonymous function and everything will still work as expected.
But wait there is still more :). This construct allows us to solve a problem that sometimes occurs when using closures in javascript. I will once again let John Resig explain, I quote:
Remember that closures allow you to reference variables that exist within the parent function. However, it does not provide the value of the variable at the time it is created; it provides the last value of the variable within the parent function. The most common issue under which you’ll see this occur is during a for loop. There is one variable being used as the iterator (e.g., i). Inside of the for loop, new functions are being created that utilize the closure to reference the iterator again. The problem is that by the time the new closured functions are called, they will reference the last value of the iterator (i.e., the last position in an array), not the value that you would expect. Listing 2-16 shows an example of using anonymous functions to induce scope, to create an instance where expected closure is possible.
// An element with an ID of main var obj = document.getElementById("main"); // An array of items to bind to var items = [ "click", "keypress" ]; // Iterate through each of the items for ( var i = 0; i < items.length; i++ ) { // Use a self-executed anonymous function to induce scope (function(){ // Remember the value within this scope var item = items[i]; // Bind a function to the element obj[ "on" + item ] = function() { // item refers to a parent variable that has been successfully // scoped within the context of this for loop alert( "Thanks for your " + item ); }; })(); }
Essentially what all of that means is this, people often write naive javascript code like this (this is the naive version of the loop from above):
for ( var i = 0; i < items.length; i++ ) { var item = items[i]; // Bind a function to the elment obj[ "on" + item ] = function() { alert( "Thanks for your " + items[i] ); }; }
The functions we create within the loop are closures, but unfortunately they will lock in the last value of i
from the enclosing scope (in this case it will probably be 2 which is gonna cause trouble). What we likely want is for each function we create within the loop to lock in the value of i at the time we create it. This is where our self-executing anonymous function comes in, here is a similar but perhaps easier to understand way of rewriting that loop:
for ( var i = 0; i < items.length; i++ ) { (function(index){ obj[ "on" + item ] = function() { alert( "Thanks for your " + items[index] ); }; })(i); }
Because we invoke our anonymous function on every iteration, the parameter we pass in is locked in to the value it was at the time it was passed in, so all the functions we create within the loop will work as expected.
There you go, two good reasons to use the self-executing anonymous function construct and why it actually works in the first place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With