JavaScript closures Discussion

-------------------

Author: willingtolove;

This link: http://www.cnblogs.com/willingtolove/p/4745889.html

1. The scope of variables:

  In javascript, the scope of local variables is determined by its function defined, the nested function can access variables outside its scope.

  EX1:

Copy the code
1 function hello() {
2     var name = "world";
3     function hi() {
4         alert(name);
5     }
6     hi();
7 }
8 hello();
Copy the code

   Run the code above: pop-up "world";

   Since this variable is scoped name lines 1-7 (the hello function);

   To understand in detail please refer to: the scope and the scope chain ; this is useful for understanding the closure!

 2. js garbage collection mechanism

   js with automatic garbage collection, developers no longer need to be concerned about memory usage issue; principle of this garbage collection mechanism is very simple: to find a variable no longer continue to use, and free up the memory. To this end, the garbage collector will at regular intervals

(Or set by the code) periodically performing this operation.

   Life Cycle function of local variables: Local variables exist only in the course of function execution. This process will be allocated to the stack or heap space variable corresponding to their values ​​stored. When the function ends, the variable is useless, it will be garbage

Marked collector, subject to recall. The next time then perform this function, all variables back to the original state, re-assignment to use. But sometimes, this function is nested inside another function, and this function uses the internal variables of the outer function, and

Internal function is called out. At this time garbage collection will be a problem. If, after the end of the external function, and direct calls its internal function, so internal functions can not be read to the external value of the variable in the function he needs so js interpreter encounters set in function

When defined, will automatically functions and variables that it may be used (including in this variable and a function of parent and ancestor-level functions) is stored, together, the equivalent of a storage environment, i.e. to build a closure, these variables (or environmental) will not be in the

When the deposit collector recovered only when after an internal function can not be invoked (eg deleted ...), will destroy this closure, without any reference to a closure variable will be the next garbage collection starts recovered.

 3. Closure definitions:

    A closure is a function of the independent variables involved; in other words, functions defined in the closure will remember the context in which it was created;

    Such is also understood that: closure is the function of the other function can read internal variables; Javascript language since only internal function subroutine to read local variables, the closure can be simply understood as a "function is defined inside a The function".

Therefore, in essence, the closure is an internal bridge function and the function of connecting external.

   Official "explanation is: a closure is bound to have many variables and environmental variables expressions (usually a function), these variables are thus part of the expression.

In fact, it is a popular phrase: JavaScript is a function of all of closure . However, in general, the nested function arising from the closure of more powerful, but also most of the time we call "closure."

    Creating closure of most common way is to create a function within another function, access this function by another function of local variables;

    EX2:

Copy the code
1 function hello() {
2     var name = "world";
3     function hi() {
4         alert(name);
5     }
6     return hi;
7 }
8 was myHello = hello ();
9 myHello();
Copy the code

     The above operation results in a code with the same effect as EX1;

     why?

     This code has two characteristics:

    1, nested inside function hi Hello function;

    2, the function returns hello function hi.  

     After executing the so var myHello = hello (), it is actually a variable MyHello pointing function hi, then execute MyHello () pops up a window displaying the value of name. In fact, this code creates a closure, and why?

Since the variable external function hello MyHello reference functions within the function hi hello, that is: when the internal function hi hello function of a variable is referenced outside the hello function, a closure is created.

     Code execution eighth row, the name variable life cycle begins, but the implementation of the code to ninth row, the life cycle of the variable name does not end;

   By way of example above, closures can be understood: When a function is executed outside of the environment in which it was created, that is closures. (Myhello function is a closure)

   Closures are a special object, which comprises two parts: ① function; ② creation environment function;

     EX3:   closures example

    

Copy the code
 1 function play() {
 I have 2 n = 1;
 3     return function () {
 4         alert(num++)
 5     };
 6 }
 7 var myPlay = play();
 8 myPlay (); // Results: 1 
 9 myPlay (); // results: 2
10 myPlay = null; // num is recovered!
11 myPlay (); // Error: Missing Object
Copy the code

    Analysis: internal function before returning, will all (num) function external variables has visited the locked in memory, that is to say, these variables will be based in myPlay the memory will not be garbage collected;

num is locked in a closed bag myPlay, then myPlay each execution time, num will increment once;

    EX4:  closures example

Copy the code
 1 function Add(x) {
 2     return function (y) {
 3         return x + y;
 4     };
 5 }
 6 
 7 was Add5 = Add (5);
 8 was ADD10 = Add (10);
 9 
10 console.log(Add5(2));
11 console.log(Add10(2));
Copy the code

     The result: 7,12

   analysis:

Copy the code
1 // Add5 is equivalent to:
2 function Add5(y) {
3     return 5 + y;
4 };
5 // Add10 is equivalent to:
6 function Add10(y) {
7     return 10 + y;
8 };
Copy the code

    Add5 and Add10 are closures, they are stored in different environments; Add5 environment of x is 5, x is in Add10 environment 10;

4. Closure usage scenarios

  1) self-executing anonymous function: (in html element event initialization)

    EX5:

