preface

I never thought that one day I would be confused and confused by traversal questions. I didn’t know what to say. I used traversal all the time in development, but I didn’t expect that there would be so much knowledge inside.

For the front end, the most commonly encountered reference data types are arrays and objects, and there are the most traversal methods for these two data types. Why there are so many traversal methods is the problem that this chapter will discuss.

The for loop

The for loop is the most traditional traversal and the most compatible, iterating not only over groups of numbers but also over strings.

let arr = [1.2.3];
for (let i = 0; i < arr.length; i++) {
  console.log(i)
}
Copy the code

The advantage of a for loop over other loops is that it can be terminated at any time. You can use the continue and break keywords internally, and you can terminate or skip the loop if the conditions are not met.

ForEach, Map, and filter

forEach

ForEach can only be applied to arrays. It provides each element with a callback function that takes currenValue, index, and array, which are optional.

let arr = [1.2.3.4];
arr.forEach((item, i, arr) = > {
  console.log(item, i, arr)
})
Copy the code

The return value of forEach is always undefined, so it cannot be called chained, and it does not directly change the object on which it was called, but that object may be changed by callback.

map

Map can also be applied only to arrays. It provides a callback function for each element, which takes currenValue, index, and array (the latter two are optional).

let arr = [1.2.3.4];
let newArr = arr.map((item, i, arr) = > {
  console.log(item, i, arr);
})
Copy the code

The return value of a map is a new array. Using a map when you do not intend to use the new array is not intended. Use forEach or for-of instead.

There are two situations in which maps should not be used:

  1. You are not going to use the new array returned
  2. You did not return a value from the callback function

Like forEach, map does not directly change the object on which it is called, but that object may be changed by callback functions.

filter

Filter can also be applied only to arrays. It provides a callback function for each element, which takes three optional parameters, currenValue, index, and array.

let arr = [1.2.3.4];
let newFilterArr = arr.filter((item, i, arr) = > {
  return item > 1;
})
Copy the code

Filter returns a new array that has been filtered, or an empty array if none of the elements pass the filter criteria.

Filter does not alter the original array; it returns the filtered new array.

summary

  • There is no way to break or break out of the loop except by throwing an exception.
  • Both map and Filter return a new array

reduce

My girlfriend asked me if I could tell her something about Reduce

Every and some

every

The every() method tests whether all elements in an array pass the test of a given function. It returns a Boolean value.

If an empty array is received, this method returns true in all cases.

let arr = [1.2.3.4];
let boolean = arr.every((item) = > item < 5);
Copy the code

some

The some() method tests that at least one element in the array passes the provided function test. It returns a Boolean value.

If you test with an empty array, it returns false in all cases.

let arr = [1.2.3.4];
let boolean = arr.some((item) = > item < 5);
Copy the code

summary

  • Both returns Boolean values, where every is true if all elements in the array pass, and some is true if at least one element in the array passes
  • Both can be interrupted
  • Neither changes the original array

Find and findIndex

find

The find() method returns the value of the first element in the array that satisfies the provided test function. Otherwise return undefined.

let arr = [1.2.3.4];
let element = arr.find((item) = > item < 3);
Copy the code

findIndex

The findIndex() method returns the index of the first element in the array that satisfies the provided test function. Returns -1 if no corresponding element is found.

let arr = [1.2.3.4];
let index = arr.findIndex((item) = > item < 3)
Copy the code

summary

  • Neither changes the original array
  • Both can be interrupted
  • Find returns the value of the element that meets the condition, and findIndex returns the index of the element that meets the condition

for… Of and the for… in

for… of

for… The of statement creates an iteration loop over iterable objects (including Array, Map, Set, String, TypedArray, Arguments, and so on), calls custom iteration hooks, and executes statements for the values of each different property.

Iterable, that is, the object must implement iterator methods, which means that the object (or any object in its prototype chain) must have a property with a symbol. iterator key.

Object has no built-in iterator, so for… Of cannot iterate over it.

let iterator = [1.2.3.4];
for (let item of iterator) {
  console.log(item);
}
Copy the code

for… in

for… The IN statement iterates through an object’s enumerable properties other than Symbol in any order, including inherited enumerable properties that can iterate over their own enumerable properties as well as enumerable properties on their prototype.

If you want to enumerate only its own properties, use getOwnPropertyNames() or hasOwnProperty() to determine if a property is a property of the object itself. PropertyIsEnumerable can also be used.

Generally speaking, for… In should be used for debugging, making it easier to check object properties, so it is built for traversing object properties and is not recommended for use with arrays.

