Loops and closures
First Look at a demo
<!DOCTYPE HTML><HTMLLang= "en"><Head> <MetaCharSet= "UTF-8"> <title>Document</title></Head><Body> <Script> for(varI= 0; I<= 5; I++) {setTimeout (functiontimer () {console.log (i); }, I* +); } </Script></Body></HTML>
What will the results print? I believe we all know the answer is 6 6; we meant to print: 0,1,2,3,4,5 but it turned out to be 6 6, why? First explain why print out 6: Here involves the execution mechanism of the delay function, although the delay function indicates that it is executed after I seconds, and I seconds is relative to all executable code after the moment of execution, that is, after the end of the for loop, the delay function will begin to execute. But at this point i= 6; So it prints out 6. Now explain why it's 6.6: Very simple, for each execution of the for loop creates a delay function, executes 6 times, there will be 6 delay function. These 6 delay functions share a scope (global scope in this case) and I accumulate to 6, so 6 6!! will be printed
After analyzing the whole process, do you know where the problem appears? There are 2 questions 1: Each time A For loop is executed, a delay function should be executed, but not. 2: All delay functions share a scope.
Knowing where the problem is, it's good to fix it: once per loop, create a scope. The key is how to implement "one cycle at a time, create a scope", in fact, it is very simple, once per loop, immediately execute a delay function, immediately execute the function (Iife) comes in handy the principle is "rough": each delay function will be created in each iteration of the scope Iife closed up. OK, modify our code:
<!DOCTYPE HTML><HTMLLang= "en"><Head> <MetaCharSet= "UTF-8"> <title>Document</title></Head><Body> <Script> for(varI= 0; I<= 5; I++){ (function() {setTimeout (functiontimer () {console.log (i); }, I* +); })(); } </Script></Body></HTML>
Show in Chrome:
Hey??? Why is it still 6 6!!!? Where is the problem? Actually very simple, take a closer look, our iife is nothing but a null scope (I is a global variable, in the global scope) it needs to have its own variables to store the value of I in each iteration to improve the code:
<!DOCTYPE HTML><HTMLLang= "en"><Head> <MetaCharSet= "UTF-8"> <title>Document</title></Head><Body> <Script> for(varI= 0; I<= 5; I++){ (function(){ varJ=i; SetTimeout (functiontimer () {console.log (j); }, J* +); })(); } </Script></Body></HTML>
Show in Chrome:
By depositing the value of I in, we can achieve our expectations. So far, the code is no longer a mistake. However, you can also optimize:
<!DOCTYPE HTML><HTMLLang= "en"><Head> <MetaCharSet= "UTF-8"> <title>Document</title></Head><Body> <Script> for(varI= 0; I<= 5; I++){ (function(i) {setTimeout (functiontimer () {console.log (i); }, I* +); }) (i)}</Script></Body></HTML>
By passing I as a parameter, our code is more perfect.
2017-3-23 0:19
JavaScript---loops and closures