So I'm new to programming and I'm trying to learn JS with the book Eloquent Javascript.
So far so good, until I reached an example with the following code
function makeAddFunction(amount) {
function add(number) {
return number + amount;
}
return add;
}
var addTwo = makeAddFunction(2);
var addFive = makeAddFunction(5);
show(addTwo(1) + addFive(1));
note: show is like alert, only it shows the variables on the screen of a JS console the tutorial has integrated.
The author says this is an example to show how lexical scoping allows to synthesise functions. Chapter here
What I don't understand is how addTwo
and addFive
, which supposedly are variables, can send parameters to the functions makeAddFunction
and add
, and more specifically, how does the function add
knows that the parameter the variables are sending is the parameter number
.
Thanks for your help guys!
In javascript, a function is a first-class object, that is, it can be passed around, assigned to a variable, etc. The variables addTwo and addFive contain functions. Those functions are generated by the "factory" function makeAddFunction.
The functions that addTwo and addFive contain carry with them the scope that existed when they were created. That is, when addTwo, for example, was created, the parameter "amount" was 2. So addTwo, in essence, is the following function:
function addTwo(number) {
return number + 2;
}
When someone calls addTwo(), it's not passing anything back to makeAddFunction. MakeAddFunction has already run and is finished. However, the scope created within makeAddFunction (in which "amount" equals 2) lingers in the addTwo function.
addTwo
and addFive
are variables -- but they're function variables. Look at typeof(addTwo)
-- it's a function. It's like if you did this:
var addTwo = function(x) { return x + 2; };
It's the same as this:
function addTwo(x) { return x + 2; }
(Edit: As Šime pointed out, they aren't exactly the same. See here for an explanation of the difference between the two.)
The example will hopefully make sense once you understand that. You can even do weird things like this, declaring an anonymous function and invoking it right away:
var seven = function(x) { return x + 2; }(5);
Which is literally, at the physical machine code level, the exact same as: Which is equivalent to for all purposes relevant to this question:
function addTwo(x) { return x + 2; }
var seven = addTwo(5);
Edit:
Perhaps a less confusing "prequel" to this is the following:
function makeTheAddTwoFunction()
{
return function(x) { return x + 2; }
}
var addTwo = makeTheAddTwoFunction();
This is silly, but serves to illustrate functions that make functions. Of course, that sort of function usually will accept arguments so that it can make different functions each time, but there you go.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With