Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
JavaScript Closures
Coding FoundationsFrontEnd Development

JavaScript Closures

A Closer Look at JavaScript Closures

Oleh Subotin

by Oleh Subotin

Full Stack Developer

Feb, 2024
11 min read

facebooklinkedintwitter
copy
JavaScript Closures

Introduction

Closures are one of the most powerful and important features of JavaScript. They allow us to create functions that can access and manipulate variables from an outer scope, even after that scope is gone. In this article, we will explore what closures are, how they work, and why they matter.

What are closures?

A closure is a function that remembers the environment in which it was created. This means that it can access and modify variables that are defined outside of its own scope, as long as those variables are still in memory.

For example, consider the following code:

In this code, we have a function makeCounter that returns another function. The returned function is a closure, because it can access and update the variable count that is defined in the outer scope of makeCounter. Even though makeCounter has finished executing and its local scope is gone, the closure still has a reference to count and can use it.

We can see that every time we call the closure, it increments and returns the value of count. This means that the closure has its own private state that persists across multiple invocations.

Run Code from Your Browser - No Installation Required

Run Code from Your Browser - No Installation Required

How do closures work?

To understand how closures work, we need to understand how JavaScript handles scopes and variables.

JavaScript has two types of scopes: global and local. A global scope is the outermost scope that contains variables that are accessible from anywhere in the code. A local scope is a scope that is created by a function or a block, and contains variables that are only accessible within that function or block.

Variables in JavaScript are stored in objects called lexical environments. A lexical environment is a mapping of names to values, along with a reference to the outer lexical environment. The global scope has a global lexical environment, and every function or block has its own local lexical environment.

When a function is created, it also creates a closure. A closure is a combination of the function and its lexical environment. The closure has a reference to the lexical environment in which it was created, and can access and modify the variables in that environment.

When a function is invoked, it creates a new execution context. An execution context is a stack of information that is used to execute the function. The execution context contains a reference to the closure of the function, and a new local lexical environment for the function’s parameters and local variables.

The execution context also has a mechanism called scope chain. A scope chain is a list of lexical environments that are used to resolve variable names. The scope chain starts with the local lexical environment of the function, and then follows the references to the outer lexical environments until it reaches the global lexical environment.

When a variable name is used in a function, the JavaScript engine looks for the value of that name in the scope chain. It starts from the local lexical environment, and if it finds the name, it returns the value. If it doesn’t find the name, it moves to the next lexical environment in the scope chain, and repeats the process. If it reaches the end of the scope chain and still doesn’t find the name, it throws a reference error.

This is how closures can access and modify variables from an outer scope. The closure has a reference to the lexical environment in which it was created, and that lexical environment is part of the scope chain of the closure. Therefore, the closure can look for the variable name in its own lexical environment, or in any of the outer lexical environments that are still in memory.

Why do closures matter?

Closures are useful for many reasons. They allow us to create functions that have private state, that can access and modify variables from an outer scope, and that can retain their behavior even after the outer scope is gone. Some of the common use cases of closures are:

Creating private variables

Closures can create variables that are hidden from the outside world, and can only be accessed and modified by the closure itself. This can prevent unwanted interference or leakage of data. For example, we can use a closure to create a counter function that has a private variable count, and expose only the methods to increment and get the value of the counter.

Partial application

Closures can create functions that have some of the arguments pre-filled, and return a new function that takes the remaining arguments. This can simplify the code and make it more reusable. For example, we can use a closure to create a function that adds a fixed number to any given number.

Memoization

Closures can create functions that cache the results of previous computations, and return the cached value if the same input is given again. This can improve the performance and efficiency of the function. For example, we can use a closure to create a function that calculates the factorial of a number, and store the results in a private object.

Conclusion

Closures are a powerful feature of JavaScript that allow us to create functions that can access and manipulate variables from an outer scope, even after that scope is gone. Closures are useful for creating private variables, partial applications, memoization, and many other scenarios. Closures are an essential part of the JavaScript language, and understanding how they work and why they matter can help us write better and more elegant code.

Start Learning Coding today and boost your Career Potential

Start Learning Coding today and boost your Career Potential

FAQs

Q: What is a closure in JavaScript?
A: A closure is a function that remembers the environment in which it was created. It can access and modify variables that are defined outside of its own scope, as long as those variables are still in memory.

Q: How do you create a closure in JavaScript?
A: You create a closure by returning a function from another function. The returned function is a closure that has a reference to the outer function’s lexical environment.

Q: What are some benefits of using closures in JavaScript?
A: Some benefits of using closures are:

  • They can create functions that have private state, such as counters, timers, or caches.
  • They can implement partial application, currying, or memoization techniques, which can improve performance and readability of code.
  • They can emulate object-oriented features, such as encapsulation, inheritance, or polymorphism, by using closures as constructors, prototypes, or methods.

Q: What are some drawbacks of using closures in JavaScript?
A: Some drawbacks of using closures are:

  • They can create memory leaks, if they hold references to variables that are no longer needed or used.
  • They can cause performance issues, if they create too many nested scopes or closures that are invoked frequently.
  • They can make debugging harder, if they obscure the source of errors or the value of variables.

Was this article helpful?

Share:

facebooklinkedintwitter
copy

Was this article helpful?

Share:

facebooklinkedintwitter
copy

Content of this article

We're sorry to hear that something went wrong. What happened?
some-alt