0

I've read through the following code for Example 7 posted on the following answer for How do JavaScript Closures work?

function newClosure(someNum, someRef) {
    // Local variables that end up within closure
    var num = someNum;
    var anArray = [1,2,3];
    var ref = someRef;
    return function(x) {
        num += x;
        anArray.push(num);
        alert('num: ' + num +
            '\nanArray ' + anArray.toString() +
            '\nref.someVar ' + ref.someVar);
      }
}
obj = {someVar: 4};
fn1 = newClosure(4, obj);
fn2 = newClosure(5, obj);
fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4;
fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4;
obj.someVar++;
fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5;
fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5;

I used the same logic for my example

function increment() {
    var id = 0;
    return function(number) {
        id += number;
        alert('Unique ID: ' + id);
    }
}

six = increment();
fourteen = increment();

six(6);
fourteen(8);

In the example I took inspiration from,

fn1(2); //num 7

The num outputs 7 because according to my understanding, it has been set to 5 from the previous call first time around. So using the same reasoning, I expected the fourteen(8) call to return the number 14 because I believed ID would have been updated to 6 rather than stay at 0. Why is the variable not static? How would I account for it to be static?

I also tried to have the function set a parameter of number and set the ID equal to the parameter but that did not update it either.

http://jsfiddle.net/de9syawe/4/ to show.

Community
  • 1
  • 1
Yash Chitneni
  • 151
  • 1
  • 10

1 Answers1

2

newClosure's closure will capture the num initialized to someNum each time it is called. Thus, f1 has its own num, which starts at 4, is incremented by one to 5, then is incremented by two to 7. Meanwhile, f2 has its own num, which starts at 5, is incremented by one to 6, and again by two to 8. The interleaving of f1 and f2 calls might confuse you, but they are completely separate, and share no variables.

In the same vein, the closure that increment constructs will capture id at value 0. six has id starting at 0, incrementing by six to 6. fourteen independently starts at its own 0, and is incremented by eight to 8.

Compare:

var globalCounter = 0;
function incrementWithGlobalCounter() {
    var counter = 0;
    return function(number) {
        counter += number;
        globalCounter += number;
        alert('Counter: ' + counter + '; Global Counter: ' + globalCounter);
    }
}

var one = incrementWithGlobalCounter();
var two = incrementWithGlobalCounter();

one(1); // 1, 1
one(1); // 2, 2
two(1); // 1, 3
two(2); // 3, 5
one(5); // 7, 10

Here, globalCounter is captured by the outer closure, so it is shared by all inner closures; the counter is captured by the inner closure and local to outer closure, so it will be independent for each inner closure.

Amadan
  • 191,408
  • 23
  • 240
  • 301
  • Thank you so much @Amadan You were right, I was confused with the f1 and f2 calls. That was a silly/stupid overlook. I didn't realize by calling fourteen, I was making a different call. But thanks for also showing me the globalCounter and making me think about the outer closure! – Yash Chitneni Dec 26 '14 at 01:33