1
function makeCounter() {
    var i = 0;
    return function() {
        console.log( ++i );
    };
}

var counter = makeCounter();
counter(); // logs: 1
counter(); // logs: 2

why the result of counter() invoked the second time is '2' but not '1'?

I try to find out its executing processes, so I rewrite makeCounter():

function makeCounter() {
    var i = 0;
    console.log('outer');
    return function() {
        console.log('inner');
        console.log( ++i );
    };
}

var counter = makeCounter();
counter();
counter();

and result is:

outer
inner
1
inner
2

Can I think that: i is the argument of function counter(), the first counter() executed, i changes to '1'. So the second counter() executed, i is '2'.

Evan Carslake
  • 2,267
  • 15
  • 38
  • 56

1 Answers1

1

As mentioned in the comments, this is an effect of what is called a closure in JavaScript. To fully understand it, I would recommend you have a look at How do JavaScript closures work from where the following quote is taken:

In JavaScript, if you declare a function within another function, then the local variables can remain accessible after returning from the function you called.

In your case, an anonymous function is declared within the makeCounter function, creating a closure (it will "remember" all the local variables at that point). The anonymous function will therefore still be able to access the variable i even after makeCounter has exited. As a result, each call to the anonymous function will increment the very same i variable.

function makeCounter() {
    var i = 0;
    return function() {
        console.log( ++i ); // Will always use the same variable "i"
    };
}

var counter = makeCounter();
counter(); // logs: 1
counter(); // logs: 2
Community
  • 1
  • 1
mhall
  • 3,671
  • 3
  • 23
  • 35