Copy the code
 1 <head>
 2     <title></title>
 3     <script type="text/javascript">
 4         window.onload = function() {
 5             for (var i = 1; i < 4; i++) {
 6                 var li = document.getElementById("a" + i);
 7 li.onclick = (function (i) {// perform functions from anonymous
 8                     return function() {
 9                         alert(i);
10                     }
11                 })(i);
12             }
13         }
14 
15     </script>
16 </head>
17 <body>
18     <ul>
19         <li id="a1">a1</li>
20         <li id="a2">a2</li>
21         <li id="a3">a3</li>
22     </ul>
23 </body>
Copy the code

    Effect: Click a1, pop a1; click on a2, pop a2; click a3, pop a3;

 

    2) to achieve package, thereby realizing the function of reading the internal variables local to the function from the outside;

    EX6:

Copy the code
 1         var person = function () {
 2 var name = "world"; // variable scope internal function, inaccessible outside    
 3             return {
 4                 getName: function () {
 5                     return name;
 6                 },
 7                 setName: function (newName) {
 8                     name = newName;
 9                 }
10             }
11         }();
12 alert (person.name); // accessed directly, the result is undefined    
13 alert (person.getName ()); // Results: world
14         person.setName("hello");
15 alert (person.getName ()); // result: hello
Copy the code

 

  3) the simulation object oriented object;

      Different objects have an independent state and a member of noninterference in each other. Although there is no such mechanism in JavaScript classes, but through the use of closures,
      we can simulate such a mechanism.

   EX7:

Copy the code
 1         function Person(){    
 2             var name = "default";       
 3        
 4             return {    
 5                 getName : function(){    
 6                     return name;    
 7                 },    
 8                 setName : function(newName){    
 9                     name = newName;    
10                 }    
11             }    
12         };    
13      
14 was hello = Person ();
15 print (hello .getName ()); // result: default 
16         hello .setName("hello");    
17         print(hello .getName());  //结果:   hello
18      
19 was the World = Person ();
20 print (world .getName ()); // result: default 
21         world .setName("world");    
22 print (world .getName ()); // Results: world 
Copy the code

 

  

5. Common Errors

  EX8-1:

Copy the code
 1 were result = [];
 2 function play() {
 3 where i = 0;
 4     for (; i < 3; i = i + 1) {
 5         result[i] = function () {
 6             alert(i)
 7         }
 8     }
 9 };
10 play();
11 result [0] (); // Results:
12 result [1] (); // Results:
13 result [2] (); // Results:
Copy the code

 

  EX6, the play function of the desired variable i is a function of the use of internal circulation, in fact, only the last value of the variable reservation is obtained, i.e. Closed recorded in a variable packet, this is only one variable reference, rather than the value of the variable when this variable is changed,

Closed bag obtained variable value will be changed.

One solution is to allow the internal functions are executed when the cycle is created immediately and capture the current index value, then a record in its own local variable. Then using the method returns the function of rewrite internal function, so that the next time when called, the return value of local variables, code improvements:

   EX8-2:

Copy the code
 1 were result = [];
 2 function play() {
 3 where i = 0;
 4     for (; i < 3; i = i + 1) {
 5         result[i] = (function (j) {
 6             return function () {
 7                 alert(j);
 8             };
 9         })(i);
10     }
11 };
12 play();
13 result [0] (); // Results: 0
14 result [1] (); // Results: 1
15 result [2] (); // results: 2
Copy the code

Performance considerations:

   EX9-1:

Copy the code
 1 function MyObject(name, message) {
 2   this.name = name.toString();
 3   this.message = message.toString();
 4   this.getName = function() {
 5     return this.name;
 6   };
 7 
 8   this.getMessage = function() {
 9     return this.message;
10   };
11 }
Copy the code

   Analysis: Each new a MyObject, getName and getMessage will copy once, affect performance;

   EX9-1 use of improved closure:

  EX9-2:

Copy the code
 1 function MyObject(name, message) {
 2     this.name = name.toString();
 3     this.message = message.toString();
 4 }
 5 (function() {
 6     this.getName = function() {
 7         return this.name;
 8     };
 9     this.getMessage = function() {
10         return this.message;
11     };
12 }).call(MyObject.prototype);
Copy the code

   Analysis: No matter how many MyObject new, getName and getMessage copy only once;

to sum up:

  In a dynamic execution environment, changes occur in real-time data, non-durable in order to maintain the values ​​of variables, we closures such vectors to store dynamic data. This is the role of closures. Also said that encountered need to store dynamically changing data or data to be recovered

, We can re-wrapped layer formed closure function is achieved by the outside.

  Of course, the closure will lead to many external function call the object can not be released, abuse closure will cause a memory leak.

  ------

  This essay is also a reference to the film's predecessors handouts, there are a lot of study and research knowledge wait, please correct me!

in a moment

Reproduced in: https: //www.cnblogs.com/zhangchenliang/p/4760669.html

Guess you like

Origin blog.csdn.net/weixin_34402090/article/details/93495555