What are JavaScript closures?
MDN web docs give this great definition of what a closure is:
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.
A practical example
In this example, the toString function uses the count variable, which is defined and initialized inside the makeCounter function. This works because the toString can access variables defined in the makeCounter function, since toString is defined inside makeCounter.
The makeCounter function ha also a return statements, let’s analyze it:
it returns an object literal
the object has four properties, which it turns out they all are functions (in JS functions are first-class objects, so variables, properties, and so on, as they can hold values, arrays, objects, can also hold functions)
this function also accesses they’re enclosing function variable count, and the last one access the toString function which is defined inside makeCounter.
It is important to note that no one can access the count variable and toString function without calling makeCounter first, which is the only way to access these.
I tried to use the most beginner-friendly syntax in the above example, because if you want to learn a bit about closures, but you new to JavaScript it could be difficult to understand some of its syntaxes. Anyway, this is the same example with a shorter syntax:
Play-pause on click
How many times you want for instance a button to pause the execution of something when clicked and resume it when clicked again. This is an example where closures can be very helpful to achieve this, as you can save the current play status in the event handler without having to make it public.
The code above achieves this:
the play status is saved in the playPause function
the function actually returns a function using the playing status variable
the returned function is the actual onclick handler, which changes the play status and plays and stops the execution
when to our example button is added the onclick event handler, note that the playPause function is invoked, that is because the functions ‘sets up’ the ground (status) for the actual handler, so it has to be invoked in order to return the actual handler.
You may be wondering why we didn’t just define the playin’ status and use it in the playPause function, without doing this strange thing of creating a function that returns another function. This is a good question indeed, but if we make something like this:
In this case, every time we click the button, it will stop the execution every time and never resumes it, because the playing value is set to true every time the event handler is called.
Summarizing
JS closures can be useful every time we need to create a ‘private’ scope for some variable, function, or whatever, when we want to ‘set up the ground’ for a function (like in the play-pause example, where we initialized the status and then returned the actual handler), and in many other cases I will maybe write about in the future. The important thing to remember about closures can be summarized as:
JS Closures lets you create functions that access their enclosing function’s scope.
Cover Image by Caspar Camille Rubin on Unsplash
Top comments (0)