Why would one write global code inside a function definition-call pair?

后端 未结 5 1645
轮回少年
轮回少年 2020-12-19 08:27

I see examples where JavaScript code including jQuery and jslint use the notation below:

(function(){
  // do something
})();

instead of:

相关标签:
5条回答
  • 2020-12-19 08:47

    The main purpose of this (Crockford's) pattern (there are others -- in some cases more performant -- too) is to avoid the pollution of the global scope with named functions/identifiers. By doing stuff within this anonymous closure, you can write your code as you'd do inside the global scope, except that everything declared inside remains local and thus cannot be accessed/referenced from outside. Use-cases where no local variables/functions are used or "exported" (assigned to a named identifier from one of the outer scopes), might exist, but don't necessarily have to be nested within a anonymous funciton.

    0 讨论(0)
  • 2020-12-19 08:52

    As everyone else has said, it's pretty much entirely to do with creating local scope. Another benefit is that you can use it to (for want of a better word) "rename" variables. Take for instance, how several javascript frameworks use $ as a shorthand for their main library function. If you create a closure like in your example, it doesn't matter what $ is outside, you can use it as a parameter and inside it can be whatever you want:

    // out here $ might be Prototype, something else, or even undefined
    (function($) {
        // in here, $ is jQuery
    })(jQuery);
    

    Another little tip for eking an extra couple of milliseconds of your script is to use this same technique to create an undefined variable. Most people think that undefined is a special keyword in javascript, but it's actually just treated as a normal variable, which you'd hope no one would define. The somewhat standard practice of checking for a undefined variable:

    if (x == undefined)
    

    ...is actually rather wasteful, since it checks the entire scope chain for a variable named "undefined". To shortcut this, you can use this method:

    (function($, undefined) {
        // code here
    })(jQuery);  // note that there's just one parameter passed
    

    Now that undefined is actually in a scope (with an undefined value), checking up the scope chain can stop at that point. Micro-optimisation, yes, but it doesn't hurt to know.

    0 讨论(0)
  • 2020-12-19 09:00

    It's about scope for functions, too - everything declared within the code block is scoped to that anonymous function only. Things are normally made public by the framework

    (function($) {
    
      var localVarOnly = "local";
    
      $.fn.myCoolFunction = function() { // in the case of jquery, make this publicly available
        otherCoolFunction(); //alerts hi
        alert(localVarOnly); // alerts local
      };
    
      function otherCoolFunction() { // scoped to this anonymous function only
        alert('hi');
      };
    
    })(jQuery);
    
    otherCoolFunction(); // undefined
    alert(localVarOnly); // undefined
    
    0 讨论(0)
  • 2020-12-19 09:06

    This is to create a scope that will contain all the variables declared. This is to avoid polluting the global scope and to avoid overriding already existing variables.

    Take this example

    (function() {
        var foo = "bar";
        var undefined = true;
        var bar = true;
    
        alert(foo); //bar
        if (bar == undefined) {
            alert("bar is undefined.. not!"); //will show even though we know that bar is not 'undefined'
        }
    
    })();
    
    var bar = true;
    alert(foo) //undefined
    if (bar == undefined) {
        alert("bar is undefined"); // will not be called
    }
    

    When it comes to the pattern, (function(){/*....*/})(); there is currently a debate going on at comp.lang.javascript about what to call this construct, and who should get the credit for it :)

    0 讨论(0)
  • 2020-12-19 09:08

    That syntax is to create local scope, as others have commented, but also to make the function self-executing. Note that simply creating local scope could also be accomplished like this:

    var foo = function(){
       // local code
    };
    foo();
    

    But if that's all you're doing, and foo has no other utility beyond calling it one time, then the anonymous, self-executing syntax simply saves you the extra var declaration:

    (function(){
       // local code
    })();
    

    In frameworks that use OOP patterns, this is also the syntax used to create singletons since the function can only run once and can never be called again by external code.

    0 讨论(0)
提交回复
热议问题