admin管理员组

文章数量:1316512

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

(function() { 
    //Code es 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 es 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?

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

(function() { 
    //Code es 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 es 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?

Share Improve this question edited Dec 4, 2011 at 19:04 tugberk asked Dec 4, 2011 at 18:57 tugberktugberk 58.5k69 gold badges251 silver badges342 bronze badges 6
  • 10 The first function is not taking any parameters, whereas the second one does. – Rob W Commented Dec 4, 2011 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 Commented Dec 4, 2011 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 Commented Dec 4, 2011 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 Commented Dec 4, 2011 at 19:03
  • 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 Commented Dec 4, 2011 at 19:08
 |  Show 1 more ment

6 Answers 6

Reset to default 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);
}

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 mon 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){
       //...
    }())
    

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.

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

if you want to pass arguments to the self executing anonymous functions, use the second one. It might e 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);

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 mon 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 es 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./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?

本文标签: Difference between these two types of self executing function on JavaScriptStack Overflow