A tutorial on deep understanding of JavaScript closures

Source: Internet
Author: User

1, what's the closure?

(Baidu Encyclopedia definition)--closures are blocks of code that can contain free (unbound to specific) variables that are not defined within the code block or in any global context, but are defined in the environment where the code block is defined (local variables). The term "closure" comes from the combination of the code blocks to be executed (because the free variables are contained in the code block, these free variables and the objects they refer to are not freed), and the Computing environment (scope) that provides the binding for the free variable.

ECMAScript in the closure interpretation, there is a saying: a closure is a function of a lexical representation that includes a variable that is not evaluated, that is, a function can use a variable defined outside the function as a closure.

To understand closures, in the return of JavaScript kings, a syntax domain and an execution domain were proposed to help us understand closures.

Syntax field: The area at which a program's paragraph is defined. Execution domain: The area that is affected by the actual invocation of a program's paragraph ()

My understanding here is that grammatical fields, such as the scope of a variable in a function, are within a function and cannot be accessed outside the function. Execution domain: Through a number of expressions of change, access to the scope of the extraterritorial content, or the role of the extraterritorial access.

Closure: a paragraph in which a grammar field is located in a particular region, with a persistent reference (read and write) to a Non-persistent variable value capability on an execution field that is outside its own scope. The non-persistent variables of these external execution domains magically retain their values when the closure was originally defined (or created).

Summarize the definition of closure: it is a paragraph that has access to an external execution field, in JavaScript, by defining functions within the function to implement the

Closures are functions that have access to variables in the scope of another function, and the common way to create closures is to create another function inside one function.

Warning: Don't be confused about closures and anonymous functions, which is a function with no name, and closures are variables defined outside of the access function. If the anonymous function can access a variable defined outside the function, it is a closure.

The above summary is written one weeks ago, today looked at, and there are new gains. Before you go to the interview, you will ask a question: what is a closure, now you know why people ask you to understand the closure, because to fully understand the closure, need to understand the scope chain, the implementation of the environment, so that you can in the use of ease.

2, the implementation of the Environment

Because closures are also a function, to understand closures, you need to understand what happens when a function is first invoked. Here's a look at the execution environment for JavaScript, which is the domain of execution mentioned above

The execution environment defines other data that a variable or function has access to, determining their respective behavior. Each execution environment has a variable object associated with it, and all variables and functions defined in the environment are stored in this object, although the code we write cannot access the object, but the parser uses it in the background when it processes the data.



The global execution environment is one of the outermost execution environments
In the browser, the global execution environment is considered a Window object, so all global variables and functions are created as properties and methods of the Window object
The environment is destroyed after all code in an execution environment has finished executing. The variables and function definitions that are saved are also destroyed (the global execution environment will not be destroyed until the application exits-for example, when a Web page or browser is closed)

For example: Just as we have stayed on Earth, and the earth is like our grammatical domain, and our execution domain is like God six launched to the moon, Yang Liwei can walk on the moon, where the Earth and the moon space is what we call the implementation of the domain, in the absence of the launch of God Six o'clock, Yang Liwei can only be on earth, just like our function, When it is not executed, it is surrounded by the two symbols of {}, when God six to the Moon, Yang Liwei can move around the moon, as the function runs, it may refer to the variables outside it, this is what we call the implementation of the environment, I personally understand that in the execution of the moment, it contains the variable object.

The implementation of the environment, so the name incredible, in the implementation of the process, after the execution of this disappeared, so you are not accessible to Shinliu last month, as soon as the return to the Earth, you have no access to the moon's execution environment

Each function has its own execution environment, and when the execution flow enters a function, the environment of the function is pushed into an environment stack. After the function is finished, the stack will eject its environment and return control to the previous execution environment, the execution flow in the ECMAScript program is controlled by this mechanism.

My understanding of the above sentence is that when the function completes, it then starts executing the variable object containing it, so that it executes until the global environment.

In JavaScript, divided into global and local (function) scope, where the local refers to the function, here, we have to mention the variable declaration, using var in the function declared variable as a local variable, if the var declaration variable is not used within the function, will default to the global variable.

var a = 1;

function A () {
alert (a);
}
A ();

A simple closure, you may wonder, so simple a function is also a closure? Yes, as long as the variables defined outside the function are closures.

In the simplest case, in the above code, the scope chain of a () contains two objects, its own variable object (which defines the arguments object), and the variable object of the global environment, which can be accessed within the function by accessing the variable A, because it can be found in the scope chain.
So how does it search, first it starts from the front end of the scope chain (that is, the variable object in the environment where the code is currently executing), in the A () function, the A function is not found, and then to its containing environment (the Global Execution environment variable object) to find, found that there is a variable, stop the search.

