What is the purpose of the outer extra parentheses on the below JavaScript closure function? I have been told in other posts that they are not strictly necessary, but they're a convention to make it clear that the result of the function is being passed, not the function itself. The below quote from http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html , however, conflicts. Which is correct?
Notice the () around the anonymous function. This is required by the language, since statements that begin with the token function are always considered to be function declarations. Including () creates a function expression instead.
(function () {
// ... all vars and functions are in this scope only
// still maintains access to all globals
}());
an outer function outer which has a variable b , and returns the inner function. an inner function inner which has its variable called a , and accesses an outer variable b , within its function body.
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function.
In JavaScript, the functions wrapped with parenthesis are called “Immediately Invoked Function Expressions" or "Self Executing Functions. The purpose of wrapping is to namespace and control the visibility of member functions. It wraps code inside a function scope and decrease clashing with other libraries.
Advantages of closures Variables in closures can help you maintain a state that you can use later. They provide data encapsulation. They help remove redundant code. They help maintain modular code.
I think that different engines have different ways of interpreting
function(){...}();
so the most popular and accepted way to make it clear, to all engines, is to group the code in parentheses.
(function(){...}());
At the same time, what you quoted makes a very interesting point. A function expression might go:
var f = function() {...}
Whereas a function declaration looks like:
function f() {...}
You see how it's easy/convenient for the parser to tell the difference by looking at the first token?
IF TOKEN1 EQ "function": FXN DECLARATION
ELSE: FXN EXPRESSION
But it wouldn't make sense for your (immediately-invoked) function to be a function declaration (it's not going to be re-used, you don't want to have it hoisted, or in the namespace, etc.) so adding some innocuous parentheses is a good way of indicating that it's a function expression.
First of all, I must clear up:
(function () {
}());
is equivalent for
(function () {
})();
and also for (Backbone.js uses it)
(function(){
}).call(this);
Second, if you're going to use it that way, then it's not an anonymous/closure function. its Immediately-Invoked Function expression
it would act as a closure (because it won't be immediately-invoked) if you assign its returned context to a variable. This kinda useful if you need a static class (when properties and methods could be accessed without instantiation). For example:
var stuff = (function(){
// AGAIN: its not an IIFE in this case
function foo() // <- public method
{
alert('Jeeez');
}
return {
foo : foo,
}
})();
stuff.foo(); //Alerts Jeeez
What is the purpose of the outer extra parentheses on the below JavaScript closure function?
The purpose isn't usual and quite strange - its all about function arguments. For example,
(function(window, document){ // <- you see this? 2 "arguments"
alert(arguments.length); // 0!
})();
but if we pass them to that outer parentheses
(function(/* So its not for arguments */ ){
alert(arguments.length); // 2
})(window, document); // <- Instead we pass arguments here
The extra surrounding parentheses disambiguate a function expression from a regular function declaration.
Though the extra parentheses are standard practice, the same thing can be achieved by doing this instead:
void function() {
// do stuff
}();
Or, even:
+function() {
// do stuff
}();
Though, out of these two alternatives, I prefer the void
notation because in most cases we don't really care about the return value of an immediate invocation.
Other places where the parentheses aren't required is when an expression is expected:
setTimeout(function() {
return function() {
alert('hello');
}
}(), 1000);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With