1

I've been programming in JS since some time, but I have never came upon a need of using immediate functions, for example:

(function(){
    console.log('hello, I am an immediate function');
}())

What would be the difference if I just wrote:

console.log('hello, I am an immediate function');

? I don't have any access to this function anyway (it is not assigned anywhere). I think (but I'm not sure) that I can implement everything without immediate functions - so why do people use it?

GG.
  • 21,083
  • 14
  • 84
  • 130
ducin
  • 25,621
  • 41
  • 157
  • 256
  • 2
    google "Javascript Self Invoking Functions", you have a few things to read, and everything should get clear after... – AntouanK Jun 20 '13 at 11:35
  • 1
    Well, in your case there really is no difference (other than the call stack and the slower execution). But no, not everything can be done without them. – Bergi Jun 20 '13 at 11:43
  • Just a FYI that this question is one of the first search hits in a google query for "Node js immediate function", which is even a auto-completion suggestion from Google. It's very bad that this question is marked as duplicate of a post that's largely unrelated, at least to those who arrive here while looking into [Node.js's event loop](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/). – RAM Oct 19 '21 at 11:36

6 Answers6

5

Update:
I've found this question where I did go into more details on closures, comlete with little drawings to clarify how closures, and function scopes are used (and how they can help you).

IIFE's, being function objects, are the only way to create real scopes in JS. They're used all over the place. Have you ever used jQuery, or some other lib? then you've used code that uses IIFE's.
Ever looked into node.js? Then you might have come across something called "the module pattern".
If you've had a go at writing your own constructor, you've probably wondered how you could have some sort of private property onto an object. The answer is IIFE's time and time again.

Also: The DOM api isn't the fastest thing in the world. Having a function containing a hard-coded document.getElementById call means that, every time the function gets called, the DOM will be traversed. That's not ideal. A quick, and easy way to fix this issue would be this:

var f = (function(domReference)
{
    var visible = !!(domReference.style.visibility === 'block')
    return function()
    {//has access to vars and arguments of outer function
        domReference.style.visibility = visible ? 'none' : 'block';
        visible = !visible;
    }
}(document.getElementById('foobar'));

But perhaps the best, and most common example is timeouts/intervals in loops:

for (var i=0;i<10;i++)
{
    setTimeout((function(currentI)
    {
        return function()
        {
            console.log(currentI);
            console.log(i);
        }
    }(i)), 1000);

Here, currentI will log 0, 1, 2... and so on, whereas i will always log 10. The reason being the timeout callback doesn't get its own copy of i's value, but it references the variable i. That variable can change its value as much as it wants, when the timeout callback is invoked, it'll log whatever value i was last assigned. Not the value i was assigned when the callback was defined.

Without going into too much detail, I mentioned private properties for objects. Well, here's an example for you to work out why the IIFE's and function scopes are crucial, and an incredibly powerful feater of JS:

var MyConstructor = (function()
{
    return function(foo, bar)
    {
        var initState = Array.prototype.slice.apply(arguments, [0]);
        this.getInit = function()
        {
            return initState;
        };
        this.foo = foo;
        this.bar = bar;
    }
}());
(function(constant)
{
    var F = function(args)
    {
        return MyConstructor.apply(this, args);
    },
    checkVar = constant || 'default constant value';
    F.prototype = MyConstructor.prototype;
    MyConstructor.prototype.getConstant = function()
    {
        if (constant !== checkVar)
        {//bad example
            return checkVar;
        }
        return constant;
    };
    MyConstructor.prototype.regularMethod = function()
    {
        return this.foo;
    };
    MyConstructor.prototype.copyFromInitState = function()
    {
        return new F(this.getInit());
    };
}('Immutable value'));

Have fun working this out... :P

Community
  • 1
  • 1
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • What's an *unreal* scope? Do you refer to the unnamedness of the function? – Bergi Jun 20 '13 at 12:17
  • @Bergi: no, I'm referring to JS not (yet) having `let` variables or block scope. Some people use object literals, and `delete` temporary values to have some sort of _"scope object"_ – Elias Van Ootegem Jun 20 '13 at 12:20
  • 1
    OK, but you also could create "real" scopes with normal functions that are not "immediately" executed but referenced somehow. – Bergi Jun 20 '13 at 12:28
  • @Bergi: Edited answer, specified that the _F_ part of _IIFE_ is what creates the scope. :) – Elias Van Ootegem Jun 20 '13 at 12:45
4

Immediately invoked function expressions are used to create namespaces. I won't explain precisely why an IIFE is so important - Ben Alman does a mighty good job at that. Nevertheless, I will say that one of the most important uses of an IIFE is to create closures. Consider:

var counter = (function () {
    var count = 0;

    return function () {
        return ++count;
    };
}());

console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

The reason we use an IIFE is because JavaScript doesn't have block scoping. Hence a IIFE is used to simulate a block scope. JavaScript 1.7 introduced the let keyword which allows you to create block scoped variables. However most implementations don't support let hence we still use IIFEs.

For example the above program could be rewritten using the let keyword as follows:

var counter;

{
    let count = 0;

    counter = function () {
        ++count;
    };
}

console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

Also notice that an IIFE can return values. Normal blocks can't do that. Hence you need to manually assign the return value to a global variable.

Mostly however an IIFE is used to encapsulate the private state of a library. It's considered bad practice to create a bunch of globals.

Sometimes it's used to encapsulate logically similar elements because as humans we like to group things. It may not really make a difference but organizing code is good. For instance, consider:

function Pet(name) {
    this.name = name;
}

Pet.prototype.feed = function (food) {
    console.log(this.name + " is eating " + food + ".");
};

Instead of this it just looks better to encapsulate your code as follows:

var Pet = (function () {
    function Pet(name) {
        this.name = name;
    }

    Pet.prototype.feed = function (food) {
        console.log(this.name + " is eating " + food + ".");
    };

    return Pet;
}());

Oh, most important. An IIFE is also used to solve the Javascript infamous Loop issue?

Community
  • 1
  • 1
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
  • 1
    Well, while [theoretically *scopes* can be seen as namespaces](http://en.wikipedia.org/wiki/Namespace#Computer_science_considerations), the term *namespace* usually refers to module objects (which are accessed with dot notation) in JS. – Bergi Jun 20 '13 at 12:25
  • 1
    Just a tiny side-note: officialy, `let` is [a future reserved keyword](http://www.ecma-international.org/ecma-262/5.1/#sec-7.6.1.2) and will not be added until ES6. Chrome only supports it as an experimental feature, and it was introduced by Mozilla as part of their own superset of JS – Elias Van Ootegem Jun 20 '13 at 13:19
1

Developers use Immediate Functions to declare private scopes. For instance...

(function($){
   $("div").html("example");
})(jQuery);

With this code you don't need $ variable in the global scope, just window.jQuery outside. It prevents posible conflicts when you want to use variable names that another libraries are using in the window object (for instance, you could be using window.$ for another proposes, like Prototype.js).

fcortes
  • 1,338
  • 3
  • 11
  • 26
1

self-invoking functions are used to prevent global variable collision. For example:

(function($){
    //your code 
})(jQuery);

In the above example, if it is in a page using jQuery and Prototype.js, you may safely refer to $ object and know that it is jquery's $ object not prototype's $ object.

Rich
  • 5,603
  • 9
  • 39
  • 61
Kemal Dağ
  • 2,743
  • 21
  • 27
1

People use it because its one of the most powerful features in javascript. Have a read and welcome to Javascript. http://javascript.crockford.com/private.html

Anthony
  • 589
  • 3
  • 15
0

The reason why people use it is emulation of private scopes. Any variable defined in anonymous function body will be hidden from outer scope (usually it's window and trash window with temp variables is bad idea).

Tommi
  • 3,199
  • 1
  • 24
  • 38