Skip to content
Hou - Engineer & Tech Educator

Learn Modern JavaScript - Closures

JavaScript, beginner, tutorial, learn-modern-javascript1 min read

Introduction

By the end of this tutorial, you will be able to:

  • understand how closures work

Closures

JavaScript functions have lexical scopes. Where a variable is accessible to a function depends on where that variable is declared within the code, hence the term lexical.

A function that is nested inside of another function has access to variables declared in its local scope, in the outer function’s scope and in the global scope. The nested function is called a closure.

Take a look at the code below. What do you think will be logged to the console? Why?

1const lastName = "Chia";
2
3const printPerson = () => {
4 // name is a local variable created by printPerson
5 const firstName = "Hou";
6
7 // logNameAndLocation() is the closure, since it's nested inside of printPerson()
8 const logNameAndLocation = () => {
9 const location = "Brooklyn, NY";
10
11 // access a variable declared in the local, outer function, and global scopes
12 console.log(`${firstName} ${lastName}, ${location}`);
13 };
14 logNameAndLocation();
15};
16
17printPerson();

Calling printPerson() will in turn invoke logNameAndLocation(), which in turn successfully logs the firstName, lastName, and `location variables to the console, since these variables live in the outer function, global, and local scopes, respectively.

Let's modify the printPerson() function to return a function reference instead:

1const lastName = "Chia";
2
3const printPerson = () => {
4 const firstName = "Hou";
5
6 const logNameAndLocation = () => {
7 const location = "Brooklyn, NY";
8 console.log(`${firstName} ${lastName}, ${location}`);
9 };
10 return logNameAndLocation;
11};
12
13const printPersonNameAndLocation = printPerson();
14printPersonNameAndLocation();

Now, the logNameAndLocation() inner function is returned from the printPerson() outer function.

printPersonNameAndLocation() references an instance of logNameAndLocation(), which is returned from printPerson() when printPerson() is called.

Does the code still work? Would the firstName varible, which belongs to the outer function, still be accessible?

The answer is yes! As it turns out, a closure maintains a reference to the lexical environment, consisting of any variables that were in-scope at the time the closure was created.

Therefore, printPersonNameAndLocation() would still be able to access the firstName variable, and the same output would still be logged to the console.

Want more content like this? Subscribe to get the latest updates in your inbox

Share your Feedback

What did you like or didn't like about this post? Let me know what worked well and what can be improved. Your feedback is much appreciated!