views:

126

answers:

4

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)
    }
};
+1  A: 

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.
Yes, but it doesn't answer the question why this anonymous function is wrapped in parenthesis.
deceze
+1  A: 

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) {}

DrakeVN
+13  A: 

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
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
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
That looks like the second function is passed as the argument to the first function... pretty confusing.
harto
+3  A: 

() 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