WEB DEVELOPER SITE
HTMLCSSJAVASCRIPTSQLPHPBOOTSTRAPJQUERYANGULARXML
 

JavaScript Closures

JavaScript variables can be local or global.

Private variables can use closures.

Global Variables

Functions can access variables defined inside the function, such as:

Example

function myFunction() { var a = 4; return a * a; }
Try it Yourself »

Functions can also access variables defined outside the function, such as:

Example

var a = 4; function myFunction() { return a * a; }
Try it Yourself »

In the latter example, a is a global variable.

Global variables belong to window objects in web pages.

Global variables apply to all scripts on the page.

In the first instance, a is a partial variable.

Local variables can only be used inside functions that define it. Not available for other functions or script code.

Global and local variables are two different variables, even if they have the same name. Modifying one will not affect the value of the other.

If a variable is declared without the var keyword, it is a global variable, even if it is defined within a function.

Variable life cycle

The scope of global variables is global, that is, global variables are everywhere in the entire JavaScript program.

Variables declared inside a function only work inside the function. These variables are local variables and the scope is local; the parameters of the function are also local and only work inside the function.


Counter dilemma

Imagine if you want to count some values and the counter is available in all functions.

You can use global variables, the function sets the counter to increment:

Example

var counter = 0; function add () { return counter + = 1; } add (); add (); add (); //counter is now 3
Try it Yourself »

The counter value changes when the add () function is executed.

But here comes the problem. Any script on the page can change the counter, even without calling the add () function.

If I declare a counter inside a function, I cannot modify the value of the counter without calling the function:

Example

function add () { var counter = 0; return counter + = 1; } add (); add (); add (); //The original intention is to output 3, but everything goes against the expectation, and the output is 1!
Try it Yourself »

The above code will not be output correctly. Every time I call the add () function, the counter will be set to 1.

JavaScript inline functions solve this problem.


JavaScript inline functions

All functions have access to global variables。  

In fact, in JavaScript, all functions have access to the scope above them.

JavaScript supports nested functions. Nested functions can access function variables from the previous level.

In this example, the embedded function plus () can access the counter variable of the parent function:

Example

function add() { var counter = 0; function plus() {counter += 1;} plus(); return counter; }
Try it Yourself »

If we can access the plus () function externally, this will solve the dilemma of the counter.

We also need to make sure that counter = 0 is executed only once.

We need closures.


JavaScript Closures

Remember the function calls itself? What does this function do?

Example

var add = (function () { var counter = 0; return function () {return counter + = 1;} }) (); add (); add (); add (); //counter is 3
Try it Yourself »

Example Explained

variable add specifies the return word value of the function's self-invocation.

The self-calling function is executed only once. Set the counter to 0. And returns a function expression.

The add variable can be used as a function. The great part is that it has access to the scoped counters of the function.

This is called a JavaScript closure. It makes it possible for functions to have private variables.

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


Closures are a mechanism for protecting private variables. When the function is executed, a private scope is formed to protect private variables inside from external interference. Intuitively, it is to form a stack environment that is not destroyed.