How JavaScript Closures Work

In this short tutorial, we are going to explain how JavaScript closures work.

In general, a closure is a unique link between a function and its Outer Lexical Environment.

A closure can be considered a way of supporting first-class functions. It’s an expression, capable of referencing variables within its scope.

Here is an example of a closure:

function sayWelcome(siteName) {
  let message = 'Welcome to ' + siteName; // Local variable
  let welcome = function () {
    console.log(message);
  }
  return welcome;
}
let welcome1 = sayWelcome('W3Docs');
welcome1(); // logs "Welcome to W3Docs"

The code, mentioned above returns a reference to a function.

It has a closure as the anonymous function() { console.log(text); } is declared within another function.

So, in JavaScript, whenever you use the function keyword, you create a closure.

If you declare a function inside another one, then the outer function’s local variables remain accessible after returning from it. It is shown above because the function welcome1() is called after the return from sayWelcome().

The code that was called references the variable message that was a local variable of the sayWelcome() function:

function sayWelcome() {
  console.log(message);
} // Output of welcome1.toString();

If you look at the output of welcome1.toString(), you will see that the code refers to the variable message.

The next example demonstrates that the local variables are not copied but kept by reference:

function incrementFunc() {
  // Local variable that ends up within closure 
  let num = 5;
  let say = function () {
    console.log(num);
  }
  num++;
  return say;
}
let sayNumber = incrementFunc();
sayNumber(); // logs 6

The next example shows that the JavaScript closure includes any local variables declared within the outer function before its existence.

Please, take into account that the variable account may be declared after the anonymous function as account is in the same scope. Moreover, sayWelcome()() may directly call the function reference returned from sayWelcome():

function sayWelcome() {
  let welcome = function () {
    console.log(account);
  }
  // Local variable that ends up within closure 
  let account = 'Welcome to your account, Ann';
  return welcome;
}
sayWelcome()(); // logs "Welcome to your account, Ann"

In the final example, we demonstrate how each call to the main function creates a separate closure:

function newClosure(someNumber, someReference) { // Local variables that end up within closure
  let num = someNumber;
  let array = [1, 2, 3];
  let ref = someReference;
  return function (x) {
    num += x;
    array.push(num);
    console.log('number: ' + num + '; array: ' + array.toString() + '; ref.someVar: ' + ref.someVar + ';');
  }
}
obj = {
  someVar: 4
};
func1 = newClosure(4, obj);
func2 = newClosure(5, obj); // attention here: new closure assigned to a new variable!
func1(1); // number: 5; array: 1,2,3,5; ref.someVar: 4; 
func2(1); // number: 6; array: 1,2,3,6; ref.someVar: 4; 
obj.someVar++;
func1(2); // number: 7; array: 1,2,3,5,7; ref.someVar: 5; 
func2(2); // number: 8; array: 1,2,3,6,8; ref.someVar: 5;

So, it can be assumed that whenever you apply function within another function, a closure is used. There is another option, as well. Anytime applying eval() inside a function, a closure is used. The text that you eval may reference local variables of the function. Inside eval you can create new local variables using eval ('var foo = …').

In JavaScript, a closure is like keeping a copy of all the local variables as they were at the time of the function existence.

It is best to think that a closure is always made as an entry to a function, and the local variables are added to the closure.

Describing JavaScript Variables

In JavaScript, a variable is the name of the storage location. It can be used for storing goodies, visitors, or other data.

You can create variables using keywords such as ‘var’, ‘let’, and ‘const’.

There exist two types of JavaScript variables: local and global.

The local variables are declared inside a function, or a block is accessible only within the function or block.

On the contrary, the global variables can be accessible from any function. They can be declared out of the function or with window objects.


Do you find this helpful?

Related articles