Closure is one of those terms you hear thrown around a lot in JavaScript development, but it’s often misunderstood and mistaken for scope. Scope is related and plays an important role in closure, but is not the same thing.
Closure is when a function has access to its original context. Here’s the Mozilla Developer Network’s take on closure:
A closure is a special kind of object that combines two things: a function and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created.
An example:
function speak() {
var greeting = 'hi';
function saySomething() {
console.log(greeting);
}
saySomething();
}
speak(); //hi
In this example, saySomething
is a closure–it is a function that has access to its original context. Put differently, it is a function AND the environment in which it was created because it can access greeting
, a variable from the parent function’s scope. greeting
is not part of saySomething
‘s scope.
Another example:
function speak(name) {
var greeting = 'hi';
function saySomething() {
console.log(name + ' says ' + greeting);
}
saySomething();
}
speak('billy'); //billy says hi
In this example, speak
defines a variable AND takes an argument. saySomething
is still a closure–it can reference variables and parameters that are part of its environment.
A common misconception about closure is that you have to return a function for a closure to exist. This is NOT true. However, let’s expand the existing example by returning the saySomething
function instead of executing it:
function speak(name) {
var greeting = 'hi';
function saySomething() {
console.log(name + ' says ' + greeting);
}
return saySomething;
}
var billySpeaks = speak('billy');
var nobodySpeaks = speak('nobody');
billySpeaks(); //billy says hi
nobodySpeaks(); //nobody says hi
You’d think name
and greeting
would only be accessible at the time of execution, but that’s obviously not the case. That’s because local variables and arguments that are in scope at the time a closure is created remain accessible–they are part of the environment.
In the preceding example, speak
is a closure that consists of the parameter name
, the local variable greeting
and the function saySomething
when it was created. Therefore, billySpeaks
and nobodySpeaks
have access to them after execution has finished.
[…] Closure […]