Comparing a closure with and without IIFE


#1

Hey,

If I use a closure inside an IIFE like this:

var outerFunction = (function() {            // this is an IIFE
  const outer = `I'm the outer function!`;

  var innerFunction = function() {
    const inner = `I'm the inner function!`;
    console.log(outer); // I'm a variable from the outer function!
  }

  return {
	kir:innerFunction
	} 
})();

It seems to me that the IIFE returns an object called outerFunction and add the method kir to it.
So that now, I can access the kir method of the object outerFunction with the following code:

outerFunction.kir();

But if I don’t use an IIFE for the same example:

function outerFunction () {
  const outer = `I'm the outer function!`;

  var innerFunction = function() { 
    const inner = `I'm the inner function!`;
    console.log(outer); // I'm the variable from the outer function!
  }

  return {			
	kir:innerFunction
	} 
}

I can access the method kir only if I run this:

outerFunction().kir();

Why it doesn’t work if I run this?:

outerFunction();
outerFunction.kir();

It seems to me that in the first example, when the IIFE runs automatically, it returns the object outerFunction and add the method kir to it.
But when I run outerFunction manually, it’s different and I can’t access the method kir.

I’m a bit confused!
Can some one please explain to me why I can’t access kir method in the second example by running this?:

outerFunction();
outerFunction.kir();

I guess this is more a question about understanding IIFE rather than the closure.

Thanks


#2

Part of your problem is your naming. In your IIFE, outerFunction is not a function. Its the return value of the outer function. A more accurate version would be:

var object = (function outerFunction() {            // this is an IIFE
  const outer = `I'm the outer function!`;

  var innerFunction = function() {
    const inner = `I'm the inner function!`;
    console.log(outer); // I'm a variable from the outer function!
  }

  return {
	kir:innerFunction
	} 
})();

The value in object is { kir:innerFunction }.

With your second example, outerFunction is the actual function. Running that function doesn’t modify the function, rather (as with the first example) returns an object with the kir property.

var object = outerFunction(); // returns { kir:innerFunction }
object.kir();

The difference is that with the second example, you can call outerFunction multiple times whereas with the IIFE, it happens only once.