I started learning Javascript about a year ago while I was attending Flatiron School. JS in general was a bit weird at first coming from a Ruby/Ruby on Rails background. One of the most challenging things for me to grasp in JS was closures.
What is a closure
First, let's talk a little bit about what a closure is in JS. Here is how (MDN)(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) defines a closure.
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.
Scope
To understand how closures work, it's a good idea to make sure you have a good understanding of the scope in JS. This defines what variables are available in what context. Global variables are available anywhere in the code and are created outside of any functions, typically they are created at the beginning of the code. Local variables (local scope) are created within a function and are only available within that function.
Syntax
A closure is basically a nested function, you will have an inner function and an outer function. In the example below updateClicks
is the outer function and reportClicks
is an inner function. What this means is that reportClicks
has access to any variables that are defined in the updateClicks
outer function as well as any functions that are defined within its own scope. If you notice here we are not calling reportClicks()
we are simply just returning it, therefore we have access to it later.
function updateClicks() {
let clicks = {};
function reportClicks(item) {
clicks[item] = clicks[item] + 1 || 1;
console.log(item, clicks);
}
return reportClicks();
}
Variables within closures
Variables that are defined within closures are just like any other variables which means they can be updated and changed. Let's take a look at another example. In the below example we are using an in/else statement to determine what meal
will return based the the criteria met.
function hungry(meal) {
function whatsForDinner() { // whatsForDinner() is an inner function, a closure
if (!meal) { // whatsForDinner() uses argument provided to the parent function
console.log('Is it time to eat?');
} else if (meal === 'Port Chops') {
console.log('These are my favorite');
} else {
console.log(`I'm eating ${meal} for dinner.`);
}
}
function digest() { // digest() is an inner function, a closure
meal = undefined; // digest() uses argument provided to the parent function
}
return {
whatsForDinner,
digest
};
}
Summary
This is a little bit about how nested functions or closures work in JS. Closures can definitely be tricky to grasp, especially if you aren't well versed in JS. Practice with them and just like anything else, you'll be able to work with them and implement them in your apps!
Top comments (2)
Should return reportClicks; ?
@Thinh Buzz Thanks!