1

I'm trying to learn Javascript by reading Eloquent Javacript. I'm on the chapter dealing with functions and I'm stuck trying to figure out how the code below works. I don't see how the add function ever gets called. I see them calling addTwo and addFive but those names are different than add. The result of this code being run is 9. Can someone please explain this to me.

 function makeAddFunction(amount) {

     function add(number) {

         return number + amount;
     }

     return add;
 }

 var addTwo = makeAddFunction(2);

 var addFive = makeAddFunction(5);

 show(addTwo(1) + addFive(1));
user2864740
  • 60,010
  • 15
  • 145
  • 220
Joe Elmore
  • 117
  • 2
  • 13
  • 2
    That's ok. google "javascript closures". it has too many resources on the web for us to start explain. – Royi Namir Nov 05 '13 at 18:45
  • http://stackoverflow.com/questions/111102/how-do-javascript-closures-work?rq=1 – user2864740 Nov 05 '13 at 18:57
  • Ohh, exact duplicate: http://stackoverflow.com/questions/4116011/javascript-example-question-lexical-scoping-closure-eloquent-javascript?rq=1 – user2864740 Nov 05 '13 at 18:57
  • possible duplicate of [Syntax of Closures](http://stackoverflow.com/questions/17982637/syntax-of-closures) – Naftali Nov 05 '13 at 18:58

6 Answers6

1

In makeAddFunction, a function is created, called add. This function is returned.

makeAddFunction is called twice with 2 different parameters, and stored in two variables, addTwo and addFive.

Calling addTwo() and addFive() is calling the functions created by add(), with the "amounts" 2 and 5 respectively.

addTwo(1) + addFive(1) == (1 + 2) + (1 + 5) == 9

Sometimes these types of 'closures' are called Builders, or Factories. The makeAddFunction 'builds' a special version of add based on the parameter you pass to makeAddFunction.

The addTwo function would look like:

function addTwo(number) {
    return number + 2;
}
azz
  • 5,852
  • 3
  • 30
  • 58
  • "indirectly" was probably poor word choice. – azz Nov 05 '13 at 18:49
  • This does not explain HOW the code works. It merely translates the code to English. – Josh Nov 05 '13 at 18:49
  • Generally explaining code involves translating it into English in a logical manner... – azz Nov 05 '13 at 18:55
  • I can see how they arrive at the number 9 but I still don't understand how addTwo and addFive pass the value 1 to the add function. I'm not even sure if I'm explaining it correct for you to understand what I'm not understanding. – Joe Elmore Nov 05 '13 at 19:48
  • For example: when they say var addTwo = makeAddFunction(2); I can see that the value 2 is being set as the argument "amount" because they called the function by it's correct name which is makeAddFunction. I don't understand how the value 1 is being set as the argument "number" in show(addTwo(1) + addFive(1)); because the function is called add, it's not called addTwo or addFive? – Joe Elmore Nov 05 '13 at 19:59
0

The makeAddFunction create a closure that sets amount as whatever number you pass in and returns a function that will add that amount to whatever number you pass to the new function and return it.

Naftali
  • 144,921
  • 39
  • 244
  • 303
0

Follow the SO Linked/Related Questions on the right. Anyway ..

This is explained the article, albeit with a lot of fluff. Anyway, with a bit of fluff-cutting here is a "annotated" version:

.. functions [do] not just package up [some code to run], but also an environment. [..] a function defined inside another function retains access [to lexical variables (like "amount")] that existed in [the outer function] at the point when [the inner function] was defined.

Thus, the [inner] add function in the above example, which is created when makeAddFunction is called, captures an environment [including the "amount" variable of the outer function]. It packages this environment, together with [the code to run], into a value [(which is a fancy way to say functions are just objects)], which is then returned from the outer function.

When this returned function ([which has been assigned to] addTwo and addFive) is called, [the called function has access to] the captured environment ([and the "amount" variable which still contains the value initially passed to makeAddFunction]). These two values ([which are currently named by] "amount" and "number") are then added, and the result is returned.

I am not found of the original usage of "value" and have edit those parts a good bit - in JavaScript, variables (not values) are bound in closures.

Community
  • 1
  • 1
user2864740
  • 60,010
  • 15
  • 145
  • 220
0

My best advice is you try to learn a bit about Javascript closures. Really. I might not be the answer you are looking for, but it is the best you can do if you want to understand what's happening there.

Get yourself a copy of any good javascript book. Let me suggest 'Javascript - The Good Parts' by Douglas Crockford.

For some of us, Javascript closures were not something we grokked. I hope it's easier for you.

Anyway, makeAddFunctionis a function creator. It creates new functions which are tied to the parameter you passed to makeAddFunction. Therefore, the addTwo variable receives and stores a new function, which you can invoke later by appending parentheses to it, i.e. addTwo().

The parameter you pass to addTwo, i.e. 1on invokation addTwo(1) is passed to the add function, because addTwo is nothing more than an add function where the amount var has a fix value of 2.

Carles Andres
  • 1,761
  • 1
  • 15
  • 22
0

var addTwo = makeAddFunction(2);

When you call makeAddFunction(2) initially, the amount var is within its function scope where add can see it. addTwo now is set to the add function that makeAddFunction(2) returned.

addTwo(1)

Remember addTwo is now set to what makeAddFunction(2) returned, which is the function add, and amount is set to 2 within makeAddFunction(2)'s scope. add just returns its argument (1), plus the amount (2) in makeAddFunction(2)'s scope.

The same goes for addFive(5).

Javascript Ninja or The Good Parts are good reads that explain closures in detail. I'd highly suggest picking up those.

jbarnett
  • 984
  • 5
  • 7
-1

Javascript relies pretty heavily on higher-order functions. Functions can be returned, assigned to variables, and passed around as values. This comes in handy in a lot of situations, especially when dealing with evented programming (JS's direct lineage from the its most prolific implementation in the browser.)

http://en.wikipedia.org/wiki/Higher-order_function

What you are seeing is a function that creates a function. It could be considered a "factory" for a function with one preset argument.

DeaconDesperado
  • 9,977
  • 9
  • 47
  • 77