current position:Home>[JS] 10. Closure application (loop processing)

[JS] 10. Closure application (loop processing)

2021-08-29 08:23:12 ahanpi

  • The mechanism based on closure completes

  • Function execution forms a private context , After execution , Something in the current context is occupied by something outside the current context , Can't be released , It's a closure

  • Characteristics of closures

    • The protection mechanism of closures : Protect the variable independence of the current context , Free from external interference
    • The preservation mechanism of closures : Save private variables , Form a non releasing context , For use by subordinate contexts
  • The disadvantages of closures : Closures occupy memory , Consume browser performance ( Closures cannot be abused )

1. Application of closures in loop event binding or loop operation

1.1 Loop event normal output

  • setTimeout([function], [interval]) Set a timer , wait for interval Duration , Trigger function perform
for (var i = 0; i < 3; i++) {
  setTimeout(()=>{
    console.log(i)
  }, (i+1)*1000)
}
 Copy code 
  • The first cycle i=0, Set to create a timer , Not implemented at this time function,1000ms After execution
  • The second cycle i=1, Set to create a timer , Not implemented at this time function,2000ms After execution
  • The third cycle i=2, Set to create a timer , Not implemented at this time function,3000ms After execution
  • At this point, the synchronization code for Loop to i=3 The loop ends
  • 1000ms It's time to execute the callback , There is no... In the formed private context i, Find the superior context , That is, the overall situation i = 3
  • ... Output 3 individual 3

1.2 Loop event closure transformation

  • Ideas , Save a... In your own context i, Closure idea

1.2.1 How to write it 1

for (var i = 0; i < 3; i++) {
  //  Each cycle , Self executing function execution , Will produce a private context 
  //  And the current round of circulation , Global variables i The value of is passed as an argument to a formal parameter in a private context i
  (function(i){
     setTimeout(()=>{
       console.log(i)
     }, (i+1)*1000)
  })(i);
}
 Copy code 
  • The first round EC(AN1) Parameter assignment i = 0
  • The first round EC(AN2) Parameter assignment i = 1
  • The first round EC(AN3) Parameter assignment i = 2
  • Each formed private context , Will create a Arrow function heap , And assigned the value to window.setTimeout, In this way, it is equivalent that some content in the current context is occupied by content outside the context , The formed context will not be released , Private variables i The value of will not be released , Closure , Loop three times to form three closures

1.2.2 How to write it 2


// let xxx = proxy(0); // -> proxy Execution will return a function , By xxx Occupy , Don't release , Closure , Private variables in closures , Is the parameter passed by the function execution 

const proxy = i => {
  return () => {
    console.log(i);
  };
}
for (var i = 0; i < 3; i++) {
  //  The callback executes proxy Small function returned 
  setTimeout(proxy(i), (i+1)*1000)
}
 Copy code 

1.2.3 How to write it 3

  • let A private block level scope will be formed
  • be based on let The cycle of ,let There is a processing mechanism for block level scopes , First, the browser creates a parent private context , To control the cycle
  • Each round of the loop also produces a private block level context , Each has its own private variable i, Store the current cycle i Value
  • In every private block level context , Also create a function , And be window.setTimeout To take up , This block level context will not be released , Closure
for (let i = 0; i < 3; i++) {
  setTimeout(()=>{
    console.log(i)
  }, (i+1)*1000)
}
 Copy code 
  • let Formed closure , It is implemented at the bottom of the browser , In terms of performance, it is a little faster than the closure created by yourself
for (let i = 0; i < 3; i++) {
   //  Each round of the loop produces a private block level context , If nothing in the context is occupied externally , Then this cycle ends , The block level context is released 
   //  Once something is occupied , Closure will be generated 
  setTimeout(()=>{
     //  Creating a function scope is context , And x irrelevant , Also form closures 
     //  And i Irrelevant code ,setTimeout occupied , It's also a closure 
  }, 1000)
}
 Copy code 
  • Unwanted i Recommend writing , This situation , No block level context , Do not form closures
let i = 0;
for(; i<3; i++) {
  setTimeout(()=>{
   ...
  }, 1000)
}
 Copy code 

copyright notice
author[ahanpi],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210829082307226w.html