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)
    }
};
6
  • 1
    This piece of code doesn't appear to do anything. Are you sure this is all there is? Commented Jul 9, 2010 at 4: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. Commented Jul 9, 2010 at 4:15
  • 1
    You might want to check out this question: stackoverflow.com/questions/2539205/… Commented Jul 9, 2010 at 4:18
  • I love this construct. It reminds me of a magic trick or a ninja flash-bomb-shuriken maneuver. Commented Jul 9, 2010 at 4: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. Commented Jul 9, 2010 at 14:29

4 Answers 4

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));
}
Sign up to request clarification or add additional context in comments.

3 Comments

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.
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?
That looks like the second function is passed as the argument to the first function... pretty confusing.
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.

Comments

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

1 Comment

Yes, but it doesn't answer the question why this anonymous function is wrapped in parenthesis.
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) {}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.