Abu Romaïssae
Abu Romaïssae

Reputation: 3901

Why Self-Executing Anonymous Functions

Today I came a cross the self executing functions, than somehow I ended up knowing about Self-Executing Anonymous Functions, then I've read this article: http://briancrescimanno.com/how-self-executing-anonymous-functions-work/

The thing is that I don't know WHY to use Self-Executing Anonymous Functions because if I need to do something like:

var test = "a";
(function(foo) {
    alert(foo);
})(test);

I could just make something like:

var test = "a";
alert(foo);

Or did I miss anything?

also this can be done to any code inside the function, but I used alert() to make simple


Update:

Even thought I've already accepted and answer I would like to share something I've found, if anyone came across this question later :)

Using this notation we can also make an endless loop like following:

(function loop(){
    // do something here
    loop();
)();

Upvotes: 1

Views: 1147

Answers (4)

Markus Siebeneicher
Markus Siebeneicher

Reputation: 765

Your initial example isn't worth to be executed in an anonymous function, so its a bad example to understand WHY to use this technique. Here is a good example to explore state capturing:

var list = [{id: 1, data: null}, ...];

for (var i = 0; i < list.length; i++) {
  (function(item) {
    // start async request, for each item in the list, in the order of the list
    asyncAjax("get-data-from-somewhere.json?what=" + list[i].id, function (response) {
      // thats the on success callback, which gets executed when the server responded
      // each item will have different response times, therefore the order of response is various
      // if we would use simply list[i].data, it wouldn't work correctly, because "i" would has the value of list.length, because the iteration has been finished yet.
      item.data = response;
    });
  })(list[i]);   // the function will preserve the reference to the list item inside, until the function has been fully executed
}

When writing sync. code, you can always fallback to classic object oriented style of structering your code. So you can avoid closures / instant-anonymous function calls. But as soon as you use async. mechanics, closures get very handy and make your code looking more clean, off course only if you can read and understand closures :)

By the way, you could also simply write:

function(private) {}(outer)

is the same as

(function(private) {})(outer)

but the second is better, because its simply more obvious for the reader.

Upvotes: 2

Tibos
Tibos

Reputation: 27823

There are a couple of reasons why one would use an IIFE:

1) No littering

var a = 'foo';
alert(a);

vs

(function() {
  var a = 'foo';
  alert(a);
}())

Both examples do the same thing, but in the second example there is no a variable inside the outer scope.

2) State capturing

var a = 'foo';
window.setTimeout(function() { alert(a); }, 1);
a = 'bar';

vs

var a = 'foo';
window.setTimeout( (function(a_copy) { 
    return function() { alert(a_copy); }
  }(a)), 1);
a = 'bar';

The first example alerts bar, while the second alerts foo. You will find this technique used especially with loops.

Upvotes: 4

micha
micha

Reputation: 49572

Self executing functions are not really useful if you just do an alert inside.

Consider something like this:

(function(foo) {
    var a = ..
    // do something with a and foo
})(test);

The advantage here is that a is "private" inside the method and cannot be used outside the method. So a doesn't end up as a global variable and can't be overwritten by some other piece of javascript which uses a variable of the same name.

Upvotes: 1

James Allardice
James Allardice

Reputation: 165971

The syntax you describe is commonly referred to as an "immediately invoked function expression", or IIFE.

One of the common use cases is to emulate private variables:

var ns = (function () {
    var x = 1; // "private"
    return {
        getX: function () {
            return x;
        }
    }
}());
ns.getX(); // 1
ns.x; // undefined because x is "private"

In that example the x variable is local to the IIFE. It's not directly accessible outside of it. However, since it is referred to by the getX method, which is accessible outside of the IIFE (because it's part of the returned object) a reference to x is kept alive. This is what is usually meant by the term "closure".

Upvotes: 2

Related Questions