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.
22k14 gold badges93 silver badges133 bronze badges
asked Jun 20, 2013 at 11:34
3
  • 2
    google "Javascript Self Invoking Functions", you have a few things to read, and everything should get clear after... Commented Jun 20, 2013 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. Commented Jun 20, 2013 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. Commented Oct 19, 2021 at 11:36

6 Answers 6

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

answered Jun 20, 2013 at 12:06
Sign up to request clarification or add additional context in comments.

4 Comments

What's an unreal scope? Do you refer to the unnamedness of the function?
@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"
OK, but you also could create "real" scopes with normal functions that are not "immediately" executed but referenced somehow.
@Bergi: Edited answer, specified that the F part of IIFE is what creates the scope. :)
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?

answered Jun 20, 2013 at 12:06

2 Comments

Well, while theoretically scopes can be seen as namespaces, the term namespace usually refers to module objects (which are accessed with dot notation) in JS.
Just a tiny side-note: officialy, let is a future reserved keyword 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
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

answered Jun 20, 2013 at 11:40

Comments

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

answered Jun 20, 2013 at 11:35

Comments

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,7519 gold badges45 silver badges63 bronze badges
answered Jun 20, 2013 at 11:37

2 Comments

Well, your aliasing code is not an example of preventing global variable collisions...
If I were to write bar = 'foo' in your IIFE, I'd still be cluttering the global scope (implied globals)
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).

answered Jun 20, 2013 at 11:36

2 Comments

(function () {}()) is acceptable. Crockford prefers that style.
Fair enough, removed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.