let obj = {a: 1.b: 2.c: 3};
for (let key in obj) {
  console.log("obj." + key + "=" + obj[key])
}
Copy the code

Let’s look at hasOwnProperty() in action

let obj = {a: 1.b: 2.c: 3};
function Person() {
  this.name = 'hanmeimei';
}
Person.prototype = obj;
let instance = new Person();
for (let key in instance) {
  console.log("instance." + key + "=" + instance[key])
} 
Output: instance.name = hanmeimei 
        instance.a = 1
        instance.b = 2
        instance.c = 3
for (let key in instance) {
  if (instance.hasOwnProperty(key)) {
    console.log("instance." + key + "=" + instance[key])
  }
} 
Output: instance.name=hanmeimei
Copy the code

summary

  • for… Of traverses the iterable, for… In traverses an object’s enumerable properties other than Symbol, including inherited enumerable properties
  • Either can be terminated by break, continue, throw, and return

Object. The keys and Object. The values and the Object. Entries and Object getOwnPropertyNames

Object.keys

The object.keys () method returns an array of a given Object’s own enumerable properties in the same order as the property names would be returned if the Object were iterated through normally.

let result = Object.keys({3: 'a'.1: 'b'.2: 'c'});
Output: ['1'.'2'.'3'];
Copy the code

The return value is an array of strings representing all the enumerable attributes of a given object, whose elements are derived from attributes that can be directly enumerated from the given object. The order of these attributes is the same as when the object attributes are manually traversed.

Object.values

The object.values () method returns an array of all the enumerable property values of a given Object itself, in the same order as the values used for… The in loop has the same order (the difference is that for-In loops enumerate properties in the stereotype chain).

let result = Object.values({3: 'a'.1: 'b'.2: 'c'});
Output: ['a'.'b'.'c'];
Copy the code

The return value is an array containing the values of all the enumerable properties of the object itself.

Object.entries

The object.entries () method returns an array of key-value pairs for the given Object’s own enumerable properties, arranged in the same order as for… The in loop returns the same order as it iterates through the object (the difference is that the for-In loop also enumerates properties in the prototype chain)

const obj = {a: 1.b: 2};
for (const [key, value] of Object.entries(obj)) {
  console.log(`${key}: ${value}`)}Output: a: 1
        b: 2

/ / the Object Map
const obj = {a: 1.b: 2};
const map = new Map (Object.entries(obj));
Output: Map(2) {'a'= >1.'b'= >2}
Copy the code

The return value is an array of key-value pairs for the given object’s own enumerable properties.

Object.getOwnPropertyNames

Object. GetOwnPropertyNames () method returns a specified by the Object of all its attributes of the attribute name (including not enumerated attribute but does not include Symbol value as the name of the attribute) consisting of an array.

const my_obj = Object.create({}, {
  getFoo: {
    value: function() { return this.foo; },
    enumerable: false}}); my_obj.foo =1;

console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
Copy the code

The return value is an array of strings corresponding to its properties found on the given object. The array pair element is an enumerable or non-enumerable property name string owned by OBJ itself.

summary

  • Object. The keys and the for… Both in iterate over enumerable attributes, but there is a difference between the two, for… In iterates over enumerable properties above the prototype chain in addition to its own enumerable properties, while Object.keys can only iterate over its own enumerable properties.
  • Object. The getOwnPropertyNames and Object. The keys and the for… The difference in in is that it can iterate over non-enumerable properties, but not over properties on the stereotype
  • Values returns the enumerable value of the Object itself
  • Object.entries return the Object’s own enumerable key-value pairs, which can be used to transform collections of objects

Supplement: for… Traversal order of in

In the previous section, several Object methods had instructions for traversal order and for… In the same order, for… What is the traversal order of in?

ECMAScript states that the order in which objects are traversed is determined by the order in which attributes are written when the object is defined, but exceptions are found in practice. As shown below.

let result = Object.keys({3: 'a'.1: 'b'.2: 'c'});
Output: ['1'.'2'.'3'];
Copy the code

It should print [‘3’, ‘1’, ‘2’], but it prints [‘1’, ‘2’, ‘3’]

This is because Chrome Opera uses ECMA-262 version 5. The order in which for-in statements iterate over attributes of objects is not specified. They will first extract all attributes whose parseFloat value is a non-negative integer. It then sorts the properties in numerical order first through, and then through all the remaining properties in the order defined by the object. Other browsers use ECMA-262 version 3 and traverse properties in exactly the order defined by the object.

summary

Summary and comparison of traversal methods and differences, hope in the future development can use appropriate traversal method, reduce useless traversal, after all, will cause a lot of consumption, which write wrong hope we supplement!!