DEV Community

loading...
Cover image for Closures In JS

Closures In JS

randysteele profile image Randy Steele ・2 min read

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

Alt Text
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();

}

Enter fullscreen mode Exit fullscreen mode

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
    };
  }
Enter fullscreen mode Exit fullscreen mode

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!

Resources

MDN
ECMA-262-3 in detail. Chapter 6. Closures

Discussion (2)

pic
Editor guide
Collapse
thinhbuzz profile image
Thinh Buzz

Should return reportClicks; ?

Collapse
randysteele profile image
Randy Steele Author

@Thinh Buzz Thanks!