10

Possible Duplicate:
What do parentheses surrounding a JavaScript object/function/class declaration mean?
What does this “(function(){});”, a function inside brackets, mean in javascript?
A Javascript function

I encountered markup similar to this:

var something = (function(){
    //do stuff
    return stuff;
})()
document.ondblclick = function(e) { alert(something(e)) };

I don't understand the opening ( and closing )() in the something variable. Could you explain the difference to writing it like this?

var something = function(){
    //do stuff
    return stuff;
};

Thanks!

Community
  • 1
  • 1
Sean Bone
  • 3,368
  • 7
  • 31
  • 47
  • 5
    `()` invokes the function, the other parens are redundant. So in the second case `something` would be assigned to the function and in first case `something` would be assigned to `stuff` – Esailija Aug 03 '12 at 12:40
  • go to google, type 'JavaScript closure' and start reading :) – Elias Van Ootegem Aug 03 '12 at 12:41
  • 1
    Both are function expressions. The first looks like an attempt to explicitly make it a function expression. For instance, remove `var something =`, and the first will still run. However, when the parentheses at the edges are removed, an error will be thrown: "function statement requires a name" (assuming that the writer has thought about this, of course!). The first is immediately invoked, so `something` references the **value of the `stuff` variable**. The latter `something` is a **reference to a function**. When called, it refers to the value of the `stuff` variable at that moment. – Rob W Aug 03 '12 at 12:43
  • @EliasVanOotegem: That depends on the returned `stuff`, see [Is the following JavaScript construct called a Closure?](http://stackoverflow.com/q/3872604/1048572) – Bergi Aug 03 '12 at 12:45
  • @Esailija @RobW meaning that in the first case the function is executed every time I use the `something` variable (which could therefore change every time), but in the second case the function is executed only at the variable declaration, and `something` always returns the same value? – Sean Bone Aug 03 '12 at 12:47
  • @Sean in the first case, `something` is `stuff`, whatever that is. In the second case `something` is just that function. – Esailija Aug 03 '12 at 12:49
  • @Sean In the first case, the `something` variable does **not** hold a function reference. The parentheses after the function **immediately** call the function, so the return value is stored in `something`. In the second case, `something` is a function. The return value depends on an external variable, so it might be different. – Rob W Aug 03 '12 at 12:53
  • @Bergi: well, stuff is a function here, because the snippet goes on to do this: `something(e)`. – Elias Van Ootegem Aug 03 '12 at 12:54
  • @RobW: in the first case, `stuff` is a function reference though... as I said in my comment to Bergi – Elias Van Ootegem Aug 03 '12 at 12:55
  • @EliasVanOotegem It is *expected* to be a function reference (as seen in the `ondblclick` event). In the second function, `stuff` is expected to be a string though. – Rob W Aug 03 '12 at 12:57
  • @RobW, no it isn't: the event object (e) is being passed to it: I'm yet to see working code where a string constant accepts an argument... – Elias Van Ootegem Aug 03 '12 at 12:59
  • @EliasVanOotegem @RobW Yes, in the original code `stuff` is a function... – Sean Bone Aug 03 '12 at 13:10
  • Thank you everyone for your quick and very good answers and comments! It's not easy but I think I understood it, very useful! Thanks again! – Sean Bone Aug 03 '12 at 13:38

5 Answers5

5

(function(){ ... }) is a (anonymous) function expression, you could e.g. assign that value to a variable.

The brackets behind it will immidiately execute the function expression, resulting in the return value of the function (in here: stuff). The construct is called IIFE.

When stuff is a function (which I assume, because you invoke something lateron), this is called a closure - the returned function (stuff, assigned to something) still has access to the variables in the execution context of that anonymous function.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
5

It's probably easier to understand if you leave the redundant parens out because they serve no purpose:

var something = function() {
    return 3;
} // <-- a function. 
(); // now invoke it and the result is 3 (because the return value is 3) assigned to variable called something 

console.log(something) //3 because the function returned 3 

var something = function() {
    return 3;
}; // a function is assigned to a variable called something

console.log(something) //logs the function body because it was assigned to a function
console.log(something()) //invoke the function assigned to something, resulting in 3 being logged to the console because that's what the function returns
Esailija
  • 138,174
  • 23
  • 272
  • 326
  • Accepted this answer because it was the simplest and clearest to me, but really all answers were correct and extremely useful! Thank you!! – Sean Bone Aug 03 '12 at 13:40
  • @Sean thanks a lot, I was about to delete it because it was not getting upvotes :P – Esailija Aug 03 '12 at 13:49
  • I'd rather add those redundant parens. JSLint says: "Wrap an immediate function invocation in parentheses to assist the reader in understanding that the expression is the result of a function, and not the function itself." – Bruno Schäpper Aug 03 '12 at 13:59
  • 2
    @VainFellowman yes I was afraid someone that agrees with crockford would come here and comment that. I disagree because I would just make a function declaration (`function something(){}`) if the result would just be the function itself anyway. The declaration is easier to write and you get a named function for free as well. But this is just an opinion as is what JSLint says. – Esailija Aug 03 '12 at 14:01
  • @Esailija good point. Having a named function is a good thing anyway, for example in debugging. Adding those parens is a good habit I think, it costs no extra time and is way easier to understand. – Bruno Schäpper Aug 03 '12 at 14:04
  • @VainFellowman @Esailija think I got it now... So I could write: `var tag = document.createElement("script"); tag.src = fileName; tag.onload = function(arg1, arg2) { return function() { alert (arg1 + arg2); }; }('Script ', 'loaded!'); document.body.appendChild(tag);` and it would alert `Script loaded!` when the script loads, correct? Not that this example itself has much sense :) – Sean Bone Aug 04 '12 at 06:06
  • Ok - all clear now. Thanks a LOT guys! – Sean Bone Aug 06 '12 at 12:39
