JavaScript must know the Closure_javascript skills

Source: Internet
Author: User
Tags closure
The following code fragment indentation is currently not perfect, you can also choose to download PDF to read.

Contents

  • Summary
  • What is closure
  • Execution space (execution context, Execution contexts)
  • Some usages of closure
  • About the efficiency of closure
  • Application recommendations
  • Conclusion
  • Resources
  • The RST source of this article

What is closure

One definition is:

A "closure" is a expression (typically a function) which can have free variables together and an environment that binds T Hose variables (that "closes" expression).

My understanding is that closure is an expression (usually a function) that shares some of the free variables with an environment that binds those free variables (or the end this expression, which is also known as the origin of the name closure . The so-called environment is a larger block, and all the free variables are declared (meaningful) in this block. and binding means that the scope of these free variables is this environment.

Give a simple example.

  var flag  =  false ; The //debug Switch /env is both the so-called environment //And inner is the so-called expression, name is the so-called free variable  function env () // The entire env can be considered a closure { var name  =  Zhutao ;  function inner () { return name  +  ' is a student. ' ;}  return inner ; //Returns an intrinsic function} //closure End Flag  =  true ;  if (flag) {///Here is the most magical place where the code executes where the inner function has actually been out of the Env body, //and can still be referenced, which is called the formation of a closure  var inne R_func_ref  = env (); //This is where inner_func_ref refers to the inner () function Object Alert (Inner_func_ref ()); //Zhutao is a student.}   

In the above example, the function env is the so-called environment in the definition, the function inner is the so-called expression in the definition, and name is the so-called free variable , bound in the Env environment the end of the Env is also the end of closure.

In JavaScript, if the body of the external function in which the internal function is located is still able to be referenced, a so-called closure is formed.

We need to know some other knowledge before we know closure.

Execution space (execution context, Execution contexts)

In JavaScript, each executable code has a certain execution space , such as the global execution space, function space, recursive function execution space, etc. And a complete JavaScript execution process can be seen as having a stack of execution space , constantly changing the execution Space (out of stack, into the stack).

This is an important concept, and the understanding of this concept is also closely related to the understanding of this keyword in another article in this series that will be completed.

For detailed explanation please refer to the upcoming post of this keyword .

The execution space can be understood as a set of objects with attributes, but these properties are usually not accessible, and the set of objects provides a certain context (space) for the execution of the code.

When executing to a function, the execution space of this function is established (so-called stack), the execution is finished, the execution space exits back to the original execution space (the so-called out stack), while the JS interpreter maintains such an execution space stack together in the running process. To provide different execution space for different code.

So what does the execution space have to do with closure?

In short, certain execution space corresponds to a certain closure, only in the same closure method can access the same closure variable.

For a simple example:

The example about the context is 
 true"Zhutao"this.name    

Some usages of closure

When internal functions and free variables are in the same closure, they can be accessed at will, and the order of declarations is not important.

A few common examples:

Some applicationsFlag= True; functionOuterfun () {VarNum= 100; VarPrintnum= function() {alert (num);}The NUM referenced here is a reference, not a value, so the num is changed back, and Num here is also in effectNum++; ReturnPrintnum;}VarMyFunc=Outerfun (); MyFunc ();The output is 101, not 100. Another example, the following example, can see the anonymous function (intrinsic function) before the declaration of the external function variable, but still able to access the variables of the external function That is, internal functions are located in the same closure as variables of external functions, so you can access functionSameclosure () {VarIcanaccess= function() {alert (name); var name  =  "Zhutao" ;  return icanaccess ;  var testsameclosure  = Sameclosure (); Testsameclosure ();  Zhutao //Another application, about module pattern, which can be actually called private, public and other methods and variables  var module  = ( function module () { var privatevar  =  Zhutao is private ; //Private  return {Publicgetprivatevar :  function () { return privatevar ;} , //Public method, you can take the so-called private variable Publicvar :  "I ' m a public variable" //Public variable} ; })();  if (flag) {alert (Module.publicgetprivatevar ()); //Zhutao is Private alert (Module.publicvar); //I ' m a public variable alert (MODULE.PRIVATEVAR); //undefined}                

About the efficiency of closure

Because the actual application of closure can be used several times to generate an internal function (anonymous), there is a possible efficiency problem. (object creation, memory management release, etc.).

Therefore, you should minimize the generation of internal functions and use the reference of functions.

For example:

An example of efficiency is 
 falsefunction () {alert (= showmefunction showme () {alert  (  

Application recommendations

Don ' t use closures unless for you 
really need closure semantics 
. In most cases, nonnested 
functions are "right way" go. 
Eric Lippert, Microsoft 

The above discussion is based on efficiency considerations, while IE 4-6 may have problems with memory leaks when using closure, referencing the relevant parts of JavaScript Closures.

And on some occasions, you may have to use closure, such as looping problems .

Code:

Flag= True; Generate some links to the body, and then bind the events functionAddlink (num) {For(VarI= 0;I<Num;I++) {VarLink= Document. createelement ( ' a '); link.innerhtml  =  "Link"  + i ; Link.onclick  =  function () {alert (i);};  document.body.appendChild (link); //Unfortunately, when you click on each link, the output is link 4 ///Use closure to solve this problem  function addLink2 (num) { for ( var i
                               
                                =0; I 
                                 <num ; I  + +) { var link  =  document.createelement ( ' a '); link.innerhtml  =  "Link"  + i ; Link.onclick  =  function (j) {//Use closure  return  function () {alert (j);}; //Returns a function} (i); //Call this function  document.body.appendChild (link);}  window.onload  = Addlink ( 4);  window.onload  = AddLink2 ( 4);           
                                

Why does the above problem arise? (The fact that in a previous project, also encountered the same problem, but did not understand closure, but also confused)

This is because, for addlink, I have become 4 before exiting the Addlink function, so whatever event triggers later, the output is 4.

But the latter, using the closure. Makes J reference to I in the current loop, so for each subsequent trigger event, the corresponding result will be obtained as expected.

Concrete discussions are visible: so

This is a typical closure scenario, and if not used, this problem cannot be solved.

Conclusion

The following excerpt from Summary of JavaScript closures:

  1. When you use another function in one function, a closure is generated
  2. When you use Eval (), a closure is generated.
  3. It is best to assume that closure is always generated at the entrance of the function and that local variables are automatically added to the closure

Other details can refer to the link above.

In short, regarding closure, you must keep the following points in mind:

  1. Closure is to provide a mechanism for variable sharing (internal functions can access variables of external functions)
  2. Note the efficiency issues that closure may cite (how to avoid it, see detailed in the article)
  3. Specific application scenarios to be familiar with

The last blog is about prototype, the next post is expected to speak this keyword , welcome to discuss and leave a message.

Resources

  1. JavaScript Closures
  2. Explaining JavaScript Scope and Closures
  3. JavaScript Closures 101
  4. JavaScript and memory leaks
  5. Closures in JavaScript

The RST source of this article

The source code of this article is linked here.

The JavaScript code involved in this article can be downloaded here.

You can also choose to download PDF to read.

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.