Cover image for Closures in JavaScript can...

Closures in JavaScript can...

brandonleboeuf profile image Brandon LeBoeuf ・2 min read

An attempt to understand Closures in JavaScript

I gain more understanding of a topic when I get to talk/write about it... much to my wife's horror as she has zero interest in JavaScript (though she is kind and will still listen)!

In processing my current understanding of closures, I hope that you find it helpful as well!

Global Scope

When variables are declared in the global scope, they are accessible by any part of your application.

let val = 0;  
val += 1;

console.log(val); // 1

This data is exposed throughout the application...

You can isolate, or protect, the data from the rest of your application by using closures...

function() {
  let val = 0;

val += 1;

console.log(val); // ReferenceError: val is not defined

val +=1 no longer has access to change val.

Execution Context

Within a function, a new execution context is initialized in which variables can be created, mutated, reassigned, and/or read. Unless something gets returned out of that function, it exists in that functions execution context and in that context alone. 

After completion, everything that was created within the execution context is gone, and the only thing that remains is that which was returned.

Clousers allow you to isolate and protect data so that it can only be accessed by certain parts of your application, keeping that data isolated.


Here, nothing can change the data inside of assignValue due to closures, {}.

function assignValue() {
  let val = 0;
  return val += 1;

let newVal = assignValue();

console.log(newVal);  // 1

newVal is assigned the result of calling the function assignValue.

Once that execution context is completed, the only thing that remains from the function is that which was returned. Everything inside the execution context is gone, and only what was returned gets stored in newVal.

The data inside assignValue remains isolated from the rest of our applications.

val +=1 would still throw a ReferenceError

Maintain State

What if we want part of our application to be able to interact with that data?

Instead of just incrementing a number and returning it, we will create a new function inside the execution context (which still accomplishes the same task as before) but then returns that new function instead.

function assignValue() { 
 let val = 0;
 function addOne() {
   return val += 1; 

 return addOne;

const newVal = assignValue();

console.log(newVal()); // 1
console.log(newVal()); // 2
console.log(newVal()); // 3

Since the function addOne had access to the variables within the original execution context, we can still increment val, even though the initial execution context of assignValue is now gone.

We are able to maintain state, while still isolation the values inside assignValue from the rest of our application.

Final Thoughts

Closures can allow you to prevent other parts of your application from being able to interact with data.

You can use Closures to isolate state from the rest of your application.


Editor guide