⌈ 2022 ⌋ JavaScript super detailed loop summary

Posted by habs20 on Fri, 07 Jan 2022 11:26:53 +0100

preface

This is one of my series of articles on basic JavaScript. It doesn't talk about the efficiency of various loops. It mainly summarizes the use methods and some precautions. Click the secondary and tertiary titles to open the corresponding MDN documents. The daily blog is recorded in YuQue. Welcome to pay attention Language bird document.

If the article is helpful to you, you are welcome to like, comment, collect and forward. If you have questions and doubts, you can also leave a message in the comment area. I will reply to you at the first time. If you think there is something wrong in my article, please tell me. Understanding the wrong things in pairs is fatal in any industry.

Loop in JavaScript

  1. for
  2. for...of
  3. for...in
  4. for await...of
  5. forEach cannot be classified as such
  6. while
  7. do...while

First create the basic data, and the full text is universal.

const string='12345'

const array = [1, 2, 3, 4, 5]

const uint8Array=new Uint8Array([0, 1, 2, 3])

const searchParams = new URLSearchParams("key1=value1&key2=value2");

const obj = {
    'obj0': 1,
    'obj1': 2,
    'obj2': 3,
    'obj3': 4,
    'obj4': 5
}

const obj2 = Object.defineProperties({
    'obj0': 1
}, {
    'obj1': {
        value: 2,
        enumerable: true
    },
    'obj2': {
        value: 3,
        enumerable: true
    },
    'obj3': {
        value: 4,
        enumerable: false
    },
});
obj2.__proto__.obj4=5

const map = new Map([[0,1],[1,2],[2,3],[3,4],[4,5]])
const set = new Set([1,2,3,4,5])

for

Pure for is the most basic circular statement in JavaScript

for (let i = 0; i < array.length; i++) {
    console.log(map.get(i)); //Cycle output 1 2 3 4 5
}

You should know that the three expressions of for are optional, that is, let I = 0 above; i < array. length; I + +, however, although the expression is optional, there are three; It's mandatory.

for (let i = 0,j=0; ; i++,j++) {
    //If he doesn't stop here, he will gg
    if (i > array.length) break;
    console.log(i,j);
}
// 0 0
// 1 1
// 2 2
// 3 3
// 4 4
// 5 5

If you need to, you can even declare a for loop without a statement, which is OK.

let j=[]
for (let i = 0; i < array.length; i++,j.push(i)); //This semicolon cannot be less
console.log(j) //[ 1, 2, 3, 4, 5 ]

for...of

for... The of statement loops iteratable objects (including Array, Map, Set, String, TypedArray, arguments objects, etc.), and the value of the object looped out.

for (const element of array) {
  console.log(element);//Cycle output 1 2 3 4 5
}

Note here that ordinary object objects are not Iteratable object , cannot use for of,

for (let element of obj) {
    console.log(element); // TypeError: obj is not iterable
}

You can even loop strings

for (let element of string) {
    console.log(element); //Cycle output 1 2 3 4 5
}

You can also cycle Map and Set

for (let element of map) {
      //It's an array
    console.log(element[0],element[1]);
    // 0 1
    // 1 2
    // 2 3
    // 3 4
    // 4 5
}

for (let element of set) {
    console.log(element); //Cycle output 1 2 3 4 5
}

For for Of can be terminated by break, throw, continue and return.

for (let element of set) {
    if(element>3) break
    console.log(element); //Cycle output 1 2 3
}

For ordinary object s that are not supported, we can create an iterator for them, which can also implement for Of loop.

obj[Symbol.iterator] = function*(){
    var keys = Object.keys(obj);
    for(var key of keys){
        yield [key,obj[key]]
    }
};

for(var [key,value] of obj){
    console.log(key,value);
    // obj0 1
    // obj1 2
    // obj2 3
    // obj3 4
    // obj4 5
}

Can also use Object.entries Implement traversal, object The entries () method returns an array of key value pairs of enumerable properties of a given object.

for (const [key, value] of Object.entries(obj2)) {
    console.log(`${key}: ${value}`);
    //obj0: 1
    //obj1: 2
    //obj2: 3
}

There are other iteratable objects that can use for Of, not one by one.

for...in

for... The in statement traverses the enumerable properties of an object other than Symbol in any order, including the inherited enumerable properties. Note: the statement cannot guarantee the traversal order (there are some differences between browsers. You can also learn about the general properties and sorting properties).

for (let prop in obj) {
    console.log(prop + " = " + obj[prop]);
    // obj0 = 1
    // obj1 = 2
    // obj2 = 3
    // obj3 = 4
    // obj4 = 5
}

Only iteratable attributes will be traversed. The enumerable of obj2['obj3 '] is false. All attributes have not been traversed. obj2['obj4'] is an inherited attribute (_proto__ above) and can be traversed.

