JavaScript learning Summary (16) -- Javascript Closure (Closure)

Source: Internet
Author: User
Tags closure definition

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! 1. To understand the scope of variables, you must first understand the special scope of variables in Javascript. In JavaScript, variables have two scopes: global variables and local variables. In Javascript, global variables can be directly read within the function. 1 var n = 999; // defines the global variable n2 function f1 () {3 alert ("access the global variable n, n =" + n) within the function ); // access the global variable n4} 5 f1 () within the function; // 999 run the result: But in turn, the global variable n4} 5 f1 () cannot be read outside the function. 1 function f1 () {2 var n = 999; // define the local variable n3} 4 alert in the f1 function ("access the local variable n outside the function, n = "+ n); // access the local variable n outside the function. Error: n undefined running result: note that when the variable is declared inside the function, be sure to use the var command. If not, a global variable is declared! 1 function f1 () {2 n = 999; 3} 4 f1 (); 5 alert ("n is not declared using var in the f1 function. n is a global variable, \ r \ n proof: n = "+ n +", window. the result of n = n is: "+ (window. n = n); running result: 2. How do I 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. Copy code 1 function f1 () {2 var n = 999; // The local variable n3 in the f1 function // define an f2 function 4 function f2 () in the f1 function () {5 // within the f2 function is the 6 alert (n) that can access the local variable n; // 9997} 8} copy the code above, function f2 is included in function f1. All local variables in 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. Copy code 1 function f1 () {2 var n = 999; // local variable n 3 // f2 function 4 function f2 () declared inside the f1 function () {5 alert (n); 6} 7 8 return f2; // use the f2 function as the return value of the f1 function 9} 10 var result = f1 (); // After f1 is called, the return value is an f2 function. At this time, the result is the result of f2 function 11 (); // 999. Call the f2 function to copy the code execution result: 3. The concept of closure the f2 function in the previous Code section 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. 4. The purpose of the closure 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. Copy code 1 function f1 () {2 var n = 999; 3 // nAdd is a global variable that is not declared using var, this variable now points to an anonymous function 4 nAdd = function () {n + = 1} 5 function f2 () {6 alert (n) declared inside the f1 function ); 7} 8 return f2; 9} 10 11 var result = f1 (); // result is the f2 function 12 result (); // call the result function 99913 nAdd () for the first time (); // nAdd represents an anonymous function declared inside the f1 function, and nAdd () is calling the anonymous function 14 result (); // The second call to result function 1000 copies the code running result: in this Code, result is actually the closure of the f2 function. 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. Note: 1) because the closure will make the variables in the function be saved in the memory, the memory consumption is very high, so the closure cannot be abused, otherwise, it may cause webpage performance problems and may cause memory leakage 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. 6. 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: Copy code 1 var name = "The Window"; 2 var object = {3 name: "My Object", 4 getNameFunc: function () {5 return function () {6 return this. name; 7}; 8} 9}; 10 alert (object. getNameFunc (); copy The code execution result: code snippet 2: Copy code 1 var name = "The Window"; 2 var object = {3 name: "My Object ", 4 getNameFunc: function () {5 var that = this; 6 return function () {7 return that. name; 8}; 9} 10}; 11 alert (object. ge TNameFunc (); copy the code running result: add a comment to the code below to analyze the running results of the above two code snippets: code snippet 1: analysis is as follows: copy code 1/* 2 in JavaScript, the declared JavaScript global object, global function, and global variable are automatically members of the window object. 3. The global variable is the property of the window object. 4. Global functions are the methods of window objects. 5 */6 var name = "The Window"; // declare a global variable name. In this case, The global variable name automatically becomes an attribute of The window object. 7 // proof: 8 alert ("window. name: "+ window. name); // window can be used. name (Object name. the global variable name automatically becomes an attribute of the window object 9 // declare the global object, in this case, the global variable object automatically becomes a 10 var object = {11 name: "My Object" attribute of the window object, // The name12 getNameFunc: function () attribute of the object () {// The getNameFunc function of the object 13 // the return value of the getNameFunc method of the object is an anonymous function 14 return f Unction () {15 // at this time, this indicates which object is used, refers to the window object, which object calls the function of this, and this refers to which object. 16 // prove that this in the anonymous function represents the window object rather than object17 alert ("this = object Result:" + (this = object )); 18 alert ("this = window:" + (this = window); 19 return this. name; // since this represents the window object, this. name is The name of The window object "The Window" 20}; 21} 22}; 23 // proof: the global object is an attribute of the window object. object: "+ window. object); 25 alert ("window. object. name: "+ window. object. name); 26/* 27 after the getNameFunc method is called, an anonymous method is returned. 28 at this time, retFn indicates anonymity. Method. Now it is equivalent to giving the anonymous method a name called retFn. 29 at this time, the retFn function automatically becomes a function of window object 30 */31 var retFn = object. getNameFunc (); 32 alert (retFn (); // call the returned anonymous method. Who is calling this anonymous method? Is the window object 33 // proof: The retFn function is a function of the window object 34 alert ("window. retFn (): "+ window. retFn (); // use window. retFn () (Object Name. method Name) to call the retFn method, it is proved that the retFn function is a function of the window object to copy code Segment 2: Analysis: copy code 1 var name = "The Window"; // global variable name 2 // Global object 3 var Object = {4 name: "My object", 5 6 getNameFunc: function () {7/* 8 which object does this represent? this indicates the object and which object calls the function of this, this indicates which object 9 is executed after that = this. At this time, that also indicates object 1. 0 */11 var that = this; // that is a local variable 12 declared in the getNameFunc function // It proves that this in the getNameFunc function represents the object rather than window13 alert ("this = object: "+ (this = object); 14 alert (" this = window: "+ (this = window )); 15 // prove that the result of object 16 alert ("that = object is:" + (that = object); 17 return function () {18/* that is a local variable declared in the getNameFunc function. 19 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, 20 It is now that it can be used normally and has not been recycled. 21 The reason is that 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, 22. 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 completed. 23 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. 24 */25 return that. name; // that indicates the object, so that. the access by name is naturally the object name "My Object" 26}; 27 28} 29 30}; 31 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 giving the anonymous method a name called retFn32 alert (retFn (); copying the code is also attached with an example I wrote when learning JavaScript closures: copy code 1 <script type = "text/javascript"> 2 function A () {3 var I = 0; // declare the local variable I 4 inside function A // declare the subfunction B 5 function B () {6 alert ("I =" + (+ + I); // access the local variable I 7} 8 return B declared inside function A in subfunction B; // return the address of the function B 9} 10/* 11 after var c = A () is executed, variable c actually points to function B, and variable I is used in B, 12. After executing c (), a window will pop up showing the I value (1 for the first time). 13. This Code actually creates a closure, 14 because variable c outside function a references function b15 inside function a, that is, when function B inside function a is referenced by a variable outside function, 16. a so-called "closure" 17 is created. After a executes and returns, the 18 Closure makes the garbage collection mechanism of JavaScript GC not to reclaim the resources occupied by, 19 because the execution of the internal function B of a depends on the variable 20 */21 a () in A; // at this time, the memory will certainly have the space for I. When the execution of () then, GC will reclaim the memory space allocated for I 22 var c = A (); // This usage, GC will not regard I as A memory Handler processes 23 c (); // It is equivalent to calling B () and the result is: I = 124 c (); // The result is: I = 225 c (); // The result is: I = 326 </script> copy the code running result: the above is the summary of the JavaScript closure. If something is wrong, please point it out, make progress together!

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.