What do parentheses surrounding an object/function/class declaration mean? [duplicate]
Asked Answered
T

7

320

In the YUI library examples, you can find many uses of this construct:

(function() {
    var Dom = YAHOO.util.Dom,
    Event = YAHOO.util.Event,
    layout = null,
        ...
})();

I think the last couple of parentheses are to execute the function just after the declaration.

... But what about the previous set of parentheses surrounding the function declaration?

I think it is a matter of scope; that's to hide inside variables to outside functions and possibly global objects. Is it? More generally, what are the mechanics of those parentheses?

Transcribe answered 13/1, 2009 at 20:48 Comment(4)
This is also discussed in Difference between (function(){})(); and function(){}();.Jamima
I think we need both duplicates as-is, since they're stated so differently.Scanty
That's a good reason to not delete, but I don't see why we can't close as a duplicate.Gambrinus
This question has NOT been asked before the linked question...Reverberatory
S
241

It is a self-executing anonymous function. The first set of parentheses contain the expressions to be executed, and the second set of parentheses executes those expressions.

It is a useful construct when trying to hide variables from the parent namespace. All the code within the function is contained in the private scope of the function, meaning it can't be accessed at all from outside the function, making it truly private.

See:

http://en.wikipedia.org/wiki/Closure_%28computer_science%29

http://peter.michaux.ca/articles/javascript-namespacing

Squatness answered 13/1, 2009 at 20:58 Comment(4)
The parenthesis are only required in this context because function in JavaScript can be both a statement or an expression, depending upon context. The parenthesis force it to be an expression. The following is also valid: var x = function () { return 1 }() even though there are no surrounding parenthesis. Just a function-expression and the application (...) of said expression. In a case I this, I would recommend putting a ; before the opening parenthesis: I write semi-colon free code and lines starting with a ( may be parsed as expression continued from the previous line.Thorson
@Thorson => why put "()" at the end, after "}" ?Gyasi
Wait...so this mess is just a hack to get around the bizarre scoping that JS uses?Margalo
@Beska: Not really. JavaScript is function scoped (broadly speaking), which isn't so bizarre. And functions can be declared and executed in a single expression. It would be fairer to say the "hack" of using it to implement "private" variables is more due to the lack of a mature module system in JavaScript.Squatness
T
153

Andy Hume pretty much gave the answer, I just want to add a few more details.

With this construct you are creating an anonymous function with its own evaluation environment or closure, and then you immediately evaluate it. The nice thing about this is that you can access the variables declared before the anonymous function, and you can use local variables inside this function without accidentally overwriting an existing variable.

The use of the var keyword is very important, because in JavaScript every variable is global by default, but with the keyword you create a new, lexically scoped variable, that is, it is visible by the code between the two braces. In your example, you are essentially creating short aliases to the objects in the YUI library, but it has more powerful uses.

I don't want to leave you without a code example, so I'll put here a simple example to illustrate a closure:

var add_gen = function(n) {
  return function(x) {
    return n + x;
  };
};
var add2 = add_gen(2);
add2(3); // result is 5

What is going on here? In the function add_gen you are creating an another function which will simply add the number n to its argument. The trick is that in the variables defined in the function parameter list act as lexically scoped variables, like the ones defined with var.

The returned function is defined between the braces of the add_gen function so it will have access to the value of n even after add_gen function has finished executing, that is why you will get 5 when executing the last line of the example.

With the help of function parameters being lexically scoped, you can work around the "problems" arising from using loop variables in anonymous functions. Take a simple example:

for(var i=0; i<5; i++) {
  setTimeout(function(){alert(i)}, 10);
}

The "expected" result could be the numbers from zero to four, but you get four instances of fives instead. This happens because the anonymous function in setTimeout and the for loop are using the very same i variable, so by the time the functions get evaluated, i will be 5.

You can get the naively expected result by using the technique in your question and the fact, that function parameters are lexically scoped. (I've used this approach in an other answer)

for(var i=0; i<5; i++) {
  setTimeout(
     (function(j) {
       return function(){alert(j)};
     })(i), 10);
}

With the immediate evaluation of the outer function you are creating a completely independent variable named j in each iteration, and the current value of i will be copied in to this variable, so you will get the result what was naively expected from the first try.

I suggest you to try to understand the excellent tutorial at http://ejohn.org/apps/learn/ to understand closures better, that is where I learnt very-very much.

Thermoluminescence answered 14/1, 2009 at 0:47 Comment(0)
A
47

...but what about the previous round parenteses surrounding all the function declaration?

Specifically, it makes JavaScript interpret the 'function() {...}' construct as an inline anonymous function expression. If you omitted the brackets:

function() {
    alert('hello');
}();

You'd get a syntax error, because the JS parser would see the 'function' keyword and assume you're starting a function statement of the form:

function doSomething() {
}

...and you can't have a function statement without a function name.

function expressions and function statements are two different constructs which are handled in very different ways. Unfortunately the syntax is almost identical, so it's not just confusing to the programmer, even the parser has difficulty telling which you mean!

Adventuress answered 14/1, 2009 at 9:36 Comment(0)
F
15

Juts to follow up on what Andy Hume and others have said:

The '()' surrounding the anonymous function is the 'grouping operator' as defined in section 11.1.6 of the ECMA spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf.

Taken verbatim from the docs:

11.1.6 The Grouping Operator

The production PrimaryExpression : ( Expression ) is evaluated as follows:

  1. Return the result of evaluating Expression. This may be of type Reference.

In this context the function is treated as an expression.

Feuillant answered 25/7, 2013 at 14:37 Comment(0)
S
8

A few considerations on the subject:

  • The parenthesis:

    The browser (engine/parser) associates the keyword function with

    [optional name]([optional parameters]){...code...}
    

    So in an expression like function(){}() the last parenthesis makes no sense.

    Now think at

    name=function(){} ; name() !?
    

Yes, the first pair of parenthesis force the anonymous function to turn into a variable (stored expression) and the second launches evaluation/execution, so ( function(){} )() makes sense.

  • The utility: ?

    1. For executing some code on load and isolate the used variables from the rest of the page especially when name conflicts are possible;

    2. Replace eval("string") with

      (new Function("string"))()

    3. Wrap long code for " =?: " operator like:

      result = exp_to_test ? (function(){... long_code ...})() : (function(){...})();

Synchromesh answered 20/10, 2011 at 21:56 Comment(1)
for the case function name(){}() the variable name is created implicitly so placing braces after the code definitions is a shorthand for name();Synchromesh
H
5

The first parentheses are for, if you will, order of operations. The 'result' of the set of parentheses surrounding the function definition is the function itself which, indeed, the second set of parentheses executes.

As to why it's useful, I'm not enough of a JavaScript wizard to have any idea. :P

Heteropolar answered 13/1, 2009 at 20:53 Comment(0)
D
2

See this question. The first set of parenthesis aren't necessary if you use a function name, but a nameless function requires this construct and the parenthesis serve for coders to realize that they've viewing a self-invoking function when browsing the code (see one blogger's best-practices recommendation).

Dislocate answered 16/9, 2010 at 22:10 Comment(2)
you do need the parentheses if you're using a named function, but can leave them out if you're assigning a function's result to a variable. i.e. function myResult () { ...}() will fail but var myResult = function { ... }() will workCrissie
Great explanation in your best-practices linkVinic

© 2022 - 2024 — McMap. All rights reserved.