for (let prop in obj2) {
    console.log(prop + " = " + obj2[prop]);
    // obj0 = 1
    // obj1 = 2
    // obj2 = 3
    // obj4 = 5
}

If you only need your own attributes, you can use hasOwnProperty judge

for (let prop in obj2) {
    if (obj2.hasOwnProperty(prop)) {
        console.log(prop + " = " + obj[prop]);
    }
    // obj0 = 1
    // obj1 = 2
    // obj2 = 3
}

for await...of

And for Fo, but it only applies to asynchronous iterators that are asynchronous and iteratable.

function getRes(){
   return  fetch('http://whois.pconline.com.cn/ip.jsp')
        .then(response => 'res')
}

async function test(){
    let i=0
    let arr = [getRes(),getRes(),getRes()]
    for await (let x of arr){
        i++
        console.log(x+'---'+i); //Cycle out res---1 res---2 res---3 in sequence
    }
}

test()

The asynchronous generator has implemented the asynchronous iterator protocol, so you can use for await Of loop.

async function* asyncGenerator() {
    let i = 0;
    while (i < 3) {
        yield i++;
    }
}

async function test(){
    for await (num of asyncGenerator()) {
        if (num>1) break; //You can also use break to abort, completely and for Of same
        console.log(num); //Loop out 0 in order 
    }
}

test()

while

while statement can execute a specified piece of code in a loop on the premise that a conditional expression is true until the expression is not true.

let n=0
while (n < array.length) {
    console.log(array[n]); //Cycle output 1 2 3 4 5 
    n++;
}

do...while

do...while statementcreates a loop that executes the specified statement until the condition value is false. After the code in do is executed, the conditions in while are detected, so the code in do will be executed at least once.

let n=0

do {
    console.log(array[n]); //Cycle output 1 2 3 4 5 
    n++;
}while (n < array.length)
  
  
do {
    console.log(array[n]); //1 will cycle at least once
    n++;
}while (n < 0)

forEach

In JavaScript, there are forEach methods for Array, Map, Set, NodeList, TypedArray and URLSearchParams. The given function is executed once for each element of the above types without return value. Except URLSearchParams, there is the second thisArg optional parameter in Map prototype. Examples are available in forEach.

Map.prototype.forEach

map.forEach((value,key,myMap)=>{
    console.log(`${key}-${value}-${myMap.get(key)}`)
    // 0-1-1
    // 1-2-2
    // 2-3-3
    // 3-4-4
    // 4-5-5
})

//The second parameter, which will not be exemplified later in this article, cannot use the arrow function here
//If an arrow function expression is used to pass in a function parameter, the thisArg parameter will be ignored because the arrow function is lexically bound to the this value.
map.forEach(function(value,key,myMap){
    console.log(`${key}-${value}-${myMap.get(key)}-${this.exp}`)
    // 0-1-1-exp
    // 1-2-2-exp
    // 2-3-3-exp
    // 3-4-4-exp
    // 4-5-5-exp
},{exp:'exp'})

Array.prototype.forEach

  1. The forEach method executes the callback function once for each item with valid value in the array in ascending order;
  2. forEach does not change the original array, but can be modified by callback;
  3. forEach cannot be called chained;
  4. The scope of forEach traversal will be determined before calling callback for the first time;
  5. There is no way to abort or jump out of a forEach loop except by throwing an exception;
  6. If the existing value is changed, callback gets the latest value;
  7. Items added to the array after calling forEach will not be accessed by callback;
  8. Deleted items are not traversed. If the accessed element is deleted during the iteration (for example, using shift), the subsequent element will be skipped.
array.forEach((currentValue, index ,myArray)=> {
    console.log(`${currentValue}-${index}-${myArray[index]}`);
    // 1-0-1
    // 2-1-2
    // 3-2-3
    // 4-3-4
    // 5-4-5
});

The scope of forEach traversal will be determined before the first call to callback. Items added to the array after calling forEach will not be accessed by callback. If the existing value is changed, the value passed to the callback is the value of forEach (traversing to their moment). The deleted items will not be traversed. If the accessed elements are deleted during the iteration (for example, using shift), the subsequent elements will be skipped.

array.forEach((currentValue) => {
    if (currentValue === 1) {
        //If the existing value is changed, the value passed to callback is the value at the moment when forEach() traverses them
        array[4] = 666  
        //The scope of forEach traversal will be determined before the first call to callback
        array.push(777) 
    }
    console.log(currentValue)
    // 1 2 3 4 666
});

