2

Possible Duplicate:
javascript function vs. ( function() { … } ());

Sorry if this is too basic, but what is this construct do?

(function MyFunction() {
  /* Some codes ... */    
})();

Maybe there is a special term for that? It can be useful for Googling, instead of just putting that snippet in the search field.

Community
  • 1
  • 1
moey
  • 10,587
  • 25
  • 68
  • 112
  • 2
    It's an self-invoking anonymous function. `MyFunction` outside this declaration will not refer to the function, but inside it, `MyFunction` can be used to invoke itself again. – Rob W Dec 28 '11 at 13:44
  • Please note, in IE ( lte 8 ) MyFunction will be leaked to global scope :) [http://jsfiddle.net/DEn4e/](http://jsfiddle.net/DEn4e/) – abuduba Dec 28 '11 at 14:02

5 Answers5

6

It's called the direct invocation pattern. It defines an anonymous function, and then immediately executes it. This is useful for 'private' variables and such. If you'd normally do this:

// global namespace
var data = 'lol';
function getData() {
  return data;
}

there'd be a variable data in the global namespace and if someone entered data = 123 in a web console it could break your script. Using the direct invocation pattern, you can do this:

// global namespace
/*lotsofcodehere*/
(function MyFunction() {
  // closure namespace
  var data = 'lol';
  this.getData = function getData() {
    return data;
  }
})();
// global again

In this case, the function getData will still exist in the global namespace, but data will be inaccessible from outside the closure namespace.

You'll also notice MyFunction won't exist in the global namespace when using this pattern. That is because of one of many small language rules, but basically a function is always available by it's name inside the function. If you have something like this:

// returns the amount of from--s needed to get to 0 :D
// (yes, it returns it's input number :D)
(function() {
var i = 0, keep = false;

this.countToZero = function(from) {
  if(from === 0) {
    keep = false; // don't keep i's contents on next invocation
    return i;
  }
  if(!keep) i = 0; // reset i on first invocation
  i++;
  keep = true;
  return countToZero(from - 1);
}
})();

It works perfectly, and countToZero(5) will nicely return 5. But well, it's not really nice if you use it in the non-global namespace, if this is used inside a function it'll define countToZero as a member property of that function, which will break our return (as countToZero is no longer accessible through the global namespace)
This is not a realistic scenario perhaps, but it works for this example. Instead of the above code, we'll use this:

/*code*/
this.countToZero = function countToZero(from) {
  // countToZero will *always* exist here as a reference to this function!
  /*code*/
  return countToZero(from);
};

This code is quite hard to break, except if you pass Infinity as the first param of course, even if you use it in completely ridiculous ways.

...

did I say I was going to provide clear explanation or nice, real-life examples? I hope I didn't

goto-bus-stop
  • 11,655
  • 2
  • 24
  • 31
  • 1
    If I understand this correctly, that anonymous function will immediately execute. But, how can we get the return value i.e. `data`? Is it assignable to a different variable? – moey Dec 28 '11 at 13:57
  • 1
    You can not access `data` from outside the function, as it is a variable private to that function. Functions can, however, access all variables in functions *above* them, so `data` is available to `getData`. There's probably a better explanation out there somewhere, a search query for 'function scoping javascript' should do the trick ;) – goto-bus-stop Dec 28 '11 at 14:04
  • 1
    `data` is available within the function it is defined in. You either pass it around as an argument in other function calls or bind to events which will be called once those events happen. – igorw Dec 28 '11 at 14:17
4

It creates and executes the function MyFunction without placing it on the global namespace. This is a good way to avoid namespace pollution. Once executed, it cannot ever be executed again, since it wasn't actually saved anywhere.

Tom van der Woerdt
  • 29,532
  • 7
  • 72
  • 105
2

This basically invokes code in MyFunction() without adding it to the global namespace, needless to say ofcourse that variables defined in MyFunction will not be available in global as well.

I've seen this construct most of the times in conjunction with the need to execute a piece of code that has recursive logic that needs to be hidden, e.g. traversal of certain sub subdocuments to the page.

MahdeTo
  • 11,034
  • 2
  • 27
  • 28
1

It's a self-executing function. You define the function, with or without a name, and immediately execute it.

Josh Smeaton
  • 47,939
  • 24
  • 129
  • 164
0

function is called immediately after define it.

This works that :

function MyFunction() {
  /* Some codes ... */    
} 
MyFunction(); 

But does not have access to MyFunction in the global scope, That means - you don't have acces from anywhere ( except IE <= 8 => http://jsfiddle.net/DEn4e/) Therefore do not recommend because it causes leaks variables to global scope :)

abuduba
  • 4,986
  • 7
  • 26
  • 43
  • 1
    This is not strictly equivalent as MyFunction in your example is accessible beyond the invocation and can be called normally. – MahdeTo Dec 28 '11 at 13:49
  • 1
    **That is not true.** It doesn't get stored on the global namespace, which does happen in your case. – Tom van der Woerdt Dec 28 '11 at 13:49
  • Really? put to address bar in ie : `javascript:(function MyFunction() { })();alert( MyFunction);` – abuduba Dec 28 '11 at 13:56
  • The code in the question won't make the function globally available, but the code in this answer will. I think that's what the previous comments were saying. – nnnnnn Dec 28 '11 at 14:01
  • Check this out on IE lte 8 => [http://jsfiddle.net/DEn4e/](http://jsfiddle.net/DEn4e); If you have IE9 press F12 to set compability mode. Unfortunately still a lot of people are working on these versions – abuduba Dec 28 '11 at 14:06