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 question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does this mean? (function (x,y)){…}){a,b); in JavaScript
I am a starter to javascript. I know to write JS userdefined functions.
But recently I came across some thing that I can’t recognize. Can anyone explain to me what this is?
(function( window, undefined ) {
var jQuery = (function() {
});
window.jQuery = window.$ = jQuery;
})(window);
What is the meaning of this? When I Google javascript functions I am getting only
function foo(){
alert("This is an alert");
}
I know to use these type of functions
Short answer: Those are immediately invoked functions that provide lexical scope and closures.
For a better explanation please take a look at this answer I posted some time ago.
UPDATE:
Lexical scope means that variables declared within a function won't be visible outside of the function body.
Closure is a way to keep references to variables that would otherwise be out of scope, because if they were in scope where the function body was defined then it is available to any subsequent invocation of that function. See: Closure on Wikipedia.
UPDATE 2:
If you really want to understand all of these then I strongly recommend watching the 1986 Structure and Interpretation of Computer Programs MIT lectures by Gerry Sussman and Hal Abelson
(available on YouTube). In my opinion there is no better way to truly understand JavaScript than watching those very lectures, even though they are not about JavaScript. You will quickly see which language was really the inspiration for Brendan Eich when he designed JavaScript. Hint: It was not Java.
It is a Function that executes itself, also called a module pattern.
It is often used to introduce public and private namespaces since attributes defined on the inside of said function are not accessible from the outside while attributes you return are.
For example, if you return an object, you can then treat the function as an object like this:
var a = (function() {
var a= 0; // this is only accessible inside this function
var b = {
a: 1 // this will be returned and therefore be accessible on the outside
};
return b;
})();
console.log(a.a); // outputs 1
The following is a function statement. It can exist alone.
function foo(){
alert("This is an alert");
}
It can be 'called' (executed) like this:
foo();
The following is a function expression (such as anonymous function ** see edit at the bottom **).
As any other expression, it is like an rvalue, you can assign it to a variable
var f = function (){
alert("This is an alert");
};
which, then, can be 'called' (executed) like this:
f();
or you can use operators over it like this:
(function (){
alert("This is an alert");
})();
And note that this variable can now be passed as parameter to other functions! (i.e. we can pass functions as parameters).
Now, lets analyze this:
(function( window, undefined ) {
//blah blah blah -1
//blah blah blah -2
})(window);
this can be broken down into two:
var f = function( window, undefined ) {
//blah blah blah
};
f(window);
The function (assigned to f) takes 2 parameters, window and undefined. We are passing the 1st parameter as window (which will be provided by the browser to the caller; it's a global object). Note that we are not passing any 2nd parameter. But since we are expecting 2nd param in the function but not passing any, the Javascript interpreter will assign an undefined value (as defined in the interpreter) to it. So the variable (parameter) undefined now contains undefined.
The main purpose of accepting these two values as parameters is to make the function independent of the global variables. (Just imagine what would happen if some JS script or a browser plugin changes undefined to something else!!)
Refer:
https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Functions
https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Expressions_and_Operators
EDIT:
As #FelixKling commented, function expressions need not be anonymous, they can have names.
var f = function foo(){
alert("This is an alert");
}
This is an interesting article about their usage.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What do parentheses surrounding a JavaScript object/function/class declaration mean?
I see functions inside parentheses in jQuery plugins and the like.
For example,
(function(args) {
// ...
})(localVariable);
What does this do, exactly?
You mean something like the following?:
(function() {
// ...
})();
This basically ensures that any "var" declarations are kept private (they are scoped to the anonymous function in which they have been placed) rather than global. For example, consider:
var counter = 0;
window['inc'] = function() {
return counter++;
};
vs.
(function() {
var counter = 0;
window['inc'] = function() {
return counter++;
};
})();
Both of these have the effect of defining a function window.inc that returns a counter that gets incremented; however, in the first version, counter is actually visible to all other modules, because it is in the global scope, whereas the latter ensures that only window.inc can access counter.
Note that the code creates a function and immediately invokes it (that's what the last parens are for).
The unofficial name is an 'immediate function' - the basic idea is that the function is defined and called on the fly.
Here's a simple example:
http://javascriptmountain.com/2011/06/functions/immediate-functions-in-javascript-the-basics/
The parentheses are actually not necessary unless the return value of the function is assigned to a variable, but they are usually used for readability.
The reason it is done in situations like jquery plugins is that it provides a sort of 'sandbox' for executing code. Say we did the following:
(function($) {
// augment $ with methods
}(jQuery));
this defines a function that takes in one parameter, then IMMEDIATELY calls the function, passing in the global jquery object. Any vars that are declared and used inside the immediate function will be locally scoped to the function, and will not interfere with global scope or disrupt any global variables that may have been declared in other pieces of javascript code being used (important for libraries intended to be used with large amounts of other code).
However, since we are passing in the global jquery object when we call the function, we can still add methods and properties to the '$' parameter inside of the function that will hang around on the jquery object after the function completes.
Hope this helps!
I'm pretty new to JavaScript, which I am learning on my own. I'm currently creating and tweaking GreaseMonkey scripts. I've noticed that most simple scripts (i.e. those with no need for named functions) go straight into the main code, but some instead are set up like this:
(function() {
//main code here
})();
What is the significance of this type of coding? I've commented out both the top and bottom, and the script still runs exactly the same.
Is it just a coding standard, or does it actually have a function? And, as my title asks, is it something specific to GreaseMonkey, or something that I should do all the time?
This technique effectively creates a private namespace, accessible only to this script. For example, this code:
(function() {
var a = 5;
})();
will have no effect on the global namespace (the a variable is captured by the closure, so window.a will not be affected). It's a very nice way to keep many scripts from stepping on each other's global variables, by making them not global at all. I use this technique all the time when writing any JavaScript, not just Greasemonkey scripts, and would strongly recommend it as a best practice when writing libraries.
If you wanted to expose some functions to other JavaScript code instead of completely isolating your script, you could do something like this:
var MyNamespace = (function () {
var that = {};
that.square = function(x) {
return x*x;
};
return that;
})();
Then you could do MyNamespace.square(5) from another script, and this would return 25.
It's a self executing anonymous function.
It's usually used to change the scope, all variables/functions declared inside this will be in the anonymous function's scope instead of the global (window) scope.
The code serves two purposes:
It keeps objects/variables local to the anonymous function scope. This is important as we see that you may have several script files that all might share the same variable name. If they did, they could replace the variables value and truly muck with your application.
The () at the the end of the line calls the declared function. In other words, the anonymous function you created inside the first set of parentheses can automatically be called instantly. Unless you assigned it to a variable, there would be no other way to call it. This avoids creating a variable in memory and just calls the function at runtime.
Here's the answer for those who never heard of the word closures:
Suppose we have a function
function sayHi() { alert('Hello'); }
We would call this function by doing this:
sayHi();
The above is whats called a named function, if you don't know what that means, then it's what you think of when you hear the word function
In some languages you don't have to name a function, you can leave it blank like so:
alert('Sup');
function() {alert('Hello'); }
3 + 1;
alert('Peace');
Line 2 is perfectly valid. Of course line 2 won't really do anything in your page, just like line 3 doesn't do anything. That is called an anonymous function. Now just like we can assign a variable to line 3 like:
result = 3 + 1;
We can do the same with line 2, like this:
myFunc = function() { alert('Hello'); };
And we can use myFunc as a function like the sayHi() function before. We call it just like we call sayHi()
sayHi();
myFunc();
Now since javascript is written to be versatile, where stuff like [0, 1, 2].indexOf(1) works, we can do the following:
func = function() { alert('hello'); };
func();
(function() { alert('hello'); })();
And line 1 & 2 will accomplish the same thing as line 3 since line 3 is just an expanded version of line 1 and 2. The advantage of line 3 is that if someone later on in the code uses a func variable it wouldn't cause a problem with your own code, also any variables declared in line 3's function (with a var keyword) won't be a valid variable outside of your function, which in this case is what a closure is.
Well that's it for this micro-tutorial, hope it helps.
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.