3

In the below, I'm confused by the syntax

(function (h,j) { })

What does it mean in javascript to have a function sit inside ()'s like that?

function myfunc(c, b) {
    try {
            (function (h, j) {
                //do a bunch of stuff
            })
    } catch (e) {
        myerror(e)
    }
};
deceze
  • 510,633
  • 85
  • 743
  • 889
jmat
  • 153
  • 1
  • 8
  • 1
    This piece of code doesn't appear to do anything. Are you sure this is all there is? – deceze Jul 09 '10 at 04:09
  • 2
    `(function (h,j) { })` doesn't do anything. `(function (h,j) { })(arg1,arg2)` creates and executes an anonymous function. Notice the difference is the parentheses after the first part - just like saying `alert` vs. `alert()`, one mentions a function, the other executes it. – JAL Jul 09 '10 at 04:15
  • 1
    You might want to check out this question: http://stackoverflow.com/questions/2539205/javascript-inline-function-vs-predefined-functions – Gert Grenander Jul 09 '10 at 04:18
  • I love this construct. It reminds me of a magic trick or a ninja flash-bomb-shuriken maneuver. – JAL Jul 09 '10 at 04:41
  • There is more, I just ripped it out of some code to do an example..but I think everyone here and below caught on to what I was saying....thx. – jmat Jul 09 '10 at 14:29
  • The link to the other stackoverflow article was good which led to this: http://yura.thinkweb2.com/named-function-expressions/ which is very useful – jmat Jul 09 '10 at 14:40

4 Answers4

15

By itself, such a function declaration is useless. This kind of declaration is only useful if you actually invoke the function, which is done like this:

(function (h, j) { ... } (x, y));

This is usually done to hide variables, since JavaScript only has function scope (no block scope).

Edit:

Some examples - hopefully these don't confuse things...

As mentioned in a comment, this technique is useful for keeping variables out of the global scope. For example, some initialisation script might do the following:

(function () {
    var x = 42;
    var y = 'foo';

    function doInitialisation(a, b) {
        // ...
    }

    doInitialisation(x, y);
}());

None of x, y or doInitialisation are visible after the function completes.

Another use-case is for avoiding closures in loops. E.g. the following causes a well-known problem:

var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
    links[i].onclick = function () {
        alert(i);
    };
}

In the above example, every onclick handler shares the same value of i. Function scope can avoid this:

var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
    links[i].onclick = (function (x) {
        return function() {
            alert(x);
        }
    }(i));
}
harto
  • 89,823
  • 9
  • 47
  • 61
  • To add to that: no other block enclosure syntax in Javascript actually limits scope. Variables declared in the body of anything other than a function usually get injected into the global namespace, which [can cause problems](http://www.yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/). – Michael Louis Thaler Jul 09 '10 at 04:12
  • I was looking at a script and pulled the code from that, I also saw this going on a lot: (function (h, j) { //a bunch of foo })(function() { //more foo }) In this case I would assume that the second function actually is invocation of the first function passing it h and j? – jmat Jul 09 '10 at 14:43
  • That looks like the second function is passed as the argument to the first function... pretty confusing. – harto Jul 11 '10 at 06:40
4

() is a grouping operator, and it returns the result of evaluating the expression inside it.

So while

> function(x,y) {}
SyntaxError: Unexpected token (

by itself is a SyntaxError, but by surrounding it in parentheses, the expression inside the parentheses is evaluated and returned.

> (function(x,y) {})
function (x,y) {}

Function expressions and declarations do not yield any value, so we get undefined as a result.

Function Declaration

> function a(x,y) {}
undefined

Function Declaration (with grouping operator)

(function a(x,y) {})
function a(x,y) {}

Function Expression

> var x = function(x,y) {}
undefined

Function Expression (with grouping operator)

> var x;
> (x = function(x,y) {})
function (x,y) {}

However, the usage in your example seems to be useless. It does nothing.

Anurag
  • 140,337
  • 36
  • 221
  • 257
1

That syntax is what is known as an Anonymous Function. Most often, you will see them used as callbacks for various other function calls (for example, in jQuery).

Dan D.
  • 1,117
  • 1
  • 11
  • 18
  • 1
    Yes, but it doesn't answer the question why this anonymous function is wrapped in parenthesis. – deceze Jul 09 '10 at 04:11
1

It's a kind of inline function, so you can take the advantages of covariance. By this I mean,inside

(function (h, j) { //do a bunch of stuff }) You can access the variables of the containing function , here it's function myfunc(c, b) {}

Toan Nguyen
  • 11,263
  • 5
  • 43
  • 59