What Is the Purpose of Wrapping Whole JavaScript Files in Anonymous Functions Like "(Function(){ … })()"

What is the purpose of wrapping whole Javascript files in anonymous functions like “(function(){ … })()”?

It's usually to namespace (see later) and control the visibility of member functions and/or variables. Think of it like an object definition. The technical name for it is an Immediately Invoked Function Expression (IIFE). jQuery plugins are usually written like this.

In Javascript, you can nest functions. So, the following is legal:

function outerFunction() {
function innerFunction() {
// code
}
}

Now you can call outerFunction(), but the visiblity of innerFunction() is limited to the scope of outerFunction(), meaning it is private to outerFunction(). It basically follows the same principle as variables in Javascript:

var globalVariable;

function someFunction() {
var localVariable;
}

Correspondingly:

function globalFunction() {

var localFunction1 = function() {
//I'm anonymous! But localFunction1 is a reference to me!
};

function localFunction2() {
//I'm named!
}
}

In the above scenario, you can call globalFunction() from anywhere, but you cannot call localFunction1 or localFunction2.

What you're doing when you write (function() { ... })(), is you're making the code inside the first set of parentheses a function literal (meaning the whole "object" is actually a function). After that, you're self-invoking the function (the final ()) that you just defined. So the major advantage of this as I mentioned before, is that you can have private methods/functions and properties:

(function() {
var private_var;

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

In the first example, you would explicitly invoke globalFunction by name to run it. That is, you would just do globalFunction() to run it. But in the above example, you're not just defining a function; you're defining and invoking it in one go. This means that when the your JavaScript file is loaded, it is immediately executed. Of course, you could do:

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

The behavior would largely be the same except for one significant difference: you avoid polluting the global scope when you use an IIFE (as a consequence it also means that you cannot invoke the function multiple times since it doesn't have a name, but since this function is only meant to be executed once it really isn't an issue).

The neat thing with IIFEs is that you can also define things inside and only expose the parts that you want to the outside world so (an example of namespacing so you can basically create your own library/plugin):

var myPlugin = (function() {
var private_var;

function private_function() {
}

return {
public_function1: function() {
},
public_function2: function() {
}
}
})()

Now you can call myPlugin.public_function1(), but you cannot access private_function()! So pretty similar to a class definition. To understand this better, I recommend the following links for some further reading:

  • Namespacing your Javascript
  • Private members in Javascript (by Douglas Crockford)

EDIT

I forgot to mention. In that final (), you can pass anything you want inside. For example, when you create jQuery plugins, you pass in jQuery or $ like so:

(function(jQ) { ... code ... })(jQuery) 

So what you're doing here is defining a function that takes in one parameter (called jQ, a local variable, and known only to that function). Then you're self-invoking the function and passing in a parameter (also called jQuery, but this one is from the outside world and a reference to the actual jQuery itself). There is no pressing need to do this, but there are some advantages:

  • You can redefine a global parameter and give it a name that makes sense in the local scope.
  • There is a slight performance advantage since it is faster to look things up in the local scope instead of having to walk up the scope chain into the global scope.
  • There are benefits for compression (minification).

Earlier I described how these functions run automatically at startup, but if they run automatically who is passing in the arguments? This technique assumes that all the parameters you need are already defined as global variables. So if jQuery wasn't already defined as a global variable this example would not work. As you might guess, one things jquery.js does during its initialization is define a 'jQuery' global variable, as well as its more famous '$' global variable, which allows this code to work after jQuery has been included.

Why does wrapping a callback in an anonymous function change the meaning of 'this'?

Using an anonymous function wraps MyObj in a closure. That closure's lexical scope (execution context) is now localized to the closure. So this is localized to the closure (and MyObj) as well.

You can discover that by using a debugger with a break point set on the callback() call.

This image shows the variable structure with the closure in place:

With anonymous function wrapper

Without the function wrapper, the lexical scope is the same scope as the higherOrder() function - which is the global scope. Again, this is demonstrated with a break point on the same line of code (note lack of closure):

Without wrapper

Note: this code is run in node - so no Window object here.

Purpose of wrapping with anonymous function

The second case is jQuery's shorthand for "on document ready".

It's the equivalent of:

$(document).ready(function() {
$('#square').pep();
});

Documentation: https://api.jquery.com/ready/

Javascript: Wrap code in an anonymous function

Completely appropriate. That's commonly known as an IIFE.

Benefits are:

  • You can avoid variable naming clashes by "working under a namespace" - naming variables and setting scope:

    (function ($, DOM, ultraSelector) {

    $(DOM).find(ultraSelector); // $ is always jQuery

    })(jQuery, document, 'mySelector');

    $ = false; // here $ is not jQuery anymore
  • Your variables stay managed under your scope, never globally acessible; and

  • You can 'use strict' safely knowing that only the code inside the IIFE will be affected:

    (function () {

    'use strict';

    globalVariable = true; // will throw error
    var scopedVariable = true; // only accessible inside this IIFE

    })();

    globalVariable = true; // will define a global variable
    var scopedVariable = true; // is not really scoped, since its scope is global

I would say its more secure, yes. At least your variables are not easily accessed via browser console.

I strongly recommend the use of IIFEs, as does Douglas Crockford - http://javascript.crockford.com/
... tho he advocates the parens should be inside the declaration (function(){ }())

Is there any reason to wrap anonymous JavaScript functions in braces?

The first syntax is only valid if you assign the result of the function execution to a variable, If you just want to execute the function, this form would be a syntax error:

function(){
return 'test';
}();

The other form is still valid, though:

(function(){
return 'test';
})();

Therefore the second version is more flexible and can be used more consistently.

(The first form is not valid syntax to avoid ambiguities in the Javascript grammar.)

What is the (function() { } )() construct in JavaScript?

It’s an Immediately-Invoked Function Expression, or IIFE for short. It executes immediately after it’s created.

It has nothing to do with any event-handler for any events (such as document.onload).

Consider the part within the first pair of parentheses: (function(){})();....it is a regular function expression. Then look at the last pair (function(){})();, this is normally added to an expression to call a function; in this case, our prior expression.

This pattern is often used when trying to avoid polluting the global namespace, because all the variables used inside the IIFE (like in any other normal function) are not visible outside its scope.

This is why, maybe, you confused this construction with an event-handler for window.onload, because it’s often used as this:

(function(){
// all your code here
var foo = function() {};
window.onload = foo;
// ...
})();
// foo is unreachable here (it’s undefined)

Correction suggested by Guffa:

The function is executed right after it's created, not after it is parsed. The entire script block is parsed before any code in it is executed. Also, parsing code doesn't automatically mean that it's executed, if for example the IIFE is inside a function then it won't be executed until the function is called.

Update
Since this is a pretty popular topic, it's worth mentioning that IIFE's can also be written with ES6's arrow function (like Gajus has pointed out in a comment) :

((foo) => {
// do something with foo here foo
})('foo value')


Related Topics



Leave a reply



Submit