This is the 100th unwatered original, want to get more original good articles, please search the public number to pay attention to us ~ this article first in the political cloud front blog: JS commonly used loop traversal you will be several

preface

As one of the most basic data structures, arrays and objects play a crucial role in all kinds of programming languages. It’s hard to imagine a programming language without arrays and objects. In particular, JS, a weakly typed language, is very flexible. This article walks you through the common array traversal, object traversal use comparison and precautions.

Array traversal

As JS continues to evolve, the ES7 specification has more than a dozen traversal methods. The following is a set of similar methods to describe the common array traversal methods.

For, forEach,for … of

const list = [1.2.3.4.5.6.7.8.10.11];

for (let i = 0, len = list.length; i < len; i++) {
  if (list[i] === 5) {
    break; // 1, 2, 3, 4
    // continue; // 1 2 3 4 6 7 8 undefined 10 11
  }
  console.log(list[i]);
}

for (const item of list) {
  if (item === 5) {
    break; // 1, 2, 3, 4
    // continue; // 1 2 3 4 6 7 8 undefined 10 11
  }
  console.log(item);
}

list.forEach((item, index, arr) = > {
  if (item === 5) return;
  console.log(index); // 0 1 2 3 5 6 7 9 10
  console.log(item); // 1 2 3 4 6 7 8 10 11
});
Copy the code

summary

  • All three are basic left-to-right traversal sets
  • ForEach cannot break out of the loop; The for and the for… Of can be skipped or interrupted using break or continue.
  • for … Of accesses the actual element directly. For iterates over a set of indexes, and forEach is more verbose. The element, index, and array can all be retrieved.
  • for … Of and for are also executed if there are empty elements in the array.

Some, every

const list = [
  { name: 'Head navigation'.backward: false },
  { name: '轮播'.backward: true },
  { name: 'footer'.backward: false},];const someBackward = list.some(item= > item.backward);
// someBackward: true
const everyNewest = list.every(item= >! item.backward);// everyNewest: false
Copy the code

summary

  • Both are used to make array conditions, and both return a Boolean value
  • Both can be interrupted
  • Some returns true if an element satisfies a condition, and the loop breaks; Return false if all elements do not meet the condition.
  • Every is the opposite of some. If the beneficial element does not satisfy the condition, false is returned and the loop breaks. Return true if all elements satisfy the condition.

The filter, the map

const list = [
{ name: 'Head navigation'.type: 'nav'.id: 1}, {name: '轮播'.type: 'content'.id: 2 },
{ name: 'footer'.type: 'nav'.id: 3},];const resultList = list.filter(item= > {
  console.log(item);
  return item.type === 'nav';
});
// resultList: [
// {name: 'nav', type: 'nav', id: 1},
// {name: 'footer ', type: 'nav', id: 3},
// ]

const newList = list.map(item= > {
  console.log(item);
  return item.id;
});
// newList: [1, empty, 2, 3]

// list: [
// {name: 'nav', type: 'nav', id: 1},
// empty,
// {name: 'content', type: 'content', id: 2},
// {name: 'footer ', type: 'nav', id: 3},
// ]
Copy the code

summary

  • Both generate a new array and do not change the array (except for iterating over an array of objects and manipulating an element object in a callback).
  • Both skip empty elements. Those of you who are interested can print it yourself
  • Map forms the return values of the callback into a new array of the same length as the original array.
  • Filter forms a new array of elements that match the callback condition, with a different length than the original array.
  • The new array elements generated by the map are customizable.
  • The new array elements generated by filter cannot be customized and are consistent with the corresponding original array elements.

The find, findIndex

const list = [
{ name: 'Head navigation'.id: 1 },
{ name: '轮播'.id: 2 },
{ name: 'footer'.id: 3},];const result = list.find((item) = > item.id === 3);
// result: {name: 'footer ', id: 3}
result.name = 'Bottom navigation';
// list: [
// {name: 'header ', id: 1},
//   { name: '轮播', id: 2 },
// {name: 'bottom navigation ', id: 3},
// ]

const index = list.findIndex((item) = > item.id === 3);
// index: 2
list[index].name // 'bottom navigation ';
Copy the code

summary

  • Both are used to find array elements.
  • The find method returns the value of the first element in the array that satisfies callback. Return undefined if none exists.
  • FindIndex It returns the index of the element found in the array, not its value, or -1 if none exists.

Reduce, reduceRight

The reduce method takes two arguments, the first a callback and the second an initialValue.

ReduceRight method in addition to reduce execution direction opposite (from right to left), other completely consistent with it.

