I'll start by going over what your code does, then further explain what makes it a closure.
var digit_names = (function() {
var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
return function (n) {
return names[n];
};
}());
alert(digit_names(3)); // 'three'
To begin with, you have an Immediately Invoked Function Expression (iife):
var digit_names = (function () {...}());
What this does is it defines a function, and then immediately executes (or, invokes) it. In your case, the function is:
function() {
var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
return function (n) {
return names[n];
};
}
What this function does is it first defines a names
variable that contains an array, then it returns an anonymous function that will return a single element from that array when executed.
Now lets go back to your original code.
var digit_names = (function() {
var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
return function (n) {
return names[n];
};
}());
alert(digit_names(3)); // 'three'
digit_names
is defined as containing the return value of the iife. that means, digit_names
contains this function:
function (n) {
return names[n];
}
Since that function was defined inside the iife, it has access to all variables defined within the iife, making names
defined as the array. The fact that the function references the names
array is what makes it a closure.
digit_names
contains the return value of the iife which is a function that returns a value from the names array. By referencing the names array, that function can be called a closure. Put another way, digit_names
references a function that references a variable that was defined within the same scope that the function was defined in.
Here's another example:
var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
var digit_names = function (n) {
return names[n];
}
alert(digit_names(3)); // 'three'
In this case, digit_names
still stores a reference to the anonymous function, and the anonymous function is still a closure, however the names array is no longer private. The end result is the same though, because names
is only created once.