JavaScript Closure

JavaScript variables belong tolocallocalGlobalor

scopes.ClosureGlobal variables can be accessed through

can implement local (private).

Global variablesFunctions can access functionsInternal

Example

function myFunction() {
    var a = 4;
    return a * a;
} 

Try It Yourself

But functions can also access variables defined by functionsExternalDefined variables, such as:

Example

var a = 4;
function myFunction() {
    return a * a;
} 

Try It Yourself

In the last example,a isGlobalVariables.

In a web page, global variables belong to the window object.

Global variables can be used and modified by all scripts on the page (and in the window).

In the first example,a isLocalVariables.

Local variables can only be used within the function they are defined in. They are invisible to other functions and script code.

having global variables and local variables with the same name are different variables. Modifying one does not change the other.

withoutkeyword var Variables created are always global, even if they are created in a function.

Variable lifecycle

Global variables live as long as your application (window, web page).

Local variables do not live long. They are created when a function is called and deleted when the function is completed.

A counter's dilemma

Suppose you want to use a variable to count, and you want this counter to be available to all functions.

You can use global variables and functions to increment the counter:

Example

// Initialize the counter
var counter = 0;
// Function to increment the counter
function add() {
  counter += 1;
}
// Call add() three times
add();
add();
add();
// At this point, the counter should be 3

Try It Yourself

The above solution has a problem: any code on the page can change the counter without calling add().

For the add() function, the counter should be local to prevent other code from changing it:

Example

// Initialize the counter
var counter = 0;
// Function to increment the counter
function add() {
  var counter = 0; 
  counter += 1;
}
// Call add() three times
add();
add();
add();
// At this point, the counter should be 3. But it is 0.

Try It Yourself

It is not useful because we display the global counter instead of the local counter.

By making the function return it, we can remove the global counter and access the local counter:

Example

// Function to increment the counter
function add() {
  var counter = 0; 
  counter += 1;
  return counter;
}
// Call add() three times
add();
add();
add();
// At this point, the counter should be 3. But it is 1.

Try It Yourself

It is not useful because we reset the local counter every time we call the function.

JavaScript internal functions can solve this problem.

JavaScript nested functions

All functions have the right to access the global scope.

In fact, in JavaScript, all functions have the right to access their 'upper' scopes.

JavaScript supports nested functions. Nested functions can access their outer scopes.

In this example, the internal function plus() can access the parent function's counter Counter variable:

Example

function add() {
    var counter = 0;
    function plus() {counter += 1;}
    plus();     
    return counter; 
}

Try It Yourself

This can solve the counter dilemma if we can access it from the outside plus() function.

We also need to find a function that runs only once counter = 0 method.

We need a closure (closure).

JavaScript Closure

Remember the self-invoking function? What does this function do?

Example

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();
add();
add();
add();
// Counter is currently 3 

Try It Yourself

Example Explanation

variable add The assignment is the return value of the self-invoking function.

This self-invoking function runs only once. It sets the counter to zero (0) and returns the function expression.

So add becomes a function. The most "exciting" part is that it can access the counter in the parent scope.

This is called JavaScript Closure. It makes the function have a "PrivateVariables become possible.

The counter is protected by the scope of this anonymous function and can only be modified using the add function.

A closure is a function that has access to the parent scope, even after the parent function has closed.