4

I always use the following self executing function in order to avoid exposing my code to global scope in JavaScript:

(function() { 
    //Code comes here
})();

I believe that this is also called self executing anonymous function as well. Sometimes, I also see the below code used for the same purpose:

(function(d){
    //Code comes here
})(document.documentElement);

I am not sure what makes the difference here so I am asking this question.

What is the difference (or are the differences) between these two types of self executing function on JavaScript?

tugberk
  • 57,477
  • 67
  • 243
  • 335
  • 10
    The first function is not taking any parameters, whereas the second one does. – Rob W Dec 04 '11 at 18:58
  • Ok, I figured that but `document.documentElement` can be also used inside the function. Why is it being used like that? – tugberk Dec 04 '11 at 19:00
  • 1
    Functions in Javascript are never "self-executing", whether they are anonymous or not. There is always a *call* to the function somewhere if they execute at all. Your call is right before the semicolon. – Greg Hewgill Dec 04 '11 at 19:00
  • @GregHewgill hmm, so the term I used wrong? I always hear that term but it is used metaphorically I guess in this case. Also is this code is the same with the first one I referenced above: `(function(w){})(window);` – tugberk Dec 04 '11 at 19:03
  • @GregHewgill is technically correct, but it's true that this idiom is commonly known as a self-executing anonymous function :) re window, see my answer – Anentropic Dec 04 '11 at 19:06
  • 2
    The term is erroneous, but generally understood amongst most JS programmers these days to refer to the example above. There are a lot of people advocating for the term Immediately Invoked Function Expression (IIFE, pronounced "iffy") that I think makes more sense. – Kevin Ennis Dec 04 '11 at 19:08

6 Answers6

8

The code below demonstrates what's happening. In reality, the foo and bar variables don't exist, and the functions are anonymous.

var foo = function() {}
foo();

var bar = function(d){}
bar(document.documentElement);

The (function(d){})(d) method is called a closure. It's used to pass variable values which are subject to change, such as in loops.

Have a look at a practical an example:

for(var i=0; i<10; i++) {
    document.links[i].onclick = function(){
        alert(i); //Will always alert 9
    }
}

After implementing the closure:

for(var i=0; i<10; i++) {
    (function(i){
        document.links[i].onclick = function(){
            alert(i); //Will alert 0, 1, ... 9
        }
    })(i);
}
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Thanks. Your examples are very interesting and useful. I am still trying to figure out why it always alert 9 on the second sample:) – tugberk Dec 04 '11 at 19:09
  • @tugberk Because the loop walks from zero to nine, updating variable `i` at each enumeration. When the user clicks at the link, the `i` variable is displayed - which equals `9`, per last update. – Rob W Dec 04 '11 at 19:11
  • last question. Are these two the same when they are used inside the DOM: `(function(){})();` and `(function(w){})(window);` – tugberk Dec 04 '11 at 19:13
  • 1. Why use function expressions here instead of function declarations? 2. The thing you're calling a "closure" is **not** a closure. – Matt Ball Dec 04 '11 at 19:20
  • Only if you define a variable `w` in the first function. – Rob W Dec 04 '11 at 19:20
  • @MДΓΓБДLL 1. `here`, inside the loop I assume? To show a parellel to the format as presented in the question. 2. I meant, in the context of the last example, it's creating a closure. You're right that the expression itself is not a closure. – Rob W Dec 04 '11 at 21:47
  • 1. No, `here` referring to `foo` and `bar` (you edited your answer when I first noticed it, but before I actually commented). 2. Yes, let's try to keep things simple for the n00bs, but it's equally important to not mislead them. Too many times, I've seen anonymous functions conflated with closures. Fight the ignorance! – Matt Ball Dec 04 '11 at 21:50
  • @MДΓΓБДLL 1. I posted my answre as a follow-up of my comment at the OP. Strictly, they're not equal. But for the sake of understanding that the first and second expressions at the OP are equal, I have rewritten the code in a -very likely- more familiar form. – Rob W Dec 04 '11 at 21:54
