First contact This problem is still in I just started to learn JS, then is confused, after more than a year, and suddenly think of this problem, in this spring-filled weekend, I sat down to study and the results and share the next;
First look at the code: demo.html
<! DOCTYPE html>
<meta charset= "GBK"/>
<title> Closure Cycle Issues </title>
<style type= "Text/css" >
p {background:red;}
</style>
<body>
<p id= "P0" > paragraph 0</p>
<p id= "P1" > paragraph 1</p>
<p id= "P2" > paragraph 2</p>
<p id= "P3" > paragraph 3</p>
<p id= "P4" > paragraph 4</p>
<script type= "Text/javascript" >
for (var i=0; i<5; i++) {
document.getElementById ("P" +i). Onclick=function () {
alert (i); The variable i, which accesses the parent function, closes the packet
};
};
</script>
</body>
Each time the loop adds a click event to the corresponding numbered paragraph, the callback function of the event is to execute an alert (); If you haven't used it before, you'll probably think that clicking on a paragraph will pop up the corresponding number 0,1,2,3,4 of the paragraph. But actually it's all popped up 5;
There have been a lot of discussion blogs on the internet, and they have given a lot of ways to implement the corresponding numbering. A more understandable approach is as follows:
1. Save the variable I on a property of the corresponding paragraph : Click to view the effect.
var pary = document.getElementsByTagName ("P"); for (var i=0; i< 5; i++) { pary[i].no = i; Pary[i].onclick = function () { alert (this.no); } };
2, add a layer of closure, I pass the function parameter form to the inner layer function : Click to see the effect.
~function Test () { var pary = document.getElementsByTagName ("P"); for (var i=0; i< pary.length; i++) { (function (ARG) { Pary[i].onclick = function () { alert (arg); } ; }) (i);//call-time argument } } ();
Of course there are other ways, but they are not very well understood.
And what I'm going to explore is why the return value in Demo.html is always 5. It is said on the Internet that "variable i is stored in the function as a pointer or variable address", because only in this way can it be explained. But how can we serve the audience with just one conclusion?
The topic of pointers or variable addresses is commonplace in C, but it is rarely used in JS's sexy language except for objects and their object properties. A basic data type is actually linked to the pointer, which brings up the desire to explore.
3, try the following code Click to see the effect
~function Test () { var temp =10; for (var i=0; i< 5; i++) { document.getElementById ("P" +i). Onclick=function () { alert (temp);//The variable that accessed the parent function temp , Closures } }; temp=20; } ();
The result of the execution is that each paragraph pops up with 20, not 10. Note that when we clicked, the value of temp was already 20. It's an obvious result that doesn't seem to need me, because temp was already assigned a value of 20 before we clicked.
4, then look at the following code click to see the effect.
We have a program to trigger the Click event before temp is changed, the popup is 10;
~function Test () { var temp =10; for (var i=0; i< 5; i++) { document.getElementById ("P" +i). Onclick=function () { alert (temp);//access to the parent function of the variable i, closure } if (i===1) { var evt = document.createevent ("mouseevents"); Evt.initevent ("click", True,true); document.getElementById ("P1"). Dispatchevent (EVT); } ; temp=20; } ();
This means that the Click event callback function we bound at P1 was supposed to return 10, and when I manually clicked the P0 paragraph again, the reason for popping 20 was because the value of temp changed. This means that each time the popup is accessed is the value of the temp at the moment, not the value at the time of the binding, which means that the variable temp is actually saved as a variable address. The extension is open: The function internally accesses a variable with the sibling of the function, then the variable is resident memory. Access to the variable is essentially the address of the variable;
Through the above conclusions, we can simply describe the nature of closures: in the sub-scope, a copy of the variables obtained at the parent scope, these variables will not be destroyed with the destruction of the parent scope, because they are already resident memory!
This statement also explains the characteristics of closures:
1: Memory leak due to resident memory
2, as long as the other scopes can fetch the access interface to the child scope, there is a way for other scopes to access the variables of the parent scope of that child-scope.
See examples of such a typical closure:
function A () {
var a=1;
function B () {
return A;
};
return B;
};
var c=a ();//c gets the access interface of child scope B of a
Console.log (c ());//1 C can access variable A in the parent scope of B
If there are deficiencies, welcome correction, Common progress!
Cyclic parameter problems in closures