I have been reading a lot of Javascript lately and I have been noticing that the whole file is wrapped like the following in the .js files to be imported.
(function() {
...
code
...
})();
What is the reason for doing this rather than a simple set of constructor functions?
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:
Now you can call
outerFunction(), but the visiblity ofinnerFunction()is limited to the scope ofouterFunction(), meaning it is private toouterFunction(). It basically follows the same principle as variables in Javascript:Correspondingly:
In the above scenario, you can call
globalFunction()from anywhere, but you cannot calllocalFunction1orlocalFunction2.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:In the first example, you would explicitly invoke
globalFunctionby name to run it. That is, you would just doglobalFunction()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: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):
Now you can call
myPlugin.public_function1(), but you cannot accessprivate_function()! So pretty similar to a class definition. To understand this better, I recommend the following links for some further reading:EDIT
I forgot to mention. In that final
(), you can pass anything you want inside. For example, when you create jQuery plugins, you pass injQueryor$like so: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 calledjQuery, 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: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.