Related
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:
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.
In short
Summary
In its simplest form, this technique aims to wrap code inside a function scope.
It helps decreases chances of:
clashing with other applications/libraries
polluting superior (global most likely) scope
It does not detect when the document is ready - it is not some kind of document.onload nor window.onload
It is commonly known as an Immediately Invoked Function Expression (IIFE) or Self Executing Anonymous Function.
Code Explained
var someFunction = function(){ console.log('wagwan!'); };
(function() { /* function scope starts here */
console.log('start of IIFE');
var myNumber = 4; /* number variable declaration */
var myFunction = function(){ /* function variable declaration */
console.log('formidable!');
};
var myObject = { /* object variable declaration */
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
})(); /* function scope ends */
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
In the example above, any variable defined in the function (i.e. declared using var) will be "private" and accessible within the function scope ONLY (as Vivin Paliath puts it). In other words, these variables are not visible/reachable outside the function. See live demo.
Javascript has function scoping. "Parameters and variables defined in a function are not visible outside of the function, and that a variable defined anywhere within a function is visible everywhere within the function." (from "Javascript: The Good Parts").
More details
Alternative Code
In the end, the code posted before could also be done as follows:
var someFunction = function(){ console.log('wagwan!'); };
var myMainFunction = function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
};
myMainFunction(); // I CALL "myMainFunction" FUNCTION HERE
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
See live demo.
The Roots
Iteration 1
One day, someone probably thought "there must be a way to avoid naming 'myMainFunction', since all we want is to execute it immediately."
If you go back to the basics, you find out that:
expression: something evaluating to a value. i.e. 3+11/x
statement: line(s) of code doing something BUT it does not evaluate to a value. i.e. if(){}
Similarly, function expressions evaluate to a value. And one consequence (I assume?) is that they can be immediately invoked:
var italianSayinSomething = function(){ console.log('mamamia!'); }();
So our more complex example becomes:
var someFunction = function(){ console.log('wagwan!'); };
var myMainFunction = function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
}();
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
See live demo.
Iteration 2
The next step is the thought "why have var myMainFunction = if we don't even use it!?".
The answer is simple: try removing this, such as below:
function(){ console.log('mamamia!'); }();
See live demo.
It won't work because "function declarations are not invokable".
The trick is that by removing var myMainFunction = we transformed the function expression into a function declaration. See the links in "Resources" for more details on this.
The next question is "why can't I keep it as a function expression with something other than var myMainFunction =?
The answer is "you can", and there are actually many ways you could do this: adding a +, a !, a -, or maybe wrapping in a pair of parenthesis (as it's now done by convention), and more I believe. As example:
(function(){ console.log('mamamia!'); })(); // live demo: jsbin.com/zokuwodoco/1/edit?js,console.
or
+function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wuwipiyazi/1/edit?js,console
or
-function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wejupaheva/1/edit?js,console
What does the exclamation mark do before the function?
JavaScript plus sign in front of function name
So once the relevant modification is added to what was once our "Alternative Code", we return to the exact same code as the one used in the "Code Explained" example
var someFunction = function(){ console.log('wagwan!'); };
(function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
})();
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Read more about Expressions vs Statements:
developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Function_constructor_vs._function_declaration_vs._function_expression
Javascript: difference between a statement and an expression?
Expression Versus Statement
Demystifying Scopes
One thing one might wonder is "what happens when you do NOT define the variable 'properly' inside the function -- i.e. do a simple assignment instead?"
(function() {
var myNumber = 4; /* number variable declaration */
var myFunction = function(){ /* function variable declaration */
console.log('formidable!');
};
var myObject = { /* object variable declaration */
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
myOtherFunction = function(){ /* oops, an assignment instead of a declaration */
console.log('haha. got ya!');
};
})();
myOtherFunction(); // reachable, hence works: see in the console
window.myOtherFunction(); // works in the browser, myOtherFunction is then in the global scope
myFunction(); // unreachable, will throw an error, see in the console
See live demo.
Basically, if a variable that was not declared in its current scope is assigned a value, then "a look up the scope chain occurs until it finds the variable or hits the global scope (at which point it will create it)".
When in a browser environment (vs a server environment like nodejs) the global scope is defined by the window object. Hence we can do window.myOtherFunction().
My "Good practices" tip on this topic is to always use var when defining anything: whether it's a number, object or function, & even when in the global scope. This makes the code much simpler.
Note:
javascript does not have block scope (Update: block scope local variables added in ES6.)
javascript has only function scope & global scope (window scope in a browser environment)
Read more about Javascript Scopes:
What is the purpose of the var keyword and when to use it (or omit it)?
What is the scope of variables in JavaScript?
Resources
youtu.be/i_qE1iAmjFg?t=2m15s - Paul Irish presents the IIFE at min 2:15, do watch this!
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions
Book: Javascript, the good parts - highly recommended
youtu.be/i_qE1iAmjFg?t=4m36s - Paul Irish presents the module pattern at 4:36
Next Steps
Once you get this IIFE concept, it leads to the module pattern, which is commonly done by leveraging this IIFE pattern. Have fun :)
Javascript in a browser only really has a couple of effective scopes: function scope and global scope.
If a variable isn't in function scope, it's in global scope. And global variables are generally bad, so this is a construct to keep a library's variables to itself.
That's called a closure. It basically seals the code inside the function so that other libraries don't interfere with it. It's similar to creating a namespace in compiled languages.
Example. Suppose I write:
(function() {
var x = 2;
// do stuff with x
})();
Now other libraries cannot access the variable x I created to use in my library.
You can use function closures as data in larger expressions as well, as in this method of determining browser support for some of the html5 objects.
navigator.html5={
canvas: (function(){
var dc= document.createElement('canvas');
if(!dc.getContext) return 0;
var c= dc.getContext('2d');
return typeof c.fillText== 'function'? 2: 1;
})(),
localStorage: (function(){
return !!window.localStorage;
})(),
webworkers: (function(){
return !!window.Worker;
})(),
offline: (function(){
return !!window.applicationCache;
})()
}
In addition to keeping the variables local, one very handy use is when writing a library using a global variable, you can give it a shorter variable name to use within the library. It's often used in writing jQuery plugins, since jQuery allows you to disable the $ variable pointing to jQuery, using jQuery.noConflict(). In case it is disabled, your code can still use $ and not break if you just do:
(function($) { ...code...})(jQuery);
To avoid clash with other methods/libraries in the same window,
Avoid Global scope, make it local scope,
To make debugging faster (local scope),
JavaScript has function scope only, so it will help in compilation of codes as well.
We should also use 'use strict' in the scope function to make sure that the code should be executed in "strict mode". Sample code shown below
(function() {
'use strict';
//Your code from here
})();
Provide an example for the accepted answer, from https://requirejs.org/docs/whyamd.html:
(function () {
var $ = this.jQuery;
this.myExample = function () {};
}());
The code demonstrates that we can:
use global variables inside the scope
export functions, variables etc.. by binding on this, which is the window object as for browsers.
Its called encapsulation in OOP.
This isn't actually a specific issue I have but something I'd like to educate myself on:
As far as I understand, in JavaScript the following code
if (true) {
function greet(){ alert("Hello!"); }
} else {
function greet(){ alert("Hi!"); }
}
greet();
outputs Hi! because the code is actually evaluated as something like this:
greet = function(){ alert("Hello!"); }
greet = function(){ alert("Hi!"); }
if(true){
// possibly a no-op assignment, such as greet = greet?
}else{
// same as the other branch?
}
greet();
From a language design perspective, why does JavaScript behave in this way?
Named functions are created before the code starts, so that you don't have to put the declaration of a function before the code that uses it:
x(); // this is possible because the function already exists
function x() {}
It doesn't matter where the function declaration is, even if it's inside a flow control structure, it's still created before the code starts. So, there is no executable code at all inside the if statement in your example, not even a no-op assignment.
If you want to assign function declarations dynamically, you have use a variable:
var greet;
if (true) {
greet = function(){ alert("Hello!"); }
} else {
greet = function(){ alert("Hi!"); }
}
greet();
You don't have to use anonymous functions though, you could assign one of two named functions to the variable.
You may have found a quirk of the language and if you look a bit further you will also find different implementations.
ECMAScript processing has two phases - in the first, all declarations are processed to create named properties within the scope of their declaration. In the second, the code is executed. So declared functions and variables are available in their declared scope from the start of execution, regardless of where in the code they are declared.
And those that are created or assigned values by assignment will have values only when the assignment code is executed.
So:
// Call x
x();
// Declare x
function x(){}
works without error. This is colloquially called "hoisting", meaning declarations are "hoisted" to the top of the scope.
However, to paraphrase your example:
if (true) {
function x(){
alert('true x');
}
} else {
function x(){
alert('false x');
}
}
// In most browsers
x(); // false x
// But in Firefox
x(); // true x
For most browsers, the second declaration overrides the first. That is because ECMAScript does not have block scope, only function and global scope.
However, in this case extensions are allowed to the language. Firefox treats the above as named function expressions, hence is shows true x. More importantly, because other browsers treat the expressions as declarations, x can be called from above the code block but in Firefox it can't, you'll get an error.
The bottom line is if you want to conditionally assign a function to a named parameter or variable, do it explicitly like:
var x;
if (true) {
x = function (){
alert('true x');
};
} else {
x = function (){
alert('false x');
};
}
so that you get consistent behaviour. And you must also remember that x will not be a function until after the code has been executed, it will not be "hoisted" because it isn't a declaration.
First, it does not always behave in this way. In the case of Function Expressions function object is only available in the internal scope.
Second, when you define a function it is very likely that you want to use it in the current scope. So it is very natural that it will become available in the current scope. Consider that the enclosing scope (depending on the function definition location) is the global object or the enclosing function body not the if block.
Now, I can reduce your question to the following question:
Why the function name is used as the variable name?
A : Otherwise developers have to always assign function to a variable (which I prefer).
I have a function like this:
function run(arg) {
if (!window.alreadyRun) init();
window.alreadyRun = true;
/* more code */
}
You get the idea, I'm trying to figure out if it's the first time a function is called.
Is there a better way to do this? Without using globals? Something like this:
function run(arg) {
var ranAlready;
if (!ranAlready) init();
ranAlready = true;
/* more code */
}
This will return a function, with a variable called runCount which will hold the number of times it was called.
var yourFunction = function() {
var runCount = 0;
return function() {
console.log(runCount);
runCount++;
}
}
var a = yourFunction();
a(); // runCount: 0
a(); // runCount: 1
a(); // runCount: 2
a(); // runCount: 3
See it on jsFiddle.
If you just want to run an init type function, you could place the code above returning the inner function. It will be called once before returning the inner function, and its scope will retain to its outer function.
The power of closures.
var f = (function(run) {
return function() {
if (!run) init(),run=true;
// do code
};
}(false));
You can even use if (!run) init() && run = true and get init to return false if you want it to be called again on the next function call.
We have a self executing function which creates a local run variable and set's it to false by passing it in as an argument. We then have a single line which checks if it's false if so it does init(), run=true which is running the init function and assigning it to true in a single expression.
Basically anywhere were your using global scope to make the variable static to the function you can instead use a closure as a scope level between local function scope & global scope.
If you need a variable that is static to a function & read only you can use the little known const keyword.
I think closures are completely overkill for this, and only complicates the code.
What you're describing is known as a static variable in Object Oriented languages, and it can be mimicked quite easily in JS by attaching properties directly to the function. This is possible because functions are first-class objects in JS:
function run(arg) {
if (!run.ranAlready) { // run.ranAlready is undefined at first, so falsy
run.ranAlready = true;
init();
}
/* more code */
}
This is far simpler than nested functions, and you can continue to use run() in exactly the same way.
Another advantage is that, for unit testing, you can still access the ranAlready property from outside the function to check that your code is working correctly:
assert(run.runAlready == false);
run();
assert(run.runAlready === true);
Granted, this can't be used for anonymous functions, such as in event handlers, but isn't it much cleaner to give that anonymous function a name instead of using nested functions and an extra function invocation?
Here's just another way to do it. You can have the function modify itself. In the case below, myfunction gets changed to a new one. This may not be exactly what you're looking for but I think it's useful to at least post this so you can see alternative ways to do things (and also: self modifying code can just be cool at times).
var myfunction = function() {
alert("This is the first time I'm executed");
myfunction = function() {
alert('Subsequent times');
}
}
myfunction(); // displays the alert 'This is the first time...'
myfunction(); // displays the alert 'Subsequent times'
myfunction();
Example: http://jsfiddle.net/jonathon/wntmB/
(function() {})() and its jQuery-specific cousin (function($) {})(jQuery) pop up all the time in Javascript code.
How do these constructs work, and what problems do they solve?
Examples appreciated
With the increasing popularity of JavaScript frameworks, the $ sign was used in many different occasions. So, to alleviate possible clashes, you can use those constructs:
(function ($){
// Your code using $ here.
})(jQuery);
Specifically, that's an anonymous function declaration which gets executed immediately passing the main jQuery object as parameter. Inside that function, you can use $ to refer to that object, without worrying about other frameworks being in scope as well.
This is a technique used to limit variable scope; it's the only way to prevent variables from polluting the global namespace.
var bar = 1; // bar is now part of the global namespace
alert(bar);
(function () {
var foo = 1; // foo has function scope
alert(foo);
// code to be executed goes here
})();
1) It defines an anonymous function and executes it straight away.
2) It's usually done so as not to pollute the global namespace with unwanted code.
3) You need to expose some methods from it, anything declared inside will be "private", for example:
MyLib = (function(){
// other private stuff here
return {
init: function(){
}
};
})();
Or, alternatively:
MyLib = {};
(function({
MyLib.foo = function(){
}
}));
The point is, there are many ways you can use it, but the result stays the same.
It's just an anonymous function that is called immediately. You could first create the function and then call it, and you get the same effect:
(function(){ ... })();
works as:
temp = function(){ ... };
temp();
You can also do the same with a named function:
function temp() { ... }
temp();
The code that you call jQuery-specific is only that in the sense that you use the jQuery object in it. It's just an anonymous function with a parameter, that is called immediately.
You can do the same thing in two steps, and you can do it with any parameters you like:
temp = function(answer){ ... };
temp(42);
The problem that this solves is that it creates a closuse for the code in the function. You can declare variables in it without polluting the global namespace, thus reducing the risk of conflicts when using one script along with another.
In the specific case for jQuery you use it in compatibility mode where it doesn't declare the name $ as an alias for jQuery. By sending in the jQuery object into the closure and naming the parameter $ you can still use the same syntax as without compatibility mode.
It explains here that your first construct provides scope for variables.
Variables are scoped at the function level in javascript. This is different to what you might be used to in a language like C# or Java where the variables are scoped to the block. What this means is if you declare a variable inside a loop or an if statement, it will be available to the entire function.
If you ever find yourself needing to explicitly scope a variable inside a function you can use an anonymous function to do this. You can actually create an anonymous function and then execute it straight away and all the variables inside will be scoped to the anonymous function:
(function() {
var myProperty = "hello world";
alert(myProperty);
})();
alert(typeof(myProperty)); // undefined
Another reason to do this is to remove any confusion over which framework's $ operator you are using. To force jQuery, for instance, you can do:
;(function($){
... your jQuery code here...
})(jQuery);
By passing in the $ operator as a parameter and invoking it on jQuery, the $ operator within the function is locked to jQuery even if you have other frameworks loaded.
Another use for this construct is to "capture" the values of local variables that will be used in a closure. For example:
for (var i = 0; i < 3; i++) {
$("#button"+i).click(function() {
alert(i);
});
}
The above code will make all three buttons pop up "3". On the other hand:
for (var i = 0; i < 3; i++) {
(function(i) {
$("#button"+i).click(function() {
alert(i);
});
})(i);
}
This will make the three buttons pop up "0", "1", and "2" as expected.
The reason for this is that a closure keeps a reference to its enclosing stack frame, which holds the current values of its variables. If those variables change before the closure executes, then the closure will see only the latest values, not the values as they were at the time the closure was created. By wrapping the closure creation inside another function as in the second example above, the current value of the variable i is saved in the stack frame of the anonymous function.
This is considered a closure. It means the code contained will run within its own lexical scope. This means you can define new variables and functions and they won't collide with the namespace used in code outside of the closure.
var i = 0;
alert("The magic number is " + i);
(function() {
var i = 99;
alert("The magic number inside the closure is " + i);
})();
alert("The magic number is still " + i);
This will generate three popups, demonstrating that the i in the closure does not alter the pre-existing variable of the same name:
The magic number is 0
The magic number inside the closure is 99
The magic number is still 0
They are often used in jQuery plugins. As explained in the jQuery Plugins Authoring Guide all variables declared inside { } are private and are not visible to the outside which allows for better encapsulation.
As others have said, they both define anonymous functions that are invoked immediately. I generally wrap my JavaScript class declarations in this structure in order to create a static private scope for the class. I can then place constant data, static methods, event handlers, or anything else in that scope and it will only be visible to instances of the class:
// Declare a namespace object.
window.MyLibrary = {};
// Wrap class declaration to create a private static scope.
(function() {
var incrementingID = 0;
function somePrivateStaticMethod() {
// ...
}
// Declare the MyObject class under the MyLibrary namespace.
MyLibrary.MyObject = function() {
this.id = incrementingID++;
};
// ...MyObject's prototype declaration goes here, etc...
MyLibrary.MyObject.prototype = {
memberMethod: function() {
// Do some stuff
// Maybe call a static private method!
somePrivateStaticMethod();
}
};
})();
In this example, the MyObject class is assigned to the MyLibrary namespace, so it is accessible. incrementingID and somePrivateStaticMethod() are not directly accessible outside of the anonymous function scope.
That is basically to namespace your JavaScript code.
For example, you can place any variables or functions within there, and from the outside, they don't exist in that scope. So when you encapsulate everything in there, you don't have to worry about clashes.
The () at the end means to self invoke. You can also add an argument there that will become the argument of your anonymous function. I do this with jQuery often, and you can see why...
(function($) {
// Now I can use $, but it won't affect any other library like Prototype
})(jQuery);
Evan Trimboli covers the rest in his answer.
It's a self-invoking function. Kind of like shorthand for writing
function DoSomeStuff($)
{
}
DoSomeStuff(jQuery);
What the above code is doing is creating an anonymous function on line 1, and then calling it on line 3 with 0 arguments. This effectively encapsulates all functions and variables defined within that library, because all of the functions will be accessible only inside that anonymous function.
This is good practice, and the reasoning behind it is to avoid polluting the global namespace with variables and functions, which could be clobbered by other pieces of Javascript throughout the site.
To clarify how the function is called, consider the simple example:
If you have this single line of Javascript included, it will invoke automatically without explicitly calling it:
alert('hello');
So, take that idea, and apply it to this example:
(function() {
alert('hello')
//anything I define in here is scoped to this function only
}) (); //here, the anonymous function is invoked
The end result is similar, because the anonymous function is invoked just like the previous example.
Because the good code answers are already taken :) I'll throw in a suggestion to watch some John Resig videos video 1 , video 2 (inventor of jQuery & master at JavaScript).
Some really good insights and answers provided in the videos.
That is what I happened to be doing at the moment when I saw your question.
function(){ // some code here }
is the way to define an anonymous function in javascript. They can give you the ability to execute a function in the context of another function (where you might not have that ability otherwise).
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:
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.
In short
Summary
In its simplest form, this technique aims to wrap code inside a function scope.
It helps decreases chances of:
clashing with other applications/libraries
polluting superior (global most likely) scope
It does not detect when the document is ready - it is not some kind of document.onload nor window.onload
It is commonly known as an Immediately Invoked Function Expression (IIFE) or Self Executing Anonymous Function.
Code Explained
var someFunction = function(){ console.log('wagwan!'); };
(function() { /* function scope starts here */
console.log('start of IIFE');
var myNumber = 4; /* number variable declaration */
var myFunction = function(){ /* function variable declaration */
console.log('formidable!');
};
var myObject = { /* object variable declaration */
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
})(); /* function scope ends */
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
In the example above, any variable defined in the function (i.e. declared using var) will be "private" and accessible within the function scope ONLY (as Vivin Paliath puts it). In other words, these variables are not visible/reachable outside the function. See live demo.
Javascript has function scoping. "Parameters and variables defined in a function are not visible outside of the function, and that a variable defined anywhere within a function is visible everywhere within the function." (from "Javascript: The Good Parts").
More details
Alternative Code
In the end, the code posted before could also be done as follows:
var someFunction = function(){ console.log('wagwan!'); };
var myMainFunction = function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
};
myMainFunction(); // I CALL "myMainFunction" FUNCTION HERE
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
See live demo.
The Roots
Iteration 1
One day, someone probably thought "there must be a way to avoid naming 'myMainFunction', since all we want is to execute it immediately."
If you go back to the basics, you find out that:
expression: something evaluating to a value. i.e. 3+11/x
statement: line(s) of code doing something BUT it does not evaluate to a value. i.e. if(){}
Similarly, function expressions evaluate to a value. And one consequence (I assume?) is that they can be immediately invoked:
var italianSayinSomething = function(){ console.log('mamamia!'); }();
So our more complex example becomes:
var someFunction = function(){ console.log('wagwan!'); };
var myMainFunction = function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
}();
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
See live demo.
Iteration 2
The next step is the thought "why have var myMainFunction = if we don't even use it!?".
The answer is simple: try removing this, such as below:
function(){ console.log('mamamia!'); }();
See live demo.
It won't work because "function declarations are not invokable".
The trick is that by removing var myMainFunction = we transformed the function expression into a function declaration. See the links in "Resources" for more details on this.
The next question is "why can't I keep it as a function expression with something other than var myMainFunction =?
The answer is "you can", and there are actually many ways you could do this: adding a +, a !, a -, or maybe wrapping in a pair of parenthesis (as it's now done by convention), and more I believe. As example:
(function(){ console.log('mamamia!'); })(); // live demo: jsbin.com/zokuwodoco/1/edit?js,console.
or
+function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wuwipiyazi/1/edit?js,console
or
-function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wejupaheva/1/edit?js,console
What does the exclamation mark do before the function?
JavaScript plus sign in front of function name
So once the relevant modification is added to what was once our "Alternative Code", we return to the exact same code as the one used in the "Code Explained" example
var someFunction = function(){ console.log('wagwan!'); };
(function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
})();
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Read more about Expressions vs Statements:
developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Function_constructor_vs._function_declaration_vs._function_expression
Javascript: difference between a statement and an expression?
Expression Versus Statement
Demystifying Scopes
One thing one might wonder is "what happens when you do NOT define the variable 'properly' inside the function -- i.e. do a simple assignment instead?"
(function() {
var myNumber = 4; /* number variable declaration */
var myFunction = function(){ /* function variable declaration */
console.log('formidable!');
};
var myObject = { /* object variable declaration */
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
myOtherFunction = function(){ /* oops, an assignment instead of a declaration */
console.log('haha. got ya!');
};
})();
myOtherFunction(); // reachable, hence works: see in the console
window.myOtherFunction(); // works in the browser, myOtherFunction is then in the global scope
myFunction(); // unreachable, will throw an error, see in the console
See live demo.
Basically, if a variable that was not declared in its current scope is assigned a value, then "a look up the scope chain occurs until it finds the variable or hits the global scope (at which point it will create it)".
When in a browser environment (vs a server environment like nodejs) the global scope is defined by the window object. Hence we can do window.myOtherFunction().
My "Good practices" tip on this topic is to always use var when defining anything: whether it's a number, object or function, & even when in the global scope. This makes the code much simpler.
Note:
javascript does not have block scope (Update: block scope local variables added in ES6.)
javascript has only function scope & global scope (window scope in a browser environment)
Read more about Javascript Scopes:
What is the purpose of the var keyword and when to use it (or omit it)?
What is the scope of variables in JavaScript?
Resources
youtu.be/i_qE1iAmjFg?t=2m15s - Paul Irish presents the IIFE at min 2:15, do watch this!
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions
Book: Javascript, the good parts - highly recommended
youtu.be/i_qE1iAmjFg?t=4m36s - Paul Irish presents the module pattern at 4:36
Next Steps
Once you get this IIFE concept, it leads to the module pattern, which is commonly done by leveraging this IIFE pattern. Have fun :)
Javascript in a browser only really has a couple of effective scopes: function scope and global scope.
If a variable isn't in function scope, it's in global scope. And global variables are generally bad, so this is a construct to keep a library's variables to itself.
That's called a closure. It basically seals the code inside the function so that other libraries don't interfere with it. It's similar to creating a namespace in compiled languages.
Example. Suppose I write:
(function() {
var x = 2;
// do stuff with x
})();
Now other libraries cannot access the variable x I created to use in my library.
You can use function closures as data in larger expressions as well, as in this method of determining browser support for some of the html5 objects.
navigator.html5={
canvas: (function(){
var dc= document.createElement('canvas');
if(!dc.getContext) return 0;
var c= dc.getContext('2d');
return typeof c.fillText== 'function'? 2: 1;
})(),
localStorage: (function(){
return !!window.localStorage;
})(),
webworkers: (function(){
return !!window.Worker;
})(),
offline: (function(){
return !!window.applicationCache;
})()
}
In addition to keeping the variables local, one very handy use is when writing a library using a global variable, you can give it a shorter variable name to use within the library. It's often used in writing jQuery plugins, since jQuery allows you to disable the $ variable pointing to jQuery, using jQuery.noConflict(). In case it is disabled, your code can still use $ and not break if you just do:
(function($) { ...code...})(jQuery);
To avoid clash with other methods/libraries in the same window,
Avoid Global scope, make it local scope,
To make debugging faster (local scope),
JavaScript has function scope only, so it will help in compilation of codes as well.
We should also use 'use strict' in the scope function to make sure that the code should be executed in "strict mode". Sample code shown below
(function() {
'use strict';
//Your code from here
})();
Provide an example for the accepted answer, from https://requirejs.org/docs/whyamd.html:
(function () {
var $ = this.jQuery;
this.myExample = function () {};
}());
The code demonstrates that we can:
use global variables inside the scope
export functions, variables etc.. by binding on this, which is the window object as for browsers.
Its called encapsulation in OOP.