A function may have many local variables defined within it, but it also has access to all variables in any scope enclosing it (including the global scope). This is known as the scope chain.
Functions also have access to the parameters of an enclosing scope.
Understanding the scope chain is essential to understanding closures!
Getting Some Closure
A closure is created when a function references variables from its enclosing context. Or simply put, when an inner function references variables from an outer function. Even if the outer function exits, the inner function holds a reference to any variables it has referenced from the outer function, including the entire scope chain.
After we call
createPersonalGreeting, it returns the inner function (
greetFunc) and exits. All of its local variables are completely hidden from us. Remember, though, the inner function we get back from
createPersonalGreeting can still reference those seemingly “lost” variables. So, when we call
helloFred, it remembers the name “Fred” and the greeting “Hello there”.
Organizing Code with Modules
Before we continue, we introduce a new technique known as an Immediately Invoked Function Expression (IIFE). It does exactly what it’s called.
Now, we have everything we need to know to create a module. Let’s say our application is a simple Hello World program. We could stuff everything for our application in the global scope, but we are better programmers than that! We’ll pack all the logic into a module and expose a pretty little interface for working with it.
We can use the
HelloWorld module’s public function,
sayHello, to display a greeting to the console. Any variables or functions used by the module is contained within the IIFE. The only way to interact with the internals of the module is through the public interface we’ve specified in the returned object.
Let’s expose some functions to set the name and greeting of our
HelloWorld module. All we have to do is add two new functions to our return object.
Now, our module allows us to change its internal state, but only via the public interface we’ve exposed.