Variable queries are not without cost, and it is clear that accessing local variables is faster than accessing global variables because you do not have to search up the scope chain.

Let's look at a complex example:

var global = "global";

function A () {
var a = "a";

function B () {
var B = "B";

Alert (Global + "," + a);
}
B ();
}
A ();


This picture, probably can see what meaning, refer to the above simple code, if there is anything do not understand, wish to leave a message, I will add.

3, scope chain

When code executes in an environment, a scope chain of variable objects is created. The purpose of the scope chain is to ensure an orderly access to all variables and functions that are authorized to access the execution environment. The front end of the scope chain is always the variable object of the environment in which the currently executing code is located.
If the environment is a function, its active object is treated as a variable object, and the active object contains only one variable at the beginning, that is, the arguments object (this object does not exist in the global environment).

The next variable object in the scope chain comes from the containing (external) environment, and the next variable object comes from the next containing environment, so that it continues to the global variable, and the variable object of the global execution environment is always the last object in the scope chain.

Identifier resolution is the process of searching for identifiers along the scope chain, which always starts at the front end of the scope chain, and then goes back backwards until the identifier is found (if an identifier is not found, it usually results in an error).

With vernacular, when a function in a program executes, it creates a chain of scopes that you can use as a search scope, and there is a scope chain front-end, what does this mean? My understanding is that the current function, such as the front end of the scope chain in the above code is the B function, and then the next variable object a function, and then the global.

Extend the scope chain (this knowledge is on the line, if you need to know more, find yourself)

Other ways to extend the scope chain, because some statements can temporarily add a variable object to the front end of the scope chain, which is removed after the code executes,

So how does a function get released? Take a look at garbage collection (for more information please find it yourself, this understanding on the line)

The normal declaration period of a local variable in an analysis function, local variables exist only in the execution of a function, in which the local variables are allocated space on memory to store them, and then use these variables in the function until the function is finished, where there is no need for local variables to exist. So they can release their memory for future use.

4, the use of closures

Learn the implementation of the environment, scope chain, closure concept, you do not know how to use it? (Copy down the code below and do it yourself)

<! DOCTYPE html>
<meta charset= "Utf-8"/>
<title> Closure Demo </title>
<style type= "Text/css" >
p {background:green;}
</style>
<script type= "Text/javascript" >
function init () {
var pary = document.getElementsByTagName ("P");
for (var i=0; i<pary.length; i++) {
Pary[i].onclick = function () {//click event OH
alert (i);
}
}
}
</script>
<body onload= "Init ();" >
<p> Products 0</p>
<p> Products 1</p>
<p> Products 2</p>
<p> Products 3</p>
<p> Products 4</p>
</body>

In the above code execution, you will find that each pop-up is 4, is not the same as you imagine, this is why?

Because of the onclick function expression, the closure is used (using the variable I outside the function), depending on the scope chain in the execution environment, because the active object of the Init function is kept in the scope of each function, they refer to the same variable I, and when the Init function returns, the value of the variable i is 4, At this point each function references the same variable object that holds the variable i, so the value of I within each function is 4

Simply put: This variable is always accessible to the global scope of I

Workaround: Do not let it always access the global scope I, let it pass a parameter to it when calling an anonymous function, because the function is passed by value (the object is also passed by value), so the value of the variable i is assigned to the parameter _i because it is passed by value, so you know.


<! DOCTYPE html>
<meta charset= "Utf-8"/>
<title> Closure Demo </title>
<style type= "Text/css" >
p {background:green;}
</style>
<script type= "Text/javascript" >
function init () {
var pary = document.getElementsByTagName ("P");
for (var i=0; i<pary.length; i++) {
(function (_i) {
Pary[_i].onclick = function () {
alert (_i);
}
}) (i);

}
}
</script>
<body onload= "Init ();" >
<p> Products 0</p>
<p> Products 1</p>
<p> Products 2</p>
<p> Products 3</p>
<p> Products 4</p>
</body>


The above method, which I think is best understood, is for passing by value, the scope chain

<! DOCTYPE html>
<meta charset= "Utf-8"/>
<title> Closure Demo </title>
<style type= "Text/css" >
p {background:green;}
</style>
<script type= "Text/javascript" >
function init () {
var pary = document.getElementsByTagName ("P");
for (var i=0; i<pary.length; i++) {
Pary[i].onclick = function (_i) {
return function () {
alert (_i);
}
} (i);
}
}
</script>
<body onload= "Init ();" >
<p> Products 0</p>
<p> Products 1</p>
<p> Products 2</p>
<p> Products 3</p>
<p> Products 4</p>
</body>


The above method is other people's, in short, the understanding, the next encounter can quickly solve

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.