0

In this example on Wikipedia (http://en.wikipedia.org/wiki/Closure_(computer_programming) ) it claims that invoking the variable closure1 with closure1(3) will return 4. Can someone walk through the example - I don't understand.

function startAt(x)
   function incrementBy(y)
       return x + y
   return incrementBy

variable closure1 = startAt(1)
variable closure2 = startAt(5)

Invoking the variable closure1 (which is of function type) with closure1(3) will return 4, while invoking closure2(3) will return 8. While closure1 and closure2 are both references to the function incrementBy, the associated environment will bind the identifier x to two distinct variables in the two invocations, leading to different results.

If it helps, here's my current understanding. variable closure1 = startAt(1) sets the variable closure1 to the function startAt() which by default is initialized to 1. However, invoking closure1(3) sets this default value to 3. What I don't understand then is where does y come from.

variable closure1 = startAt(1)
Snowcrash
  • 80,579
  • 89
  • 266
  • 376
  • Related: [How do JavaScript closures work?](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – apsillers Nov 14 '14 at 14:49
  • Closures are just the poor mans classes. Classes are just the poor mans closures. – leppie Nov 14 '14 at 15:24

1 Answers1

0

When you run startAt, you're creating a new function. Every time you run startAt, you're creating a brand new function. Therefore, we understand that the code

variable closure1 = startAt(1)
variable closure2 = startAt(5)

creates two distinct functions and stores them in colsure1 and closure2. The function startAt is like a factory that returns new functions. You've called it twice, and created two functions. Those two created functions are stored inside closure1 and closure2.

Here's what "closure" means: each function caries around its own variable environment. A variable environment is the set of external variables the function can see. A function builds its variable environment when it is created, based on all of the variables currently in scope. (The technical definition of a closure is: "functional code plus variable environment".)

When a call to startAt creates a new function, that new function builds its variable environment. The new function's variable environment includes the variable x that exists in-scope within the particular call to startAt.

So, the first call to startAt(1) has a variable x that equals 1. The function that is created inside that call to startAt has a variable environment includes that x equal to 1.

Functions can have arguments. The functions created by startAt each expect a single argument called y. Therefore, when you perform x + y when calling the created function, the y is supplied as an argument by that particular call, and the x is supplied by that function's variable environment. When you call closure1(3), the value of the argument y is 3 and the value of x (from the function's variable environment) is 1, so you get the result 4.

The second call to startAt creates a totally new variable x. This x has a value of 5. The function created by this second call to startAt has a different variable environment, which includse this new x whose value is 5. When you call that newly created function with closure2(3), we have x=5 and y=3, so x+y gives the result 8.

apsillers
  • 112,806
  • 17
  • 235
  • 239
  • This I understand: "the first call to startAt(1) has a variable _x_ that equals 1." This I don't: "The functions created by startAt each expect a single argument called _y_". Where has the `y` come from? – Snowcrash Nov 14 '14 at 19:47
  • @SnowCrash From the definition of the created function: note the `y` in `function incrementBy(y)`. Arguments are function-local variables (whose values are supplied a function-call time). By specifying a formal argument `y`, you say "Whenever this function is called, it will be supplied a value. We call this supplied value `y`." – apsillers Nov 14 '14 at 20:06