The callback function takes four arguments:

  • Accumulator is an accumulator of all the elements up to the current element. The accumulator is an accumulator of all the elements in the array.
  • Current: The array element currently being executed.
  • CurrentIndex: indicates the index of the array element currently being executed.
  • SourceArray: The original array, that is, the array of calls to reduce methods.

If no initial value is passed in, the Reduce method executes the callback function starting at index 1. If an initial value is passed in, the callback starts at index 0 and accumulates from the initial value.

Calculates the sum of a property in an array of objects
const list  = [
  { name: 'left'.width: 20 },
  { name: 'center'.width: 70 },
  { name: 'right'.width: 10},];const total = list.reduce((currentTotal, item) = > {
  return currentTotal + item.width;
}, 0);
// total: 100
Copy the code
Object array, and count the number of repeats for each item
const list  = [
  { name: 'left'.width: 20 },
  { name: 'right'.width: 10 },
  { name: 'center'.width: 70 },
  { name: 'right'.width: 10 },
  { name: 'left'.width: 20 },
  { name: 'right'.width: 10},];const repeatTime = {};
const result = list.reduce((array, item) = > {
  if (repeatTime[item.name]) {
    repeatTime[item.name]++;
    return array;
  }
  repeatTime[item.name] = 1;
  return[...array, item]; } []);// repeatTime: { left: 2, right: 3, center: 1 }
// result: [
// { name: 'left', width: 20 },
// { name: 'right', width: 10 },
// { name: 'center', width: 70 },
// ]
Copy the code
Object array maximum/minimum value
const list  = [
  { name: 'left'.width: 20 },
  { name: 'right'.width: 30 },
  { name: 'center'.width: 70 },
  { name: 'top'.width: 40 },
  { name: 'bottom'.width: 20},];const max = list.reduce((curItem, item) = > {
  return curItem.width >= item.width ? curItem : item;
});
const min = list.reduce((curItem, item) = > {
  return curItem.width <= item.width ? curItem : item;
});
// max: { name: "center", width: 70 }
// min: { name: "left", width: 20 }
Copy the code

Reduce is powerful. For more tricks and tricks, check out the 25 Things You Need to Know about The Advanced Uses of Array Reduce.

The performance comparison

Having said that, what’s the performance difference between these traversal methods? We tried it in Chrome. I used each cycle to execute 10 times, remove the maximum and minimum values and take the average to reduce the error.

var list = Array(100000).fill(1)

console.time('for');
for (let index = 0, len = list.length; index < len; index++) {
}
console.timeEnd('for');
/ / for: 2.427642822265625 ms

console.time('every');
list.every(() = > { return true })
console.timeEnd('every')
/ / some: 2.751708984375 ms

console.time('some');
list.some(() = > { return false })
console.timeEnd('some')
/ / some: 2.786590576171875 ms

console.time('foreach');
list.forEach(() = > {})
console.timeEnd('foreach');
/ / foreach: 3.126708984375 ms

console.time('map');
list.map(() = > {})
console.timeEnd('map');
/ / the map: 3.743743896484375 ms

console.time('forof');
for (let index of list) {
}
console.timeEnd('forof')
/ / forof: 6.33380126953125 ms
Copy the code

As you can see from the print, the for loop is the fastest and the for of loop the slowest

Commonly used termination of traversal, performance table comparison

Terminable or not
* * * * break continue return Performance (MS)
for Terminate ✅ Jump out of this loop ✅ 2.42
forEach 3.12
map 3.74
for of Terminate ✅ Jump out of this loop ✅ 6.33
some Return true ✅ 2.78
every Return false ✅ 2.75

Finally, the kernel of different browsers will also have some differences, interested students can also try.

Object traversal

In object traversal, it is often necessary to traverse the key and value of an object. ES5 provides for… In is used for traversing objects, but it involves the “enumerable properties” of Object properties, prototype chain properties, etc. The following will explore various methods of traversing objects from the nature of Object objects, and distinguish some characteristics of common methods.

for in

Object.prototype.fun = () = > {};const obj = { 2: 'a'.1: 'b' };for (const i in obj) {  console.log(i, ':', obj[i]); }// 1: b// 2: a// fun : () = > {} Object on the prototype chain extension method also be traversed out for (const I in obj) {if (Object. The prototype. The hasOwnProperty. Call (obj, i)) { console.log(i, ':', obj[i]); }}// name: a attributes that do not belong to itself will be filtered by hasOwnProperty
Copy the code

summary

When you use the for in loop, you return all the enumerable properties that can be accessed through the object, including both the properties that exist in the instance and the instance that exists in the stereotype. If you only need to get the instance properties of an object, use hasOwnProperty for filtering.

