Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Purpose of the outer extra parenthese on JavaScript closure function [duplicate]

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
}());
like image 653
user1032531 Avatar asked Apr 03 '13 14:04

user1032531


People also ask

What is outer function in JavaScript?

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.

What is the purpose of closure functions?

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.

What do the brackets after a function do?

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.

What is the benefit of closure in JavaScript?

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.


3 Answers

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.

like image 171
ktm5124 Avatar answered Nov 02 '22 23:11

ktm5124


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
like image 40
Yang Avatar answered Nov 02 '22 23:11

Yang


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);
like image 29
Ja͢ck Avatar answered Nov 03 '22 00:11

Ja͢ck