You said:
I understand how this works, but I do not understand why he is doing it this way
If you do not understand why he is doing it this way then you don't really understand how it really works.
What you see in that example is a closure. And in my opinion this is a better introduction to closures than a lot of the introductory examples out there.
A closure is a bit like a global variable. When using a global variable a function access data outside its own scope. For example:
var x = 2;
function amplify (n) {
return n * x; // here a function is using x which does not exist
// in the function's own scope
}
Closures are similar, except that they are hidden in global scope. Every time an inner function access a variable form an outer function it does so using the same mechanism as how global variables work except that that variable is not visible form global scope. Let's now see a simple example similar to the one in your post:
var amplify;
function init () {
var x = 2;
amplify = function (n) { return n * x };
};
init();
console.log(amplify(5)); // prints 10
console.log(x); // syntax error
So in this case, as in the code you posted, the variable x
behaves like a global variable but is invisible in global scope. Just like global variables it is visible to all functions declared in the scope it's in. And because x
is used by the amplify()
function it is not freed or garbage collected when the init()
function returns. And that is all what closures are about - this weird contradictory concept of private globals. Nothing more.
In this specific use-case the advantages are minimal. You save memory by not allocating the array each time you call the function but that's about it. But closures are much more powerful than that. You can for example share the same variables with multiple functions yet still hide it from global scope. For example:
var amplify;
var setFactor;
var getFactor;
function init () {
var x = 2;
amplify = function (n) { return n * x };
setFactor = function (n) { x = n };
getFactor = function () { return x };
};
init();
amplify(5); // returns 10
getFactor(); // returns 2
setFactor(4);
amplify(5); // returns 20
console.log(x); // still a syntax error
As you can see. Closures allow you to capture and share data amongst related functions yet hide that data from all other functions. In a way, closures are almost functional equivalents to objects. So my guide of when to use closures is when you need modularisation but objects are overkill. The most common use-case for this is capturing state for callbacks. But caching (memoization), as shown by the example code you posted, is a good use-case as well.