Use (const x in a) instead of (x in a), which would create a global variable.

For the order of loops for in, see the JavaScript Authority Guide (7th edition) 6.6.1.

  • List string attributes with non-negative integer names in numerical order from smallest to largest. This rule means that the properties of arrays and array-like objects are enumerated in the order in which they are enumerated.
  • After listing all the properties of the class array index, list all the properties of the remaining string names (including names that look like integer negative numbers or floating point numbers). These properties are listed in the order in which they were added to the object. Properties defined in object literals are listed in the order in which they appear in the literal.
  • Finally, the properties named symbolic objects are listed in the order in which they were added to the object.

Object.keys

Object.prototype.fun = () = > {};const str = 'ab';console.log(Object.keys(str));// ['0', '1']const arr = ['a', 'b']; console.log(Object.keys(arr)); // ['0', '1']const obj = { 1: 'b', 0: 'a' }; console.log(Object.keys(obj)); / / / '0', '1'
Copy the code

summary

Gets all the enumerable property values of the object itself, except the properties in the stereotype, and returns an array of property names.

Object.values

Object.prototype.fun = () = > {};const str = 'ab';console.log(Object.values(str));// ['a', 'b']const arr = ['a', 'b']; console.log(Object.values(arr)); // ['a', 'b']const obj = { 1: 'b', 0: 'a' }; console.log(Object.values(obj)); // ['a', 'b']
Copy the code

summary

Gets all the enumerable property values of the object itself, except the properties in the stereotype, and returns an array of property values.

Object.entries

const str = 'ab';for (const [key, value] of Object.entries(str)) {    console.log(`${key}: ${value}`); }// 0: a// 1: bconst arr = ['a', 'b']; for (const [key, value] of Object.entries(arr)) { console.log(`${key}: ${value}`); }// 0: a// 1: bconst obj = { 1: 'b', 0: 'a' }; for (const [key, value] of Object.entries(obj)) { console.log(`${key}: ${value}`); }// 0: a// 1: b
Copy the code

summary

Gets the enumerable values of all the properties of the object itself, except those in the stereotype, and returns a two-dimensional array. Each subarray consists of an object’s property name and property value. A method that can get both the property name and the property value.

Object.getOwnPropertyNames

Object.prototype.fun = () = > {};Array.prototype.fun = () = > {};const str = 'ab';console.log(Object.getOwnPropertyNames(str));// ['0', '1', 'length']const arr = ['a', 'b']; console.log(Object.getOwnPropertyNames(arr)); // ['0', '1', 'length']const obj = { 1: 'b', 0: 'a' }; console.log(Object.getOwnPropertyNames(obj)); / / / '0', '1'
Copy the code

summary

Gets all the enumerable property values of the object itself, except the properties in the stereotype, and returns an array of property names.

conclusion

We have compared the differences between several common traversal methods, and with that in mind, we need to think about which method is most appropriate when using it. Everyone is welcome to correct and add.

Recommended reading

Let’s talk about Deno

H5 Page list caching scheme

Open source works

  • Politics in front of tabloids

Open source address www.zoo.team/openweekly/ (there is a wechat group on the homepage of the official website of the tabloid)

, recruiting

ZooTeam (ZooTeam), a young and creative team, belongs to the product RESEARCH and development department of ZooTeam, based in picturesque Hangzhou. The team now has more than 40 front end partners, the average age of 27 years old, nearly 30% are full stack engineers, no problem youth storm team. The membership consists of “old” soldiers from Alibaba and netease, as well as fresh graduates from Zhejiang University, University of Science and Technology of China, Hangzhou Electric And other universities. In addition to the daily business connection, the team also carried out technical exploration and actual practice in the direction of material system, engineering platform, building platform, performance experience, cloud application, data analysis and visualization, promoted and implemented a series of internal technical products, and continued to explore the new boundary of the front-end technology system.

If you want to change the things you’ve been doing, you want to start doing things. If you want to change, you’ve been told you need to think more, but you can’t change; If you want to change, you have the power to achieve that result, but you are not needed; If you want to change what you want to accomplish, you need a team to support you, but there is no place for you to bring people; If you want a change of pace, it’s “3 years of experience in 5 years”; If you want to change the original savvy is good, but there is always a layer of fuzzy window paper… If you believe in the power of belief, that ordinary people can achieve extraordinary things, that you can meet a better version of yourself. If you want to get involved in the growth of a front end team with a deep understanding of the business, a sound technology system, technology that creates value, and spillover impact as the business takes off, I think we should talk about it. Any time, waiting for you to write something, to [email protected]