What is a Closure?
In JavaScript, a closure is an inner function that has access to the outer function’s variables.
The closure has three scope chains: it has access to its own scope, it has access to the outer function’s variables, and it has access to the global variables. (For more on JavaScript scoping, check out this post.)
In this example, inner()
has access to all three variables, each located at a different scope. In constrast, outer()
can only access state
and country
, as evidenced by the error when it tries to log the value of city
.
Uses for Closures – Events & Callbacks
A closure has access to the outer function’s variables even after the outer function has returned. This can be particularly useful when dealing with asynchronous events and callbacks.
When you click on the Sam button, the alertSam
callback is called. alertSam
was defined as the return value of buttonAlert
, which is createMsg
. This inner function, or closure, retains access to the variables in its parent function. So even though buttonAlert
‘s execution completed when alertSam
was originally defined, alertSam
still has access to the variable intro
because of the closure.
Potential Pitfalls – Loops
It might seem like the following code should work properly, but when you click on each of the buttons, they’ve all be numbered #4. What’s going wrong?
JS Bin on jsbin.com
The closure does ensure that the onclick
callbacks have access to i
, but unfortunately only its final value. In order to capture each value as the loop increments, you need to create a unique closure for each iteration and button. If you enclose the function holding the alert
inside another function, captureNumber
, each value of i
is then stored as a local value of num
in four separate closures for each button.
Now the buttons operate as expected.