-------------------
Willingtolove;
This article link: http://www.cnblogs.com/willingtolove/p/4745889.html
1. Scope of variables:
In JavaScript, the scope of a local variable is determined by the function it defines, and the nested function can access its external scope variables.
EX1:
1 function Hello () {2 var name = "World"; 3 function Hi () {4 alert (name); 5 }6 hi (); 7}8 hello ();
Running result of the above code: Popup "World";
Because name is the scope of this variable is 1-7 rows (hello in this function);
For a detailed understanding, consult: Scope and scope chain ; This is useful for understanding closures!
2. JS garbage collection mechanism
JS has an automatic garbage collection mechanism, developers no longer care about memory usage issues; This garbage collection mechanism is simple: identify variables that are no longer in use, and then release the memory they occupy. To do this, the garbage collector is at a fixed time interval
(or set by code) to perform this operation periodically.
The life cycle of local variables in a function: Local variables exist only during function execution. In this process, the variables are allocated the appropriate space on the stack or heap in order to store their values. When the function is finished, the variable is useless and will be garbage
The collector is marked for recycling. The next time the function is executed, all the variables return to their original state and are re-assigned. But sometimes the function is nested inside another function, and this inner function uses the variables of the external function, and
The inner function is called outside. The garbage collection mechanism can be problematic at this point. If the external function is finished and the internal function is called directly, then the intrinsic function cannot read the value of the variable in the external function that he needs. So the JS interpreter encounters a function
, it automatically stores the function and the variables it may use (including variables within the function and parent and ancestor functions), which is equivalent to storing an environment, that is, building a closure, these variables (or environments) will not be
The storage collector is recycled only if the internal function cannot be called later (for example, deleted ...) before the closure is destroyed, and no one of the closure references is reclaimed by the next memory recycle when it is started.
3. Definition of closures:
Closures are functions that involve independent variables; in other words, the function defined in the closure remembers the environment it created;
It is also understood that a closure is a function that can read the internal variables of other functions; Because in the JavaScript language, only sub-functions inside the function can read local variables, so the closure can be simply understood as "a function defined inside a function".
So, in essence, a closure is a bridge that connects the inside of the function to the outside of the function.
The official explanation is that closures are an expression (usually a function) that has many variables and environments that bind them, and so these variables are also part of the expression.
In fact, the phrase is:all the function in JavaScript is a closed packet . In general, however, the nested function produces a more powerful closure, which is what we call "closures" most of the time.
The most common way to create closures is to create another function within one function and access the local variables of the function through another function;
EX2:
1 function Hello () {2 var name = "World"; 3 function Hi () {4 alert (name), 5 }6 return hi;7}8 var Myhell o = Hello (); 9 MyHello ();
The result of the above code is the same as the effect in EX1;
Why is it?
There are two features of this code:
1. The function hi is nested inside the function hello;
2, function hello return function hi.
So after the execution of Var Myhello=hello (), the variable MyHello actually points to the function hi, and then executes MyHello () and then pops up a window to display the value of the variable name. This code actually creates a closure, why?
Because the variable myhello of the function Hello refers to the function hi inside the function hello, that is, when the function Hello's inner function hi is referenced by a variable outside the function hello, a closure is created.
When the code executes line 8th, the name variable life cycle starts, but when the code executes to line 9th, the life cycle of the name variable does not end;
In the example above, it is possible to understand closures: when a function executes outside of the environment it creates, it is a closure. (function Myhello is a closure)
A closure is a special object that consists of two parts: the ① function; the environment in which the function is created ②;
EX3: Closure Example
1 function Play () {2 var num = 1; 3 return function () {4 alert (num++) 5 }; 6} 7 var myplay = Play (); 8 Myplay ();//Results: 1 9 Myplay ();//Result: Myplay = Null;//num is recycled! Myplay ();//Error: Missing object
Analysis: The intrinsic function locks all the variables (num) in the external function that have been accessed in memory before returning, that is, the variables will reside in Myplay memory and will not be reclaimed by the garbage collector;
Num is locked in Myplay's closure, and num is added once every time the myplay is executed;
EX4: Closure Example
1 function Add (x) {2 return function (y) {3 return x + y; 4 }; 5} 6 7 var Add5 = ADD (5); 8 var Add10 = ADD (10); 9 Console.log (ADD5 (2)); Console.log (ADD10 (2));
Running Result: 7,12
Analysis:
1//add5 is equivalent to: 2 function Add5 (y) {3 return 5 + y;4};5//ADD10 equivalent: 6 function Add10 (y) {7 return + y;8};
Add5 and ADD10 are closures, but they store different environments, and X is 5 in the ADD5 environment, and X is 10 in the ADD10 environment;
4. Usage Scenarios for closures
1) anonymous self-executing function: (Initialization of element events in HTML)
EX5:
1
Effect: Click A1, Pop A1, click a2, Pop A2, click A3, Pop A3;
2) Implement encapsulation, so that the local variables inside the function are read from outside the function;
EX6:
1 var person = function () {2 var name = ' World ';//variable scope is inside function, external cannot access 3 return {4 getname:function ( {5 return name; 6 }, 7 setname:function (newName) {8 name = newName; 9 }10 }11 } (); 12< C13/>alert (person.name);//Direct access, the result is undefined alert (Person.getname ());//Result: World14 Person.setname ("Hello"); alert (Person.getname ());//Result: Hello
3) Simulating objects in object-oriented;
Different objects have independent members and states, and do not interfere with each other. Although there is no such mechanism in JavaScript, by using closures,
We can simulate such a mechanism.
EX7:
1 function person () { 2 var name = "Default"; 3 4 return { 5 getname:function () { 6 return name; 7 }, 8 setname:function (newName) { 9 name = NewName; Ten} One} ; var hello = person (); print (hello. getName ());//Result: default + hello. SetName (" Hello "); print (hello. getName ()); Result: hello18 var world = person (), print (World getName ()); Result: default . SetName ("World"); Print (World getName ()); Results:
5. Common errors Ex8-1:
1 var result = []; 2 function Play () {3 var i = 0; 4 for (; i < 3; i = i + 1) {5 Result[i] = function () {6 alert (i) 7< c4/>} 8 } 9};10 play (); result[0] (); Results: 312 result[1] (); Results: 313 result[2] (); Results: 3
In EX6, I wanted the variable i in the Play function to be used by the inner loop function, but in fact, only the value that the variable was last reserved, that is. The variable that is recorded in the closure is just a reference to the variable, not the value of the variable, when the variable is changed,
The value of the variable obtained in the closure will also be changed.
One way to do this is to have the inner function execute as soon as the loop is created, capture the current index value, and then record it in one of its own local variables. Then, using the return function method, rewrite the intrinsic function, let the next call, return the value of the local variable, the improved code:
ex8-2:
1 var result = []; 2 function Play () {3 var i = 0; 4 for (; i < 3; i = i + 1) {5 result[i] = (function (j) {6 return fu Nction () {7 alert (j); 8 }; 9 }) (i); }11};12 Play (); result[0] (); Results: 014 result[1] (); Results: result[2] (); Results: 2
Performance considerations:Ex9-1:
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 retur n this.message;10 };11}
Analysis: Each new myobject,getname and GetMessage will copy once, affecting performance;
Using closures to improve ex9-1:
Ex9-2:
1 function MyObject (name, message) {2 this.name = Name.tostring (); 3 this.message = message.tostring (); 4} 5 (Fu Nction () {6 this.getname = function () {7 return this.name; 8 }; 9 this.getmessage = function () {Ten R Eturn this.message;11 };12}). Call (Myobject.prototype);
Analysis: No matter how many new myobject,getname and getmessage only copy once;
Summarize:In the dynamic execution environment, the data changes in real time, in order to maintain the values of these non-persistent variables, we use the closure of this vector to store these dynamic data. This is the function of closures. It is also said to meet the data that needs to store dynamic changes or to be recycled
, we can solve the problem by wrapping a layer of function outside to form a closure.
Of course, closures can cause many external functions to be called objects that cannot be freed, and abusive closures can make memory leaks.
------
This piece of essay is also reference to your predecessors of the handout, there are a lot of knowledge points waiting to study, welcome to correct!
A brief talk on JavaScript closures