"Translating" javascript loops and scopes

Source: Internet
Author: User


My translation station: Www.zcfy.cc/article/javascript-loops-and-scope


Translated text link: flaviocopes.com/javascript-loops-and-scope/


JavaScript has a feature that may cause headaches for developers, and is related to loops and scopes.



As an example:



  
const operations = []
 
for (var i = 0; i < 5; i++) {
  operations.push(() => {
    console.log(i)
  })
}
 
for (const operation of operations) {
  operation()
}


It basically loops 5 times and adds a function to the operations array. This function prints out the index value of the loop variablei.



After you run these functions



The expected result should be:


01234


But what actually happens is this:


55555


Why is this happening? Because it's usingvar.



Because thevarvariable is promoted, the above code is equivalent to the


var i;
const operations = []
 
for (i = 0; i < 5; i++) {
  operations.push(() => {
    console.log(i)
  })
}
 
for (const operation of operations) {
  operation()
}


Therefore, in the for-of loop,iIt is still visible, it is equal to 5, and each time it is involved in the functioni, this value will be used.



So what should we do to make it what we think it is?



The simplest scenario is to use aletdeclaration. Introduced in ES2015, they are a great help to avoidvarsome strange questions about the use of claims.



Simple in the loop variable willvarbecomelet, can run well:


const operations = []
 
for (let i = 0; i < 5; i++) {
  operations.push(() => {
    console.log(i)
  })
}
 
for (const operation of operations) {
  operation()
}


Here is the output:


01234


How does this work? This is because each time the loop repeats, it is recreatedi, and each function addsoperationsan array, which gets its owni.



Remember that you cannot useconstin this case, because this will causeforthe new value to be tried when the second loop is given an error.



Another very common solution to this problem is to use the PRE-ES6 code, which is called an instant call function expression (iife).



In this case, you can wrap the entire function andibind it on top of it. From this way, you are creating a function that can execute immediately, and you return from it with a new function. So we can execute it later.


const operations = []
 
for (var i = 0; i < 5; i++) {
  operations.push(((j) => {
    return () => console.log(j)
  })(i))
}
 
for (const operation of operations) {
  operation()
}



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.