foo is returning a function, which takes one argument called y.
So, when you call foo you get a function back, which you can execute whenever you like with an argument, which becomes the value of y.
Notice that the returned function is anonymous, but as foo returns it, you can effectively bind the function to a variable. Here, foo is being called, and the return value is being assigned to bar.
Now, you may ask "well, if the function return has the argument y, and I call bar(10), now y is given the value 10, but now what's x?
Well, x already has a value, which it got when foo was first called. Here's a "workflow" representation.
- A function called
foo is defined, which takes one argument x. It returns an anonymous function which takes one argument called y.
- The function
foo is called with a value of x equal to 2, and it's return value is bound to bar. bar is now a reference to the anonymous function, inside which all values of x are equal to the value of x foo was called with, i.e. 2.
When the anonymous function bound to bar is called with bar(10), the argument y is given the value 10. bar executes the following
alert(2 + 10 + (++tmp));
So you might ask now, "what's tmp then"? Well, that should be reasonably straightforward to deduce if you followed the above. When the anonymous function was returned from foo, any references of variables local to were bound to the values foo had a