Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between an IIFE and non-IIFE in JavaScript Modular approach

Recently while I was trying to learn more about IIFE and modules in JavaScript a question came to my mind that how is IIFE making a Module while not Immediately Invoking the function doesn't make it a module..

can anyone share with me the Difference between this code

var MODULE = (function () {
var my = {},
    privateVariable = 1;

function privateMethod() {
    // ...
}

my.moduleProperty = 1;
my.moduleMethod = function () {
    // ...
};

return my;
}());

and this code where the function is not Immediately Invoked..

var MODULE = function () {
var my = {},
    privateVariable = 1;

function privateMethod() {
    // ...
}

my.moduleProperty = 1;
my.moduleMethod = function () {
    // ...
};

return my;
};

Does the second block of code means that Module is just a function that itself returns an object?

IF I use the second variable like this

var ModuleObj = Module();

Will this work the same as the first Code block that I shared like IIFE.. Kind of confused...

like image 377
khaled4vokalz Avatar asked Feb 06 '16 05:02

khaled4vokalz


People also ask

What is an IIFE JavaScript?

An IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.

Does JavaScript support modularity?

js applications is the built-in modularity the environment provides. As demonstrated in [link unavailable], it's simple to download and install any number of Node modules, and using them is equally simple: just include a single require() statement naming the module, and you're off and running.

How do you call a function in IIFE?

(function () { //write your js code here }); Now, use () operator to call this anonymous function immediately after completion of its definition. (function () { //write your js code here })(); So, the above is called IIFE.


1 Answers

Yeah you pretty much got the idea of the difference between the two, let's look at why you might want one over the other.

An IIFE is useful to isolate the scope. It lets you keep the variables you define private inside the IIFE without polluting the global space around it. It's a nice way to compose a function that has some variables you don't need lurking around. Let's minimize this example a bit.

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

  var counter = {
    add: function () {
      count++;
    },
    subtract: function () {
      count--;
    },
    getCount: function () {
      return count;
    }
  }
  return counter;
})();

Counter.add();
Counter.add();
Counter.getCount(); // 2
Counter.subtract();
Counter.getCount(); // 1

What happens above is that we're able to compose this "counter" functionality without leaking the private information, like count. It'd be bad if other things could override it by accident. Also what happens is that right away we can assign Counter to the result of the IFFE -- the counter set of functions. Counter is now equal to that, and counter is able to retain access to count since it was defined in the same scope.

The benefit here is that we're able to assign a variable to this composition of functionality. The IIFE basically allows us to immediately return what we return inside of it. Since we assign Counter to the IIFE, and the IIFE returns the functionality inside of it, Counter is now a fully functional component.

We don't always have to use IIFE. It's really handy when you want to "tuck away" the implementation details and return an API.


So, what if we had the same thing, but it wasn't an IIFE -- just a function?

Just like your example, we'd have to call it in order to get the "instance".

var CounterFactory = function () {
  var count = 0;
  var counter = {
    add: //...
    subtract: //...
    getCount: //...
  };
  return counter;
};

var CounterA = CounterFactory();
var CounterB = CounterFactory();

CounterA.add();
CounterA.add();
CounterA.getCount(); // 2

CounterB.add();
CounterB.getCount(); // 1

See the difference? It's all about what the function is returning. In the first example we only get a single Counter instance, which may be perfectly fine. In the second example, it's more of a "factory" -- it generates an instance of counter and we can call that multiple times and get multiple instances of it.

like image 82
Atticus Avatar answered Sep 21 '22 22:09

Atticus