Summary of JavaScript knowledge points (16): Javascript Closure (Closure) code details, javascriptclosure

Source: Internet
Author: User
Tags closure definition

Summary of JavaScript knowledge points (16): Javascript Closure (Closure) code details, javascriptclosure

Closure is a difficult and characteristic of Javascript language. Many advanced applications rely on closures for implementation. I have been familiar with the concept of closure for a long time, but I have been confused and cannot understand what the closure of JavaScript is and what is its use, today, I saw an article about JavaScript closures (the original article link) on the Internet, this is a thorough understanding of whether the closure of JavaScript is a magic horse and the purpose of the closure. I would like to share it with you here. I hope those who do not understand the closure of JavaScript can understand the closure after reading it! Most of the following content is from the original text. I add some code comments, operations, and some modifications to the original text for your convenience!

I. Scope of Variables

To understand closures, you must first understand the special variable scopes of Javascript.

In JavaScript, variables have two scopes: global variables and local variables.

In Javascript, global variables can be directly read within the function.

Var n =; // defines the global variable nfunction f () {alert ("access the global variable n, n =" + n) within the function ); // access the global variable n} f () inside the function ();//

Running result:


However, in turn, the local variables in the function cannot be read outside the function.

Function f () {var n =; // define the local variable n} alert ("access the local variable n, n =" + n) outside the function ); // access the local variable n outside the function. Error: n undefined

Running result:

 

Note that you must use the var command when declaring variables in a function. If not, a global variable is declared!

Function f () {n =;} f (); alert ("n is not declared using var in the f1 function. At this time, n is a global variable. \ r \ n proof: n = "+ n +", window. the result of n = n is: "+ (window. n = n ));

Running result:

 

2. How to read local variables from the outside?

For various reasons, we sometimes need to get local variables in the function. However, as we have already said, under normal circumstances, this cannot be done. It can only be implemented through a work und.

That is to define another function within the function.

Function f () {var n =; // The local variable n inside the f function // define an f function f () inside the f function () {// inside the f function is alert (n) that can access the local variable n );//}}

In the code above, function f2 is included in function f1. All local variables in function f1 are visible to f2. But in turn, the local variables in f2 are invisible to f1. This is the unique "chain scope" structure (chain scope) of Javascript language. The sub-object will first look up the variables of all parent objects. Therefore, all variables of the parent object are visible to the child object, and vice versa. Since f2 can read local variables in f1, As long as f2 is taken as the return value, we can't read its internal variables outside f1! Some people may have doubts that f2 is a function. How can it be returned as the return value of the f1 function? In fact, it is OK. The function name in JavaScript itself is a variable, therefore, functions can also be used as common variables. That is to say, a function can be passed to another function just like a parameter, and a function can be returned as the return value of another function.

Function f () {var n =; // local variable n // f function f () {alert (n);} return f; // use the f function as the return value of the f function} var result = f (); // the return value after the f function is called, and the result is the result () of the f function (); // 999, call the f2 Function

Running result:

 

Iii. Concepts of closures

The f2 function in the previous code is the closure. Closure definitions in various professional documents are very abstract. For example, there is a closure definition: "The JavaScript closure stores a copy of the variable from the upper-level function or scope in another scope, and these variables will not be destroyed as the upper-level function is executed ", I can hardly understand such a closure definition. In my understanding, closures are functions that can read internal variables of other functions. In Javascript, only the subfunctions in a function can read local variables. Therefore, you can simply understand the closure as a function defined in a function ". Therefore, in essence, closure is a bridge connecting the internal and external functions of a function.

Iv. Use of closures

Closures can be used in many places. It has two major functions: one is to read the internal variables of the function mentioned above, and the other is to keep the values of these variables in the memory.

How can we understand this sentence? See the following code.

Function f () {var n =; // nAdd is a global variable that is not declared using var, this variable now points to an anonymous function declared inside the f function, nAdd = function () {n + =} function f () {alert (n) ;}return f ;} var result = f (); // result is the result () of the f function; // The result function nAdd () is called for the first time (); // nAdd indicates an anonymous function declared inside the f function, and nAdd () indicates calling the anonymous function result (); // The second call to the result function 1000

Running result:

 

In this Code, the result is actually the f2 function of the closure. It runs twice in total. The first value is 999, and the second value is 1000. This proves that the local variable n in function f1 has been stored in the memory and is not automatically cleared after f1 is called.

Why? The reason is that f1 is the parent function of f2, and f2 is assigned a global variable, which causes f2 to always be in the memory, while f2 depends on f1, therefore, f1 is always in the memory and will not be recycled by the garbage collection mechanism after the call is completed.

Another noteworthy part of this code is "nAdd = function () {n + = 1}". The var keyword is not used before nAdd, therefore, nAdd is a global variable rather than a local variable. Secondly, the value of nAdd is an anonymous function, and this anonymous function itself is also a closure, so nAdd is equivalent to a setter, you can operate the local variables inside the function outside the function.

5. Notes on using closures

1) because the closure will make the variables in the function be stored in the memory, the memory consumption is very large, so the closure cannot be abused, otherwise it will cause the performance of the web page, memory leakage may occur in IE. The solution is to delete all unused local variables before exiting the function.

2) The closure changes the value of the internal variable of the parent function outside the parent function. Therefore, if you use the parent function as an object, use the closure as its Public Method, and use internal variables as its private value ), be sure not to change the value of the internal variable of the parent function.

Vi. Questions

If you can understand the running results of the following two sections of code, you should understand the operating mechanism of the closure.

Code snippet 1:

var name = "The Window";  var object = {    name : "My Object",    getNameFunc : function(){      return function(){        return this.name;      };    }  };  alert(object.getNameFunc()()); 

Running result:

 

Code snippet 2:

var name = "The Window";  var object = {    name : "My Object",    getNameFunc : function(){      var that = this;      return function(){        return that.name;      };    }  };  alert(object.getNameFunc()()); 

Running result:

 

The following code is annotated to analyze the running results of the above two code snippets:

Code snippet 1:

The analysis is as follows:

/* In JavaScript, the declared JavaScript global object, global function, and global variable automatically become a member of the window object. The global variable is the property of the window object. Global functions are the methods of window objects. */Var name = "The Window"; // declare a global variable name. In this case, The global variable name automatically becomes an attribute of The window object. // proof: alert ("window. name: "+ window. name); // window can be used. name (Object name. attribute name) to access the name, it proves that the global variable name automatically becomes an attribute of the window object // declare the Global object, in this case, the global variable object automatically becomes a property of the window object var Object = {name: "My object", // The property name of the object getNameFunc: function () {// The getNameFunc function of the object // the return value of the getNameFunc method of the object is an anonymous function return function () {// which object is this? It refers to the window object, which object calls the function where this is located, and which object this refers. // Prove that this in the anonymous function represents the window object rather than objectalert ("this = object Result:" + (this = object )); alert ("this = window:" + (this = window); return this. name; // since this represents the window object, this. name is The name of The window object, which is "The Window" };}; // It indicates that The global object is an attribute of The window object. alert ("window. object: "+ window. object); alert ("window. object. name: "+ window. object. name);/* after the getNameFunc method is called, an anonymous method is returned. In this case, retFn indicates an anonymous method. Now, it is equivalent to a retFn function named retFn. Automatically becomes a function of the window object */var retFn = object. getNameFunc (); alert (retFn (); // call the returned anonymous method. Who is calling this anonymous method? Is a window object // proof: The retFn function is a function of the window object alert ("window. retFn (): "+ window. retFn (); // use window. retFn () (Object Name. method) to call the retFn method, it proves that the retFn function is a function of the window object.

Code snippet 2:

The analysis is as follows:

Var name = "The Window"; // global variable name // Global object objectvar Object = {name: "My object", getNameFunc: function () {/* which object does this represent? this indicates the object and which object calls the function of this, this refers to the object after that = this is executed. At this time, that also represents the object */var that = this; // that is a local variable declared in the getNameFunc function // It proves that this in the getNameFunc function represents the object rather than the jsonwalert ("this = object result: "+ (this = object); alert (" this = window the result is: "+ (this = window); // prove that represents obje The result of the ct object alert ("that = object is:" + (that = object); return function () {/* that is a local variable declared in the getNameFunc function. Normally, after the getNameFunc function is called, the local variable will be recycled by the JavaScript GC, release the memory space occupied by the local variable, but now that can be used normally and has not been recycled, because getNameFunc is the parent function of this anonymous function, after the getNameFunc function is called, the anonymous function is returned and assigned a global variable retFn, which causes the anonymous function to remain in the memory, the existence of anonymous functions depends on the getNameFunc function. Therefore, the getNameFunc function is always in the memory and will not be recycled by the garbage collection mechanism after the call is complete. Since the getNameFunc function is always in the memory, the local variable declared in the getNameFunc function also exists in the memory. If yes, you can continue to use it. */Return that. name; // that indicates the object, so that. the access by name is naturally the object name "My Object" };}}; var retFn = object. getNameFunc (); // After the getNameFunc method is called, an anonymous method is returned. In this case, retFn indicates an anonymous method, now it is equivalent to providing an anonymous method named retFn alert (retFn ());

I also attached an example I wrote when learning JavaScript closures:

<Script type = "text/javascript"> function A () {var I =; // declare the local variable I in function A // declare the subfunction bfunction B in function () {alert ("I =" + (++ I); // access the local variable I} return B that is declared inside function A in subfunction B; // return the address of the function B}/* after var c = A () is executed, variable c actually points to function B, and variable I is used in B, after executing c (), a window will pop up showing the I value (for the first time). This Code actually creates a closure, because variable c outside function a references function B inside function a, that is, when function B inside function a is referenced by a variable outside function, a so-called "closure" closure is created to prevent GC from revoking the resources occupied by a after a executes and returns the result, because the execution of the internal function B of a depends on the variable */a () in A; // at this time, there must be space for I in the memory. After A () is executed, GC will reclaim the memory space allocated for I var c = A (); // This usage, GC will not treat I as garbage disposal c (); // call B () and the result is: I = c (); // The result is: I = </script>

Running result:

The above content is a summary of the JavaScript knowledge point (16), the Javascript Closure (Closure) code details, I hope to help you!

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.