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
- for
- for...of
- for...in
- for await...of
- forEach cannot be classified as such
- while
- 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
- The forEach method executes the callback function once for each item with valid value in the array in ascending order;
- forEach does not change the original array, but can be modified by callback;
- forEach cannot be called chained;
- The scope of forEach traversal will be determined before calling callback for the first time;
- There is no way to abort or jump out of a forEach loop except by throwing an exception;
- If the existing value is changed, callback gets the latest value;
- Items added to the array after calling forEach will not be accessed by callback;
- 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
Same point
- for...in and for Of statements are loop (iterative) things;
- break,continue and return can interrupt traversal.
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:
- Return will stop the statement at this time, but return is more suitable for function statements;
- 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
- forEach cannot be interrupted unless an exception is thrown;
- All three will stop / skip the statements at this time;
- break interrupts the current loop, but does not prevent subsequent program execution;
- Continue skip this cycle and continue the next cycle;
- Return is a function return statement, but the return also stops the function;
- 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?