I have always seen code like this:
(function(){
//code here
})();
How does this code work? Which function receives which parameters?
<function($){
//other code here
}
This block is passed as a parameter to the outer IIFE. It might be clearer to write it like this:
var factoryDef = function($) { ... };
(function(factory) {
// this is the outer IIFE
var someVar = {};
// you can call:
factory(someVar);
// the previous line calls factoryDef with param someVar
}(factoryDef));
So factory(someVar)
is the same as factoryDef({})
; the latter is simply the value of factory
(which is the function factoryDef
) called with the value of someVar
(which is {}
.)
Does that make sense?
Let's dissect:
Another way to look at this is:
Starts with an anonymous function declaration assigning within the function, the first parameter to be passed, the variable name "factory",
Then the anonymous function is immediately invoked, so far so good, often called IIFE, (or in this case D.C. calls "dog balls" ;) ).
Here's a twist, within the immediate invoking of the outer-most function another anonymous function is declared and passed as an argument. This, of course is referred to as "factory" within the outer-most function. And,
This inner-most anonymous function has as a named parameter "$". So I must anticipate the outer most function, when calling "factory", the inner-most function, will pass something to it which will be referred to as "$" in the inner-most function. For example: factory(jQuery);
.
Actually when reading code I think it's best to start at the end and inner. So here the first thing I look at is the function with the "$". Looks like an anonymous function declaration. And it happens to be instantiated in a function execution. Moving out and left now. The function that is being immediately executed is also an anonymous function, not a problem because it's only called once and it's execution is built it. And our inner-most anonymous function get's a name in the outer-most function declaration. Finally wrapping the whole deal in parentheses is necessary to put the anonymous function in an expression context. If the first thing on the line is the word "function" then the function is in declaration context and the Javascript parser won't allow it to be immediately invoked. Oops.
Even more stretched out looks like:
var innerMost = function($) { console.log($); };
var outerMost = function(factory) {
var kaChing = 'baLing';
factory(kaChing);
};
outerMost(innerMost);
Voilà!
.
Fiddle with this: http://jsfiddle.net/xFnP7/1/
Much more here: http://benalman.com/news/2010/11/immediately-invoked-function-expression/