1

Trying to figure out why self invoking function is preserving the private value while other type is not.

Does increase the value

var a = function(){
    var myval=10;
    return function(){
          return myval++; 
    }
}();
console.log(a());
console.log(a());
console.log(a());

Output : 10,11,12

while this code does not increase the value

var a = function(){
    var myval=10;
    return function(){
          return myval++; 
    }
};
console.log(a()());
console.log(a()());
console.log(a()());

Output :10,10,10

LilRazi
  • 690
  • 12
  • 33
  • I have to head out right now but off the top of my head I believe it's because the IIFE in #1 creates a scope for myval and each instance of invoking the inner function points to that myval. The second one creates a new scope with a new myval each console.log output so it repeatedly returns 10. – timolawl Apr 27 '16 at 19:56
  • Curious is, why 10? If you change (in not self invoked function) `myval++` to `myval+1` or `++myval` it would return 11 (always, as should when function is not self invoked). – Przemysław Melnarowicz Apr 27 '16 at 19:59
  • does that mean first method create just one instance of outer function while second method create 3 instance of outer function ? – LilRazi Apr 27 '16 at 19:59
  • 1
    post increment operator returns value *then* increments. In case you're wondering about it in a for-loop however: http://stackoverflow.com/a/4706225/5812121 – timolawl Apr 27 '16 at 20:03
  • Guy who deleted his comment was right - post increment returns not incremented value (so if you increment before return, and return variable its right). – Przemysław Melnarowicz Apr 27 '16 at 20:03
  • @LilRazi I believe that is correct. Someone correct me if I'm wrong. Will check back in this thread later.. – timolawl Apr 27 '16 at 20:06

2 Answers2

3

In your first example, a is a closure instance that gets repeatedly called in your console.logs:

console.log(a());  // <-- a is a closure, invoked once
console.log(a());  // <-- the same closure, invoked the second time
console.log(a());  // <-- the same closure, invoked a third time

However, in your second example, a is the outer function that gets repeatedly called in your console.logs:

console.log(a()());  // <-- a is the outer, returning a new closure, invoked once
console.log(a()());  // <-- a is the outer, returning a new closure, invoked once
console.log(a()());  // <-- a is the outer, returning a new closure, invoked once

So what you're doing in your second example, is recreating a new closure each time, rather than re-invoking the same closure instance as in your first example.

smaili
  • 1,245
  • 9
  • 18
2

The outer function only gets called once in the first case, but in the second one you are calling it three times, and each time you are initializing that closure's individual myval back to 10; so at the end you have three separate copies of myval that all have the value 11 from being incremented once.

Your first example is more equivalent to:

var a = function(){
    var myval=10;
    return function(){
          return myval++; 
    }
};

var b = a();

console.log(b());
console.log(b());
console.log(b());

While your second one is like:

var a = function(){
    var myval=10;
    return function(){
          return myval++; 
    }
};

var b = a();
var c = a();
var d = a();

console.log(b());
console.log(c());
console.log(d());

Calling a() creates a new inner function each time, so in the first case, where you called a once, you have one inner function that has a single myval in scope, but in the second case you created three separate inner functions that each have their own myval in scope.

Paul
  • 139,544
  • 27
  • 275
  • 264