Why do you need to invoke an anonymous function on the same line?

palig picture palig · Jul 16, 2009 · Viewed 297.1k times · Source

I was reading some posts about closures and saw this everywhere, but there is no clear explanation how it works - everytime I was just told to use it...:

// 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
})();

Ok I see that we will create new anonymous function and then execute it. So after that this simple code should work (and it does):

(function (msg){alert(msg)})('SO');

My question is what kind of magic happens here? I thought that when I wrote:

(function (msg){alert(msg)})

then a new unnamed function would be created like function ""(msg) ...

but then why doesn't this work?

(function (msg){alert(msg)});
('SO');

Why does it need to be in the same line?

Could you please point me some posts or give me an explanation?

Answer

SolutionYogi picture SolutionYogi · Jul 16, 2009

Drop the semicolon after the function definition.

(function (msg){alert(msg)})
('SO');

Above should work.

DEMO Page: https://jsfiddle.net/e7ooeq6m/

I have discussed this kind of pattern in this post:

jQuery and $ questions

EDIT:

If you look at ECMA script specification, there are 3 ways you can define a function. (Page 98, Section 13 Function Definition)

1. Using Function constructor

var sum = new Function('a','b', 'return a + b;');
alert(sum(10, 20)); //alerts 30

2. Using Function declaration.

function sum(a, b)
{
    return a + b;
}

alert(sum(10, 10)); //Alerts 20;

3. Function Expression

var sum = function(a, b) { return a + b; }

alert(sum(5, 5)); // alerts 10

So you may ask, what's the difference between declaration and expression?

From ECMA Script specification:

FunctionDeclaration : function Identifier ( FormalParameterListopt ){ FunctionBody }

FunctionExpression : function Identifieropt ( FormalParameterListopt ){ FunctionBody }

If you notice, 'identifier' is optional for function expression. And when you don't give an identifier, you create an anonymous function. It doesn't mean that you can't specify an identifier.

This means following is valid.

var sum = function mySum(a, b) { return a + b; }

Important point to note is that you can use 'mySum' only inside the mySum function body, not outside. See following example:

var test1 = function test2() { alert(typeof test2); }

alert(typeof(test2)); //alerts 'undefined', surprise! 

test1(); //alerts 'function' because test2 is a function.

Live Demo

Compare this to

 function test1() { alert(typeof test1) };

 alert(typeof test1); //alerts 'function'

 test1(); //alerts 'function'

Armed with this knowledge, let's try to analyze your code.

When you have code like,

    function(msg) { alert(msg); }

You created a function expression. And you can execute this function expression by wrapping it inside parenthesis.

    (function(msg) { alert(msg); })('SO'); //alerts SO.