Make writing a habit together! This is the fourth day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.

For performs the fastest of the traversal methods, without any additional function call stack or context. In practice, however, we have to choose which solution to use based on semantics, readability, and program performance. For, foreach, map,for… in , for… Five ways to live battle.

To introduce myself

for

I was one of the earliest iteration statements, and everyone here needs to call me grandpa. I can meet most of the needs of developers.

// let arr = [1,2,3]; for(let i = 0; i < arr.length; I ++){console.log(I) Console. log(arr[I]) let profile = {name:"April",nickname:" 27 ",country:"China"}; for(let i = 0, keys=Object.keys(profile); i < keys.length; I ++){console.log(keys[I]) // console.log(profile[keys[I]]) // / the key of the object corresponding to the value} // let STR = "abcdef"; for(let i = 0; i < str.length ; I ++){console.log(I) // index string subscript console.log(STR [I]) // the element corresponding to the string subscript document.querySelectorAll('.article > p'); for(let i = 0; i<articleParagraphs.length; i++){ articleParagraphs[i].classList.add("paragraph"); // Add a paragraph class attribute to the p tag under the class node named "article"}Copy the code

forEach

I’m an ES5 release. Callback is executed for each valid item in the array in ascending order, and deleted or uninitialized items are skipped (for example, on a sparse array). I’m an enhanced version of the for loop.

// let arr = [1,2,3]; Arr. ForEach (I => console.log(I)) // logs 1 // logs 2 // logs 3 // directly outputs the elements of array // traverses the object let profile = {name:"April",nickname:" 28 ",country:"China"}; let keys = Object.keys(profile); ForEach (I => {console.log(I) // console.log(profile[I]) // the key of the object})Copy the code

map

I’m also an ES5 release, and I can create a new array, the result of which is the return value of each element in the original array after calling the supplied function once.

Let arr = [1, 2, 3, 4, 5]; let res = arr.map(i => i * i); console.log(res) // logs [1, 4, 9, 16, 25]Copy the code

for… In the enumeration

I’m an ES5 release. Iterate through the enumerable properties of an object except Symbol in any order.