array.forEach((currentValue) => {
    if (currentValue === 1) {
        array.shift();
    }
    //When the execution reaches 1, the currentValue is already 1, so you can print it and delete the first array, resulting in
    //All arrays go back one step [2,3,4,5], but at this time, the index is already 1, so 2 printing 3,4,5 is skipped
    console.log(currentValue)
    // 1
    // 3
    // 4
    // 5
});

There is no way to abort or jump out of a forEach() loop except by throwing an exception

array.forEach((currentValue)=> {
    if(currentValue>3) break; // Uncaught SyntaxError: Illegal break statement
    console.log(currentValue)
});

Flattening arrays can be seen in my article

Set.prototype.forEach

set.forEach((value,mySet)=>{
    console.log(`${value}-${mySet}`)
    // 1-1
    // 2-2
    // 3-3
    // 4-4
    // 5-5
})

NodeList.prototype.forEach

let node = document.createElement("div");
let kid1 = document.createElement("p");
let kid2 = document.createTextNode("hey");
let kid3 = document.createElement("span");

node.appendChild(kid1);
node.appendChild(kid2);
node.appendChild(kid3);

let list = node.childNodes;

list.forEach((currentValue, currentIndex, listObj) => {
        console.log(`${currentValue}-${currentIndex}-${listObj[currentIndex]}`)
       // [object HTMLParagraphElement]-0-[object HTMLParagraphElement]
        // [object Text]-1- [object Text]
        // [object HTMLSpanElement]-2- [object HTMLSpanElement]
    }
);

TypedArray.prototype.forEach

TypedArray A typed array

uint8Array.forEach((element, index, array)=>{
    console.log(`${element}-${index}-${array[index]}`)
    // 0-0-0
    // 1-1-1
    // 2-2-2
    // 3-3-3
});

URLSearchParams.forEach

searchParams.forEach((value, key,searchParams)=> {
    console.log(value, key,searchParams.get(key));
    // value1 key1 value1
    // value2 key2 value2
});

for...of and for In similarities and differences

  1. Same point

    • for...in and for Of statements are loop (iterative) things;
    • break,continue and return can interrupt traversal.
  2. difference

    • for...in statement traverses the enumerable attributes of an object other than Symbol in any order, including inherited enumerable attributes. Note: the traversal order cannot be guaranteed by the statement;
    • for... The in iteration is the key of the object, and for Of is the value corresponding to the key of the iteration object;
    • for...in can iterate over any object, but for Of requires that the object be an iteratable object;;

do... Similarities and differences between while and while

Same point: they are all circular statements
Difference: do While will loop at least once

break,continue and return in JavaScript

return

Return statementterminates the execution of a function (return is a function return statement, but it also stops the function when it is returned), and returns a specified value to the function caller. If it is ignored, it returns undefined.

array.forEach is a method inside f(), in array Return in foreach is different from return in f() method.

// in function
function f() {
    array.forEach((item)=>{
        console.log(item) // return invalid. Continuous printing 1 2 3 4 5
        return item+1     //array.forEach has no return value
    })
    console.log(2) //Print 2
}

console.log(f()) //undefined

//At global scope
array.forEach((item)=>{
    console.log(item)
    return item+1  // return invalid. Continuous printing 1 2 3 4 5
})
 console.log(3) //Print 3

Use for inside a function or global scope In, return can normally interrupt for In statement execution

// in function
function f() {
     for (const objElement in array) {
         console.log(array[objElement]) //1
         return array[objElement]
     }
       console.log(2) //Unable to print, function execution aborted
}

console.log(f()) //1

// At global scope
for (const objElement in array) {
    console.log(array[objElement]) //1
    return array[objElement]
}
console.log(3) //Unable to print, aborted

Use for inside a function or global scope Of, return can normally interrupt for Of statement execution

// in function
function f() {
     for (const objElement of array) {
         console.log(objElement) //1
         return objElement
     }
     console.log(2) //Unable to print, function execution aborted
}

console.log(f()) //1

// At global scope
for (const objElement of array) {
    console.log(objElement) //1
    return objElement
}
console.log(3) //Unable to print, aborted

Use for within the function or global scope, and return can interrupt the execution of the for statement normally

// in function
function f() {
    for (let i = 0; i < array.length; i++) {
        console.log(array[i]) // 1
        return array[i]
    }
      console.log(2) //Unable to print, function execution aborted
}

console.log(f()) //1

// At global scope
for (let i = 0; i < array.length; i++) {
    console.log(array[i]) // Inconsistent node environment and v8 performance
    return array[i]
}
console.log(3) //Unable to print, execution aborted 

Using while and do within a function or global scope While, return can interrupt while and do normally While statement execution

// in function
function f() {
    let n=0
    while (n < array.length) {
        n++;
        if (n === 3) {
            return 'f';
        }
        console.log(n) // 1 2
    }
    console.log(2) //2
}

console.log(f()) //f

//At global scope
let n=0

