Closure usage: Classic cases
Learning the same skill will eventually put it into use. From the basic usage of JS functions, we have been studying scope chains and closures. This process consumes a lot of effort. What scenarios can closure be used in? The following is a typical case of using closures by enumeration.
Note that the following examples are typical scenarios of application closures. If you want to use them, you can also call them "code mode ". In-depth understanding and even remembering these scenarios will help you with closure techniques.
Obtain the row to be clicked in the table
Example 4.53
Code:
<HTML>
<Title> ext </title>
<Metahttp-equiv = "Content-Type" content = "text/html"; charset = "UTF-8">
<Scripttype = "text/JavaScript" src = "closure_example.js"> </SCRIPT>
<Bodyonload = "myeffect ()">
<Tableid = "mytab" border = "1">
<Tr>
<TD> column 1st </TD>
<TD> Column 2nd </TD>
<TD> column 3rd </TD>
<TD> column 4th </TD>
<TD> column 5th </TD>
</Tr>
<Tr>
<TD> 1 </TD>
<TD> 2 </TD>
<TD> 3 </TD>
<TD> 4 </TD>
<TD> 5 </TD>
</Tr>
// Repeat five <tr> entries here, with the same structure as above
</Table>
<Divid = "console" style = "Background: # FFFF00"> </div>
</Body>
</Html>
The code for closure_example.js is as follows:
Function myeffect (){
Varconsole = Document. getelementbyid ('console ');
Vartab = Document. getelementbyid ('mytab ');
Vartrs = tab. getelementsbytagname ('tr ');
For (vari = 0; I <TRS. length; I ++ ){
Vartr = TRS [I];
Tr. onmouseover = function (){
This. style. Background = "# ff0000 ";
}
Tr. onmouseout = function (){
This. style. Background = "# ffffff ";
}
Tr. onclick = (function (){
Varrownum = I;
Returnfunction (){
Console. innerhtml = "click the" + rownum + "row ";
}
})();
}
}
Resolution:
Because of this <body onload = "myeffect ()">, after the body is loaded, the myeffect () function is executed. Myeffect adds three event listening functions to each tr Tag: onmouserover, onmouseout, and onclick. The first two functions are very simple and need not be explained. Highlights: 3rd functions:
Tr. onclick = (function (){
Varrownum = I;
Returnfunction (){
Console. innerhtml = "click the" + rownum + "row ";
}
})();
As a whole, this is an "self-executed" function, and the internal return anonymous function is finally registered to The onclick event. So, why? For example, is this the same as the two functions above?
Tr. onclick = function (){
Console. innerhtml = "click the" + I + "line ";
};
Note that I is the loop variable defined in the outer for loop. You can test the code by yourself. The final result is: no matter which line you click, the result is "6th lines clicked ". So why is this result? This is because in the for loop process, I always represents the same variable. Although you seem to have registered an onclick function for each TR, the I in it eventually points to the same thing, which changes with the for loop. Therefore, after the for loop ends, I will always be 6. So how can I keep the order of the For Loop after the for loop ends? This is the function of the return function above. Use a local variable VAR rownum = I; cache the value of I, and exit even if the "self-executed" function of the outer layer, the anonymous functions returned internally can still access the values in the corresponding sequence.
With the study of the function "Scope chain" in section 3rd of this chapter, where is the local variable of the outer function rownum cached? Why does this technique work?
Simulate Multithreading
Example 4.54
HTML code:
<HTML>
<Title> simulated multithreading </title>
<Metahttp-equiv = "Content-Type" content = "text/html"; charset = "UTF-8">
<Body>
<Buttonname = "add thread" value = "add thread" onclick = "addthread ()"> Add
Thread </button>
</Body>
<Scripttype = "text/JavaScript" src = "sim_thread.js"> </SCRIPT>
</Html>
Script code:
// Here is a simple Div tool used to create a div
Function divutil (){}
Divutil. Prototype. Counter = 0;
Divutil. Prototype. creatdiv = function (){
Vardiv = Document. createelement ('div ');
Div. style. Background = '# ffff00 ';
Div. ID = This. Counter ++;
Document. Body. appendchild (DIV );
Returndiv;
}
Vardivutil = new divutil ();
// Here is the "Thread" Class
Thread = function (){}
Thread. Prototype. Start = function (){
Vardiv = divutil. creatdiv ();
If (Div. ID> = 10 ){
Div. innerhtml = "only 10 threads are allowed. Check your CPU! ";
Return;
}
Varnum = div. ID;
Setinterval (function (){
Div. innerhtml = "no" + Div. ID + "the thread is running..." + (Num ++ );
}, 50 );
}
// Tool function, add thread
Functionaddthread (){
Varthread = new thread ();
Thread. Start ();
}
The running effect is shown in Figure 4-91.
Figure 4-91 multi-thread Simulation
Resolution:
This is a very interesting example. It looks like starting multiple "Threads". The core code is this section:
VaR num = div. ID;
Setinterval (function (){
Div. innerhtml = "no" + Div. ID + "the thread is running..." + (Num ++ );
}, 50 );
Because of the closure, in the function executed by the timer setinterval, you can always access the partial variable num in the outer function.
-- This text is excerpted from ext
Book details: http://blog.csdn.net/broadview2006/article/details/7211734