23

I'm pretty new to javascript and I read about the module pattern to provide some sort of namespace and have both private and public members, for example:

var module = (function() {
   var s = "Hello, i'm private and in closure!";
   return {
      myString : s,
      myFunc: function() { alert(s); }
   };
})();

I do see the benefits of that, because it gives you some of the advantages of object-oriented programming. But I've seen a lot of examples of an IIFE that doesn't get assigned to a variable. This (as far as I see) has no advantages at all compared to a normal function that you invoke:

1. IIFE

(function() {
   var s = "Hello I'm private!";
   $('#myButton').on('click', function() {
      alert(s);
   });
})();

2. Normal function

function Initialize() {
   var s = "Hello I'm private!";
   $('#myButton').on('click', function() {
      alert(s);
   });
}

Initialize();

They both have private variables that avoid the need of creating global variables and they both execute without returning any value to a variable. Although the second one gives you the option of choosing a good name that says a lot more than a potential large IIFE without the name, leaving the reader to find out what's happening. The answer I see everywhere is 'to avoid namespace pollution' but both approaches do that, the first one is just a bit harder to understand?

In short:

What is the benefit of using an IIFE over a normal function that I'm missing? Why should I use them?

Community
  • 1
  • 1
Alexander Derck
  • 11,742
  • 4
  • 43
  • 73

1 Answers1

19

Sometimes you need to define and call function at the same time and only once so in this case anonymous function helps you. In such situations giving functions a name and then calling them is just excess.

Further sometimes you wants to create a namespace for your variables. So anonymous functions helps you there too. For example

(function($) {
    $.fn.pluginName = function(opt) {
        // implementation goes here...
    }
}(jQuery));

In above case you can safely use $ as jQuery synonym in your code.

If you define a function with name as shown below, then it will create global variable with function name as you defined.

function myFunction() {
    // function code goes here.
}
myFunction();

But if you define it without name then it won't create any global variable and your global namespace will not be polluted.

(function myFunction() {
    // function code goes here.
}());

Function with names are useful only when you need to call them from different places in your code.

Shaiju T
  • 5,220
  • 15
  • 91
  • 175
Mohammad Usman
  • 30,882
  • 16
  • 80
  • 78
  • 2
    You have an extra variable name available when you use an IIFE indeed but in my opinion the ability to choose a good name, that describes the function so you know what it does without reading the entire thing, far outweighs that benefit. – Alexander Derck May 04 '16 at 08:07
  • 6
    yes, functions with good names are useful sometimes but when you are writing a library that a lot of people will use then there is always a risk that a function that you wrote may be overridden by function from some other script. – Mohammad Usman May 04 '16 at 08:11
  • Good point, they could surely be beneficial when there are a lot of different scripts loaded – Alexander Derck May 04 '16 at 08:13
  • @AlexanderDerck which is what the namespace pollution argument is all about. When talking about modules it's a potential bad thing to name your scoping function. If there's a variable in the including script with the same name as your scoping function, that will be overriden if your module is included and since the best name of the function would likely be the same as the module it would provide any information. – Rune FS May 04 '16 at 08:20
  • @RuneFS I would say it's only useful then for large projects, that a lot of different people work on. For small projects (that I have now) I'll stick with named functions for clarity since I only use jQuery and maximum 1 file at a time. Thanks for the input! – Alexander Derck May 04 '16 at 08:31
  • 5
    Just to add: Even if you are using IIFE good practice is to name that also i.e. (function foo() { console.log("Hii"); })(); This will help you in stack trace while debugging or logging. Another important point is IIFEs are useful because they are put into stack on demand only when they are called. Thus when we call IIFE it is loaded, its scope is created and once the work is done if No Closure is maintained on any property of IIFE it gets released. In later case i.e. Not IIFE approach first it will be hoisted then loaded and will remain in memory until tab is closed – user2485435 Sep 01 '17 at 23:15