There are two very quick processes here.
If we were to write this:
function makeDigitReader () { var names; return function (n) { return names[n]; }; }
var myDigitReader = makeDigitReader();
You would correctly guess that myDigitReader would be given the inner function.
What they're doing is skipping a step.
By adding the parentheses, what they're doing is firing the function the instant that it's defined.
So you're getting this happening:
var myDigitReader = function () {
var names = [...];
return function (n) { return names[n]; };
};
myDigitReader = myDigitReader();
See what's happened?
You've returned the inner function as the new value to what used to be the outer function.
So the outer function doesn't exist anymore, but the inner function still has access to the names
array.
You can return an object instead of a function, as well.
And those object properties/functions would have access to what was initially inside of the function, as well.
Normally, you will either see these immediately-invoking functions wrapped in parentheses var myClosure = (function() { return {}; }());
.
If you intend to run one without assigning its return to a value, then you need to put it in parentheses, or add some sort of operand to the front of it, to make the compiler evaluate it.
!function () { doStuffImmediately(); }(); // does stuff right away
function () { doStuffImmediately(); }(); // ***ERROR*** it's an unnamed function
Hope that answers all of the questions you might have.