4

On the question what it does, read all the comments and other answers. They are absolutely right.

Why would you want to use it? You find this pattern very often when using closures. The intent of the following code snippet is to add an event handler to 10 different DOM elements and each one should alert it’s ID attribute (e.g. “You’ve clicked 3″). You should know that if this was your actual intent, then there is a much easier way to do this, but for academic reasons let’s stick with this implementation.

var unorderedList = $( "ul" );
for (var i = 0; i < 10; i++) {
    $("<li />", {
        id: i,
        text: "Link " + i,
        click: function() {
            console.log("You've clicked " + i);
        }
    }).appendTo( unorderedList );
}

The output of the above code may not be what you first expect. The result of every click handler will be “You’ve clicked 9″ because the value of i at the point the event handler was fired is “9″. What the developer really wanted is for the value of i to be displayed at the point in time the event handler was defined.

In order to fix the above bug we can introduce a closure.

var unorderedList = $( "ul" ), i;

for (i = 0; i < 10; i++) {
    $("<li />", {
        id: i,
        text: "Link " + i,
        click: function(index) {
            return function() {
                console.log("You've clicked " + index);
            }
        }(i)
    }).appendTo( unorderedList );
}

You can execute and modify the above code from jsFiddle.

One way to fix the above code is to utilize a self-executing anonymous function. That is a fancy term that means we are going to create a nameless function and then immediately call it. The value of this technique is that the scope of the variable stays within the function. So, first we will surround the event handler content in a function and then immediately call the function and pass in the value of i. By doing that, when the event handler is triggered it will contain the value of i that existed when the event handler was defined.

Further reading on closures: Use Cases for JavaScript Closures

Bruno Schäpper
  • 1,262
  • 1
  • 12
  • 23
  • 1
    Many words to say a simple thing. Do you really need to throw in unrelated jQuery syntax to confuse the OP? – Rob W Aug 03 '12 at 12:46
  • Your answer in the comments is perfectly right of course (+1 btw). It's an example of a simple use case. And I guess jQuery is widely known, so it makes sense to use it in an example one could actually come accross. – Bruno Schäpper Aug 03 '12 at 12:50
  • You said *"In order to fix the above bug we can introduce a closure."*, but the function you assign to `click` in the first example **is a already a closure** (it closes over `i`). Using a closure is not the way to solve that problem, making a function call and creating a new scope is the solution. That's what you have done in the second example, but you have not introduced a new closure (at least you are not using it as such). – Felix Kling Aug 03 '12 at 12:56
  • @Felix Kling yes, you are right. It is a closure too. By using a self executing anonymous function, we create a new scope, as you state in your comment. – Bruno Schäpper Aug 03 '12 at 13:00
2

All of the answers were good, but I think the simplest answer has been skimmed over:

var something = (function(){
    //do stuff
    return stuff;
})()

After this code executes, something becomes stuff. The function that returned stuff is executed before something is assigned.

var something = function(){
    //do stuff
    return stuff;
};

After this code executes, something is a function which returns stuff. The function that returns stuff was never executed.

AlexMA
  • 9,842
  • 7
  • 42
  • 64
1

Check the JavaScript FAQ section, too: Here are some pretty good explanations and examples

Ok, why should you use this:

Suppose my script is running, and there are a couple of things (I'm, for instance, looping through a nodes list) I might be needing later on. That's why I might choose to do something like this:

for(var i=0;i<nodesList.lenght;i++)
{
    if (nodesList[i].id==="theOneINeed")
    {
        aClosure = (function(node,indexInNodesList)//assign here
        {
            return function()
            {
                node.style.display = 'none';//usable after the parent function returns
                alert(indexInNodesList+ ' is now invisible');
            }
        })(nodesList[i],i);//pass the element and its index as arguments here
        break;
    }
}
i = 99999;
aClosure();//no arguments, but it'll still work, and say i was 15, even though I've just 
//assigned another value to i, it'll alert '15 is now invisible'

What this enables me to do is to prevent function arguments from being garbage collected. Normally, after a function returns, all its var's and arguments are GC'd. But in this case, the function returned another function that has a link to those arguments (it needs them), so they're not GC'ed for as long as aClosure exists.

As I said in my comment. Google closures, practice a bit, and it'll dawn on you... they really are quite powerful

Community
  • 1
  • 1
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • You are mixing the concept of closures and self-invoking functions, which can be very confusing. – Felix Kling Aug 03 '12 at 13:07
  • you're right, but I merely wanted to point out to why you might want to use them. A closure was the first thing that sprung to mind. Especially because in the snippets the OP provided, the return value/object is a function. Looked like a closure to me – Elias Van Ootegem Aug 03 '12 at 13:23