Preface we have already learned about functions and scopes. Now we are going to learn closures. This is a rather obscure knowledge point. Beginners may feel hard to understand, but none of them agree, if you are a beginner, let me give you some advice. I will learn what a closure is. Let's not talk about the definition of the example. Let's first look at a question to see if everyone can get the correct result. Copy the code function test () {var arr = []; for (var I = 0; I <10; I ++) {arr [I] = function () {return I ;}} return arr ;}var fns = test (); console. log (fns [9] (); // What is the value? Console. log (fns [0] (); // What is the value? The result of copying the Code is View Code. Are you right? What is a closure? We know that the scope of variables in javascript is divided into global variables and local variables. We can use global variables anywhere, but this is not the case for local variables, we can only get it in the scope of this variable. In other words, we can use external variables within the function, but we cannot use local variables defined inside the function outside the function, but in reality, we want to use the variables defined inside the function outside the function. What should we do? Function test () {var inner = 10;} alert (inner); // error? What should I do? We know that we can access this variable internally. We also know that the return operator can return the desired value, so I will define a function internally to access this variable, then you can simply return this function. In practice, copy the code function test () {var inner = 10; function inFun () {alert (inner );//}; return inFun;} var outter = test (); outter (); // 10; copy the code. We did it and applaud ourselves. Sometimes we should keep encouraging ourselves, don't put too much pressure on ourselves. We are not the rich generation. Don't encourage ourselves to become the rich generation. This is the closure. The official website does not provide a complete and accurate definition of the closure. It is common to define a function in a function, and this internal function can be accessed outside, at this time, a closure is formed. Look at the structure of the above function. A function returns an internal function. We know that under normal circumstances, after a function is executed, the variables in it will be released, that is, in test () after this statement is executed, the inner should be released, but we find that when outter (), we get the inner value, which is the feature of the closure: if the closure uses a local variable, the variable will be stored in the memory and the closure will keep this value until the external function is not referenced, copy the code function closure () {var num = 0; function add () {console. log (++ num);} return add;} var test1 = closure (); // form a closure and keep one of its num variables test1 (); // 1test1 (); // 2var test2 = closure (); // another closure keeps one of its own num variables test2 ();// 1test2 (); // 2 is it fun to copy the code? This is the magic of closures. It is also a headache for beginners. Believe me, I will help you understand it. To release the memory occupied by num, test1 = null; test2 = null; simple parsing example: When var test1 = closure () is executed, closure () the returned result is a function, which is equivalent to the test1 variable pointing to a function add. However, this add function has its own scope and activity object, and both exist in test1. Execute test1 () will look for the num variable, because the closure stores this variable can be obtained directly, and automatically add 1, then execute test1 () will continue to search in the execution environment and scope of the add function executed by test1. If num is 1, The num is found. When var test2 = closure () is executed, will re-create a closure and re-store the execution environment and activity objects, so this is completely irrelevant to the first time. The closure mechanism function is also an object. It has the [scope] attribute (which can only be accessed through the JavaScript engine) and points to the execution environment context when the function is defined. Assume that A is A global function and B is an internal function of. When executing function A, the context of the current execution environment points to A scope chain. The first object of the scope chain is the activity object of the current function (this, parameter, local variable), and the second object is the global window. When the Execution Code runs to the definition of B, set the [[scope] attribute of function B to the context scope chain of the execution environment. After the execution of function A is complete, if the reference of function B is not external, the activity object of function A will be reclaimed by Js. Otherwise, it will be maintained to form A closure. When function B is called, the JavaScript engine stacks the current execution environment to generate a new execution environment. The context of the new execution environment points to a scope chain, it is composed of the current active object + [scope] of function B. The first object of the chain is the activity object of the current function (this, parameter, and local variable ), the second activity object is generated by function A and the third window. Function B accesses a variable and parses the identifier (the JavaScript prototype also has an identifier). It searches for the variable from the first object in the scope chain pointed to by the current context, if no value is found, the second object is searched and the result is returned immediately. If no value is found, the undefined error is returned. When all internal references to function A's external violence are eliminated, the activity object of function A is destroyed. This section is from other places, that is to say, the execution environment and scope understand how closures maintain variables. Closure applications can read the internal variables of the function mentioned above, and keep the values of these variables in the memory. This is both a function and a drawback. We can use closures to encapsulate some private attributes, such as copying the code var factorial = (function () {var cache = []; return function (num) {if (! Cache [num]) {if (num = 0) {cache [num] = 1;} cache [num] = num * factorial (num-1 );} return cache [num] ;}}) (); the copied Code encapsulates an internal private attribute to cache the result. The following popular Module mode allows you to simulate public, private, and privileged members to copy code var Module = (function () {var privateProperty = 'foo'; function privateMethod (args) {// do something} return {publicProperty: "", publicMethod: function (args) {// do something}, privilegedMethod: function (args) {privateMethod (args) ;}}) (); copy the code. Another type of closure is called the immediate execution function expression. It is an anonymous function Self-called in the window context: copy the code (function (window) {var a = 'foo'; function private () {// do something} w Indow. module = {public: function () {// do something };}) (this ); the disadvantage of copying code closure is that the closure will make all the variables in the function be saved in the memory, and the memory consumption is very high. Therefore, the closure cannot be abused. Otherwise, it will cause web page performance problems, memory leakage may occur in IE. The solution is to delete all unused local variables before exiting the function. 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. Return to the example at the beginning. This is a classic example of closures. This is different from other examples. for analysis, an array is used here, in fact, here we execute var fns = test () to form 10 closures. Each item in the array stores a closure, which is different from other examples, in other examples, function execution forms a closure at a time, so the initial execution environment of the 10 closures is the same. Each closure uses the I variable, this variable is changed to the I value 10 after the var fns = test () function is executed to exit the loop. JavaScript is an interpreted language, so when executing the closure in the array, the value of I is 10. How can I solve this problem now? Let's think about it. When these 10 closures are formed, the execution environment is the same as the activity object. Now we want to consider the difference at the beginning. We know that the function scope is layer-by-layer, then we need to set a scope between them. The scope must have different I values. We thought of self-executing anonymous functions, (funciton (){})(), we put the I value in. Passing parameters by value is equivalent to copying a variable. In (funciton (){})() changing the I value in the external scope will not change the internal I value. Try copying the code function test () {var arr = []; for (var I = 0; I <10; I ++) {(function (I) {arr [I] = function () {return I ;}) (I) ;}return arr ;} var fns = test (); console. log (fns [9] (); // The value is 9console. log (fns [0] (); // The value is a 0-copy generation. You can also copy the code function test () {var arr = []; for (var I = 0; I <10; I ++) {arr [I] = (function (I) {return function () {return I}) (I) ;}return arr ;}var fns = test (); console. log (fns [9] (); // The value is 9console. log (fns [0] (); // The value is 0. Copy the code. The essence is to wrap a scope for each closure before the closure is formed, in this scope, a parameter is passed, that is, each closure has a different I in the upper-level scope. Of course there are other ways to do this.