Let profile = {name:"April",nickname:" 27 ",country:"China"}; for(let i in profile){ let item = profile[i]; Console. log(I) console.log(I) console.log(I) console.log(I) console.log(I) let arr = ['a','b','c']; for(let i in arr){ let item = arr[i]; Console. log(item) // Array subscript element console.log(I) // index, Let STR = "abcd" for(let I in STR){let item = STR [I]; Console. log(item) // The element corresponding to the subscript of the string console.log(I) // Index string subscript}Copy the code

for… Of the iteration

I’m an ES6 release. Create an iteration loop on iterable objects (including Array, Map, Set, String, TypedArray, Arguments, and so on), call custom iteration hooks, and execute statements for the values of each different property.

Let arr = ['a','b','c']; For (let item of arr){console.log(item)} // logs 'a' // logs 'b' // logs 'c' // iterated string let STR = "ABC "; for (let value of str) { console.log(value); } / / logs' a '/ / logs' b' / / logs' c '/ / iterative map let iterable = new map ([[" a ", 1], [" b ", 2], [" c ", 3]] for (let entry of iterable) { console.log(entry); } / / logs (" a ", 1) / / logs / / logs (" b ", 2] [" c ", 3] / / iterative map access keys for (let [key, value] of iterable) { console.log(key) console.log(value); } // set let iterable = new set ([1, 1, 2, 2, 3, 3,4]); for (let value of iterable) { console.log(value); } / / logs / 1/2 / logs/logs / 3/4 / logs/iteration DOM node let articleParagraphs = document. QuerySelectorAll ('. The article > p'); for (let paragraph of articleParagraphs) { paragraph.classList.add("paragraph"); // Add a class attribute named "paragraph" to the p tag under the class named "article" node. Function () {for (let argument of arguments) {console.log(argument); }}) (1, 2, 3); // 1 // 2 // 3 // let typeArr = new Uint8Array([0x00, 0xff]); for (let value of typeArr) { console.log(value); } // logs: // 0 // 255Copy the code

After the first round of self-introduction and skills demonstration, we learned:

  • The for statement is the original looping statement. Define a variable I (a numeric type representing the subscript of an array) and loop over I, subject to certain conditions. The condition is usually the length of the loop object, and the loop is stopped when the length is exceeded. Keys () is used with object.keys () because the Object cannot determine the length.
  • ForEach ES5 proposed. It claims to be an enhanced version of the for statement, which is much simpler to write than the for statement. But it’s essentially a loop of an array. ForEach executes the callback function once forEach array element. That’s the array that’s calling it, so it doesn’t change the original array. The return value is undefine.
  • Map ES5 is presented. The callback function is called once for each element in the array, in order. Generates a new array without modifying the original array itself. The return value is a new array.
  • for… In ES5. Iterate over enumerable properties on an object, including properties on the prototype object, in any order, i.e., in an unfixed order. I is a string when you iterate over an array using the subscript as the key. It is built to iterate over object properties and is not recommended for use with arrays.
  • for… Of ES6 proposed. Only iterate over the iterable’s data.

Ability to identify

As a programmer, it’s not enough just to get to know them, to identify their strengths and weaknesses in actual development. Use them according to local conditions. Improving the overall performance of the program is where the power lies.

About jumping out of the loop

When certain conditions are met in a loop, it jumps out of the loop body, or it skips data that does not meet the conditions and continues to loop other data. It’s a common requirement. Common statements are break and continue.

Say the distinction of both simply, had reviewed with respect to.

  • The break statement breaks out of the current loop and executes after the current loop.
  • The continue statement terminates the current loop and continues with the next loop;

Note: forEach and Map do not support breaking out of the loop body. The other three methods do.

How it works: Look at how forEach works to understand this problem.

Array.prototype. ForEach (callbackfn [, thisArg]{}Copy the code

Function passed in is the callback function here. It is definitely illegal to use break inside a callback, because break can only be used to break out of a loop, and the callback is not the body of the loop.

Using a return in a callback function simply returns the result to the parent function, the for loop, and does not end the for loop, so return is also invalid.

The map () in the same way.

Map () chain call

The map() method is chain-callable, which means it can be easily used in conjunction with other methods. For example, reduce(), sort(), filter(). But there are no other ways to do this. ForEach () returns undefined, so it cannot be chained.

// Multiply the element by itself and sum. let arr = [1, 2, 3, 4, 5]; let res1 = arr.map(item => item * item).reduce((total, value) => total + value); console.log(res1) // logs 55 undefined"Copy the code

for… In iterates through the properties on the prototype object

Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
var arr = ['a', 'b', 'c'];
arr.foo = 'hello
for (var i in arr) {
    console.log(i);
}
// logs
// 0
// 1
// 2
// foo
// arrCustom
// objCustom
Copy the code

In real development, however, we do not need properties on the prototype object. In this case we can use the hasOwnProperty() method, which returns a Boolean value indicating whether the object has the specified property in its own properties (that is, whether it has the specified key). As follows:

Object.prototype.objCustom = function() {}; Array.prototype.arrCustom = function() {}; var arr = ['a', 'b', 'c']; arr.foo = 'hello for (var i in arr) { if (arr.hasOwnProperty(i)) { console.log(i); }} // logs // 0 // 1 // 2 // foo // Can't get rid of the properties of the visible array itself. ForEach is recommendedCopy the code

For traversal of pure objects, select for.. In enumeration is more convenient; For array traversal, if you don’t need to know the index for.. An of iteration is more appropriate because it can also be broken; If you need to know the index, forEach() is more appropriate; For other strings, class array, type array iteration, for.. Be in the upper hand But note that older browsers are about compatibility.

performance

Interested readers can find a set of data to test their own, the article will directly give the results, and do the corresponding explanation.

for > for-of > forEach > map > for-in
Copy the code
  • The for loop is of course the simplest, because it doesn’t have any additional function call stacks and contexts;
  • for… Of can be used to iterate over members of any data structure that has an Iterator interface. It reads the key directly.
  • ForEach, because it’s actually a little bit more complicated than we thought, it’s actually array.forEach(function(currentValue, index, arr), thisValue) it’s not just a syntactical sugar for a normal for loop, There are also many parameters and contexts that need to be taken into account during execution, which can be slow;
  • Map () is the slowest because its return value is a brand new array of equal length, and array creation and assignment incur significant performance overhead.
  • for… In enumerates all attributes of the object, including custom added attributes that can be traversed. And for… The key of in is of String type, which requires conversion and high overhead.

conclusion

In actual development, we need to combine semantics, readability, and program performance to choose which solution to use.

If you need to map an array to another array according to some rule, you should use a map.

If you need to do simple traversal, use forEach or for of.

If you need to iterate over an iterator, use for of.

If you need to filter out items that match the criteria, use Filterr.

If you need to map to a new array by rules and then filter by criteria, use a map and a filter.

In short, according to local conditions, according to the time. Don’t let performance get in the way of semantics and readability. Under your rule, the five of them can only play to their strengths, no one can dominate.

– End –