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.