3

Remember that function arguments and variables are the same thing, deep down.

The second example is (basically) just shorthand for

(function(){
    var d = document.documentElement;
}());

since it avoids the need for the var and the =.

There are some common uses for this pattern:

  1. Creating lexically scoped variables (just remembered this after seeing Rob's answer...)

    //this does not work because JS only has function scope.
    // The i is shared so all the onclicks log N instead of the correct values
    for(var i = 0; i< N; i++){
       elems[i].onclick = function(){ console.log(i); }
    }
    
    //Each iteration now gets its own i variable in its own function
    // so things work fine.
    for(var i=0; i<N; i++){
       (function(i){
           elems[i].onclick = function{ console.log(i); };
       }(i));
    }
    

    In this case, passing the parameters directly allows us to reuse the same variable name inside, in a way that var i = i would not be able to. Also, the conciseness is a benefit, since this is just a boilerplate pattern that we don't want to dominate over the important code around it.

  2. It makes it easy to convert some old code without having to think too much about it

    (function($){
       //lots of code that expected $ to be a global...
    }(jQuery)) //and now we can seamlessly do $=jQuery instead.
    
  3. Parameters that are not passed are set to undefined. This is useful since normally undefined is just a global variable that can be set to different values (this is specially important if you are writing a library that needs to work w/ arbitrary third party scripts)

    (function(undefined){
       //...
    }())
    
hugomg
  • 68,213
  • 24
  • 160
  • 246
0

The first function takes no parameters. The second one takes a single parameter. Inside the function, the parameter is d. d is set to document.documentElement when the function is called.

Trott
  • 66,479
  • 23
  • 173
  • 212
0

It looks like the author of the second code wants to use d as a shorter way to write document.documentElement inside the function.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
0

One reason for using the second form, with the argument, is that insulates your code against other js code loaded later on the page (eg other libraries or framework code) that might re-define the variable passed in as the argument.

One common example would be if the code within your self-executing anonymous function relies upon jQuery and wants to use the $ variable.

Other js frameworks also define the $ variable. If you code your function as:

(function($){

    //Code comes here

})(jQuery);

Then you can safely use $ for jQuery even if you load some other library that defines $.

I have seen this used defensively with people passing in all the 'global' variables they need inside their block, such as window, document, jQuery/$ etc.

Better safe than sorry, especially if you use a lot of 3rd party widgets and plugins.

Update:
As others have pointed out the set of parentheses around the function are a closure. They are not strictly neccessary a lot of times where this pattern is used (@Rob W gives a good example where they're essential) but say you have a very long function body... the outer parentheses say to others reading the code that the function is probably self-executing.

Best explanation I saw of this pattern is in Paul Irish's video here: http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/ starting about 1:30

This SO question also has some informative answers: How do you explain this structure in JavaScript?

Community
  • 1
  • 1
Anentropic
  • 32,188
  • 12
  • 99
  • 147
0

if you want to pass arguments to the self executing anonymous functions, use the second one. It might come in handy when you want to use variables in the function that have the same name with others in the global scope :

var a = "I'm outside the function scope",
    b = 13;
alert(a);
alert(b);
(function(a,b){
     // a is different from the initial a
     alert(a);
     // same goes for b
     alert(b);
})("I'm inside the function scope",Math.PI);

It can also be useful to use something like :

var a;
console.log(a === undefined); // true
undefined = true;
console.log(a === undefined); // false
(function(undefined){
    console.log(a === undefined); // true, no matter what value the variable "undefined" has assigned in the global scope
})();

when trying to implement the null object design pattern

If you are concerned about efficiency, you might end up using something like this :

var a = 2;
(function(window){
    alert(a);
    // accessing a from the global scope gets translated 
    // to something like window.a, which is faster in this particular case
    // because we have the window object in the function scope
})(window);
gion_13
  • 41,171
  • 10
  • 96
  • 108