In your code:
> function setup(x) {
> var i = 0;
When setup is called, a new execution context is created with local variables x and i. When execution begins, x is assigned a value of the passed array and i is set to zero.
> return function () {
> console.log(i);
> return x[i++];
> };
This anonymous function is returned. It has a closure to the outer execution object that is placed on its scope chain (so is the global execution object).
So it has a closure to both i and x, whose values can now only be changed by the function.
> }
>
> var next = setup(['a', 'b', 'c']);
The returned function is assigned to next, so it's no longer anonymous.
>
> console.log(next());//a
When this line executes, next returns x[0], which is "a", and increments i to 1.
> console.log(next());//b
When this line executes, next returns x[1], which is "b", and increments i to 2.
> console.log(next());//c
When this line executes, next returns x[2], which is "c", and increments i to 3.