while (n < array.length) {
    n++;
    if (n === 3) {
        return 'f'; // Illegal return statement
    }
    console.log(n) 
}
console.log(3) 

Summary:

  1. Return will stop the statement at this time, but return is more suitable for function statements;
  2. The forEach method cannot be interrupted except throwing an exception. forEach will not be exemplified later in this section.

break

break statement stops the current loop, switch statement or label statement (label statement, a special article will be written later), and transfers the program control to the statement immediately after the suspended statement.

Use for inside a function or global scope In, break can normally interrupt the current cycle, but will not prevent the execution of subsequent programs.

// in function
function f() {
    for (const objElement in array) {
        console.log(array[objElement]) //1
        break
    }
    console.log(2) //2
}
//
console.log(f()) //undefined

// //At global scope
for (const objElement in array) {
    console.log(array[objElement]) //1
    break
}
console.log(3) //3

Use for inside a function or global scope Of, break can normally interrupt the current loop, but will not prevent the execution of subsequent programs.

// in function
function f() {
    for (const objElement of array) {
        console.log(objElement) //1
        break
    }
    console.log(2) //2
}
//
console.log(f()) //undefined

// //At global scope
for (const objElement of array) {
    console.log(objElement) //1
    break
}
console.log(3) //3

Using for break inside a function or in the global scope can normally interrupt the current loop, but it will not prevent the execution of subsequent programs.

// in function
function f() {
    for (let i = 0; i < array.length; i++) {
        console.log(array[i]) // 1
        break;
    }
    console.log(2) //2
}
//
console.log(f()) //undefined

// //At global scope
for (let i = 0; i < array.length; i++) {
    console.log(array[i]) // 1
    break;
}
console.log(3) //3

Using while and do within a function or global scope While and break can normally interrupt the current loop, but will not prevent the execution of subsequent programs.

// in function
function f() {
    let n=0
    while (n < array.length) {
        n++;
        if (n === 3) {
            break;
        }
        console.log(n) // 1 2
    }
    console.log(2) //2
}

console.log(f()) //undefined

//At global scope
let n=0

while (n < array.length) {
    n++;
    if (n === 3) {
        break;
    }
    console.log(n) // 1 2
}
console.log(3) //3

Summary: break terminates the current loop, but does not prevent subsequent program execution;

continue

Continue skip this cycle and continue to the next cycle.

// in function
function f() {
    for (let i = 0; i < array.length; i++) {
        if(array[i] === 1) continue;
        console.log(array[i]) // 2 3 4 5
    }
    console.log(2) //2
}

console.log(f()) //undefined

//At global scope
for (let i = 0; i < array.length; i++) {
    if(array[i] === 1) continue;
    console.log(array[i]) // 2 3 4 5

}
console.log(3) //3

Use for inside a function or global scope In, continue can skip this cycle normally and continue the next cycle.

// in function
function f() {
    for (const objElement in array) {
        if(array[objElement] === 1) continue;
        console.log(array[objElement]) // 2 3 4 5
    }
    console.log(2) //2
}

console.log(f()) //undefined

//At global scope
for (const objElement in array) {
    if(array[objElement] === 1) continue;
    console.log(array[objElement]) // 2 3 4 5
}
console.log(3) //3

Use for inside a function or global scope Of, continue normally skip this cycle and continue to the next cycle.

// in function
function f() {
    for (const objElement of array) {
        if(objElement === 1) continue;
        console.log(objElement) // 2 3 4 5
    }
    console.log(2) //2
}

console.log(f()) //undefined

//At global scope
for (const objElement of array) {
    if(objElement === 1) continue;
    console.log(objElement) // 2 3 4 5
}
console.log(3) //3

Using while and do within a function or global scope While, continue skip this cycle and continue to the next cycle.

// in function
function f() {
    let n=0
    while (n < array.length) {
        n++;
        if (n === 3) {
            continue;
        }
        console.log(n) // 1 2 4 5
    }
    console.log(2) //2
}

console.log(f()) //undefined

//At global scope
let n=0

while (n < array.length) {
    n++;
    if (n === 3) {
        continue;
    }
    console.log(n) // 1 2 4 5
}
console.log(3) //3

Summary: continue is used to skip this cycle and continue the next cycle.

summary

  1. forEach cannot be interrupted unless an exception is thrown;
  2. All three will stop / skip the statements at this time;
  3. break interrupts the current loop, but does not prevent subsequent program execution;
  4. Continue skip this cycle and continue the next cycle;
  5. Return is a function return statement, but the return also stops the function;
  6. The statement environment used is different. break and continue are used in loop or switch statements, and return is used in function statements.

quote

First published in YuQue document @ is_tao
MDN
How to use break,continue and return in js?

Topics: Javascript Front-end Interview