First, JS loop

1. General for loop

    var array = [1.2.3.4.5.6.7];  
    for (var i = 0; i < array.length; i++) {  
        console.log(i,array[i]);  
    }  
Copy the code

2.for… in

let array = [2.4.6.8.9];
for(let index in array) {  
        console.log(index+"-"+array[index]);  
    };  / / 0-1-2 4...
Copy the code

Index traverses the index of an array or string, or the key name of an object.

Enumerable can be used for… The in traverse.

Note: the fo… The in loop is generally used for traversal of objects, but there is a pit to watch out for:

Any Object inherits from Object, or any other Object, and the attributes of the inherited class are not traversable by default. The in loop skips it, but the property can be changed to be traversable, resulting in traversal of properties that do not belong to it.

For example, objects inherit the toString attribute, but for… The in loop does not traverse this property.

var obj = {};// The toString attribute exists obj.tostring
// toString() { [native code] }
for (var p in obj) { 
     console.log(p);
} // There is no output

// obj has length, but length is not traversable.
Copy the code

If the inherited property is traversable, it will be for… In loops through to. But if you just want to iterate over your own properties, use for… In, you should use the hasOwnProperty method inside the loop to determine if a property is a property of the object itself. Otherwise, ergodic distortion can occur.

var person = { name: 'Lao zhang' };
for (var key in person) {  
    if (person.hasOwnProperty(key)) {   
         console.log(key); }}// name
Copy the code

3.for… of

for… Of is new in ES6 and allows you to directly iterate over the value of this object.

let v = [1.2.3]
for(let v of array) {  
	console.log(v);  
}; / / 1 2 3
let s = "hello";  
for(let c of s) {  
	console.log(c); 
} // h e l l o
Copy the code

Note: for… Of can only be used for iterator objects, so it can only be used for arrays and strings, not objects.

4.forEach

array.forEach(calllback(currentValue, index, arr), thisValue)

  • callback

    Function executed for each element in the array, which takes three arguments:

    • The current element being processed in the currentValue array.

    • Index Indicates the index of the current element being processed in the optional array.

    • Array Optional array that the forEach() method is operating on.

  • ThisArg optional

    This parameter is optional. Used as the value of this when the callback function is executed.

  • The return value undefined

var array1 = [1.2.3.4.5];
array1.forEach((value,index,arr) = >{
    console.log(value+"--"+index);/ / 1-0 2-1...
    console.log(arr); / / [1, 2, 3, 4, 5]
}); 
Copy the code

Note: There is no way to abort or break out of the forEach() loop except by throwing an exception. The forEach() method is not the tool to use if you need to break or break out of a loop.

forEach()Execute once for each array elementcallbackFunctions; withmap()orreduce()The difference is that it always returnsundefinedValue and cannot be called chained.

5. The map () loop:

The map method passes all the members of the array to the parameter function in turn, and returns the result of each execution as a new array.

Note: returns a new array, does not alter the original array.

var numbers = [1.2.3];

numbers.map(function (n) { 
     return n + 1; 
}); 
/ / [2, 3, 4]

numbers / / [1, 2, 3]
Copy the code

The map method takes a function as an argument. When this function is called, the map method passes it three parameters: the current member, the current location, and the array itself.

[1.2.3].map(function(elem, index, arr) { 
    return elem * index; 
}); 
/ / [0, 2, 6]
Copy the code

In addition, the map() loop can take a second argument that binds the this variable inside the callback function, pointing the this object inside the callback to the second argument, and indirectly manipulating that argument (usually an array).

var arr = ['a'.'b'.'c'];

[1.2].map(function (e) {
    return this[e];
}, arr)
 // ['b', 'c']
Copy the code

Summary: The difference between forEach and map is that forEach returns an empty value, while map returns an array of results.

6. Filter () Filter loop

The filter method is used to filter the members of an array. It takes a function that all array members execute in turn, returning true members as a new array. This method does not change the original array.

[1.2.3.4.5].filter(function (elem) {
     return (elem > 3); 
}) / / [4, 5]

// The above code returns the array member greater than 3 as a new array.

var arr = [0.1.'a'.false]; 
arr.filter(Boolean) // [1, "a"]
Copy the code

The parameter function of the filter method can also take three arguments: the current member, the current position, and the entire array.

[1.2.3.4.5].filter(function (elem, index, arr) { 
    return index % 2= = =0; 
}); / / [1, 3, 5]

The filter method can also take a second argument to bind the this variable inside the parameter function.
var obj = { MAX: 3 }; 
var myFilter = function (item) {
     if (item > this.MAX) return true; 
}; 
var arr = [2.8.3.4.1.3.2.9]; 
arr.filter(myFilter, obj) / / [8, 4, 9]
Copy the code

In the code above, the myFilter has the this variable inside it, which can be bound by the second argument to the filter method, obj, and returns a member greater than 3.

7. Some (), every(

These methods, like Assert, return a Boolean value that determines whether an array member meets a condition.

They take a function as an argument that all array members execute in turn. This function takes three arguments: the current member, the current location, and the entire array, and then returns a Boolean value.

The some method returns true as long as one member returns true, and false otherwise.

var arr = [1.2.3.4.5];
arr.some(function (elem, index, arr) {
  return elem >= 3;
});
// true
Copy the code

The every method, on the other hand, returns true for all members and false otherwise. By contrast, some() returns true as long as either of them is true; Every () returns false as long as one of them is false.

var arr = [1.2.3.4.5];
arr.every(function (elem, index, arr) {
  return elem >= 3;
});
// false
Copy the code

These two methods can be used in practical development. For example, these two methods can be used to determine whether the user has checked unoperable data or whether the user has checked a operable data.

8. The reduce (), reduceRight ()

The ** Reduce and reduceRight methods process each member of the array in turn, eventually accumulating to a value. ** The difference is that reduce is processed from left to right (from the first member to the last member), reduceRight is processed from right to left (from the last member to the first member), and everything else is exactly the same.

[1.2.3.4.5].reduce(function (a, b) {
  console.log(a, b);
  return a + b;
})
/ / 1. 2
/ / 3. 3
4 / / 6
/ / 10 5
// Final result: 15
Copy the code

The first parameter of the Reduce and reduceRight methods is a function. The function takes the following four arguments.

Cumulative variable, default is the current variable of the first member of the array, default is the current position of the second member of the array (starting from 0). Only the first two of the four arguments to the original array are required.

If you want to specify an initial value for a cumulative variable, you can place it in the second argument to the Reduce and reduceRight methods.

[1.2.3.4.5].reduce(function (a, b) {
  return a + b;
}, 10);
/ / 25
Copy the code

The second argument above sets the default value and is especially useful when dealing with empty arrays, avoiding some null-pointer exceptions.

Because these two methods iterate over a set of numbers, they can actually be used to do some traversal related operations.

Finds the array member with the longest character length.

function findLongest(entries) {
  return entries.reduce(function (longest, entry) {
    return entry.length > longest.length ? entry : longest;
  }, ' ');
}

findLongest(['aaa'.'bb'.'c']) // "aaa"
Copy the code

In the code above, the reduce argument function takes the longer array member as the cumulative value. This results in the cumulative value being the member with the longest character length after iterating through all members.

9.Object,keys Iterate over the properties of the Object

Keys takes an object and returns an array. The members of this array are all the property names of the object itself (not inherited), and only the properties that are enumerable are returned.

var obj = {
  p1: 123.p2: 456
};

Object.keys(obj) // ["p1", "p2"]
Copy the code

10. Object. GetOwnPropertyNames () traverse Object’s properties

Object. The getOwnPropertyNames method and the Object. The keys are similar, is also accept an Object as a parameter, returns an array that contains all of the attributes of the Object itself. But it can return non-enumerable attributes.

var a = ['Hello'.'World'];

Object.keys(a) / / / "0", "1"
Object.getOwnPropertyNames(a) // ["0", "1", "length"]
Copy the code

The above code, the array length attribute is an enumerated attribute, so only appear in the Object. The getOwnPropertyNames method returns the result.

Since JavaScript does not provide a way to count the number of attributes on an object, you can use these two methods instead.

var obj = {
  p1: 123.p2: 456
};
Object.keys(obj).length / / 2
Object.getOwnPropertyNames(obj).length / / 2
Copy the code

11. A summary

Above cycle characteristics (same and different) :

The map(), foreach, filter loops have in common:

  1. Foreach, Map, and filter loops cannot be stopped in the middle of the loop, always iterating through all members.

  2. They can either take the second argument, which binds the this variable inside the callback function, and refer the this object inside the callback function to the second argument, indirectly manipulating that argument (usually an array).

The map() loop differs from the forEach loop:

ForEach loop returns no value; Map, filter loop returns a value.

Both map and filter() loops skip empty Spaces, but for and while loops do not

var f = function (n) { 
    return 'a' 
}; 

[1.undefined.2].map(f) // ["a", "a", "a"] 
[1.null.2].map(f) // ["a", "a", "a"]
[1.2].map(f) // ["a", , "a"] 
Copy the code

In the above code, the map method does not skip undefined and NULL, but does skip empty Spaces. The forEach method also skips the empty space in the array, so I won’t give an example here.

四 : Some () and every():

  • Some () returns true as long as one of them is true; Every () returns false as long as one of them is false.

Five: Reduce (), reduceRight() :

  • Reduce is processed from left to right (from the first member to the last member) and reduceRight is processed from right to left (from the last member to the first member).

6: two traverse Object. The Object keys and Object. GetOwnPropertyNames:

They both iterate over the properties of the object, taking an object as an argument and returning an array containing all the property names of the object itself. But object. keys cannot return non-enumerable properties; Object. GetOwnPropertyNames can return an enumeration of attributes.

Seven: for… In and for… of

(See Nguyen Yifeng)

In the case of arrays, JavaScript provides multiple traversal syntax. The original way to write it is the for loop.

for (var index = 0; index < myArray.length; index++) {
  console.log(myArray[index]);
}
Copy the code

This is cumbersome, so arrays provide built-in forEach methods.

myArray.forEach(function (value) {
  console.log(value);
});
Copy the code

The problem with this is that you can’t break out of the forEach loop, and neither break nor return will work.

for… The in loop iterates through the key names of a number group.

for (var index in myArray) {
  console.log(myArray[index]);
}
Copy the code

for… The in loop has several disadvantages.

  • The array’s key name is a number, butfor... inLoops are strings with keys “0”, “1”, “2”, and so on.
  • for... inThe loop iterates not only over numeric key names, but also over other manually added keys, and even keys on the prototype chain.
  • In some cases,for... inThe loop iterates over the key names in any order.

All in all, for… The in loop is designed primarily for traversing objects, not for traversing groups of numbers.

for… The of loop has some significant advantages over the above approaches.

for (let value of myArray) {
  console.log(value);
}
Copy the code
  • With withfor... inSame concise syntax, but nofor... inThose flaws.
  • Different from theforEachMethod, it can be withbreak,continueandreturnUse together.
  • Provides a unified operation interface for traversing all data structures.

Here is a statement that uses the break statement to break for… An example of an of loop.

for (var n of fibonacci) {
  if (n > 1000)
    break;
  console.log(n);
}
Copy the code

The example above prints Fibonacci numbers less than or equal to 1000. If the current item is greater than 1000, the for… statement is broken. Of circulation.

B: Iterator

2.1 Using Iterator to Traverse

  1. Not all array-like objects have an Iterator interface, and a handy solution is to use the array. from method to convert them to an Array.

    let arrayLike = { length: 2.0: 'a'.1: 'b' };
    
    / / an error
    for (let x of arrayLike) {
      console.log(x);
    }
    
    / / right
    for (let x of Array.from(arrayLike)) {
      console.log(x);
    }
    Copy the code

2.2 Iterator iterator extension #

Some data structures are computationally generated based on existing data structures. For example, ES6 arrays, sets, and maps all deploy the following three methods, which return a traverser object when called.

  • entries()Returns an traverser object for traversal[Key name, key value]Is an array. For arrays, the key is the index value; For the Set,The key name is the same as the key value. The Map Iterator interface is called by defaultentriesMethods.
  • keys()Returns an iterator object that iterates over all key names.
  • values()Returns a traverser object that iterates over all key values.

The traverser objects generated after these three method calls are traversed through the computed data structures.

let arr = ['a'.'b'.'c'];
for (let pair of arr.entries()) {
  console.log(pair);
}
// [0, 'a']
// [1, 'b']
// [2, 'c']
Copy the code

Note:

  1. The array, Set, and Map methods return the Iterator, SetIterator {“Gecko”, “Trident”, “Webkit”}

    This is not the same as methods like object.keys () on objects!! Object these three methods, return is an array!

    Example:

    let es6 = {
      edition: 6.committee: "TC39".standard: "ECMA-262"
    };
    let ite =  Object.entries(es6)[Symbol.iterator]()
    // Array Iterator {}
    Copy the code
  2. for… By default, keys() is used for arrays and sets, and entries() is used for Map.

  3. Directly used for… The effect of looping through an iterator object is the same!

    eg.

    let arr=[3.6.9]
    for(let i of arr){
        console.log(i)
     }
    
    for(let i of arr[Symbol.iterator]()){
        console.log(i)}
    // Both return the same 3, 6, 9
    Copy the code

2.3 Scenarios for Calling the Iterator Interface

In addition to the for… The of loop, as well as several other cases, calls the Iterator interface (symbol. Iterator method) by default.

(1) Deconstructing assignment

The symbol. iterator method is called by default when destructuring arrays and Set structures.

let set = new Set().add('a').add('b').add('c');

let [x,y] = set;
// x='a'; y='b'

let [first, ...rest] = set;
// first='a'; rest=['b','c'];
Copy the code

(2) Extended operators

Extended operators (…) The default Iterator interface is also called.

/ / a
var str = 'hello';
[...str] // ['h','e','l','l','o']

/ / two cases
let arr = ['b'.'c'];
['a'. arr,'d']
// ['a', 'b', 'c', 'd']
Copy the code

The extension operator of the above code internally calls the Iterator interface.

In effect, this provides an easy mechanism to turn any data structure with the Iterator interface deployed into an array. That is, whenever a data structure has an Iterator interface deployed, you can use the extension operator on it to turn it into an array.

let arr = [...iterable];
Copy the code

(3) the yield *

Yield * is followed by a traversable structure, which invokes the traverser interface of that structure.

let generator = function* () {
  yield 1;
  yield* [2.3.4];
  yield 5;
};

var iterator = generator();

iterator.next() // { value: 1, done: false }
iterator.next() // { value: 2, done: false }
iterator.next() // { value: 3, done: false }
iterator.next() // { value: 4, done: false }
iterator.next() // { value: 5, done: false }
iterator.next() // { value: undefined, done: true }
Copy the code

(4) Other occasions

Because array traversal calls the traverser interface, any situation that takes an array as an argument actually calls the traverser interface. Here are some examples.

  • for… of
  • Array.from()
  • WeakMap(), Set(), WeakMap(), WeakSet() (e.gnew Map([['a',1],['b',2]]))
  • Promise.all()
  • Promise.race()

2.4 Comparison with other traversal syntax

In the case of arrays, JavaScript provides multiple traversal syntax. The original way to write it is the for loop.

for (var index = 0; index < myArray.length; index++) {
  console.log(myArray[index]);
}
Copy the code

This is cumbersome, so arrays provide built-in forEach methods.

myArray.forEach(function (value) {
  console.log(value);
});
Copy the code

The problem with this is that you can’t break out of the forEach loop, and neither break nor return will work.

for… The in loop iterates through the key names of a number group.

for (var index in myArray) {
  console.log(myArray[index]);
}
Copy the code

for… The in loop has several disadvantages.

  • The array’s key name is a number, butfor... inLoops are strings with keys “0”, “1”, “2”, and so on.
  • for... inThe loop iterates not only over numeric key names, but also over other manually added keys, and even keys on the prototype chain.
  • In some cases,for... inThe loop iterates over the key names in any order.

All in all, for… The in loop is designed primarily for traversing objects, not for traversing groups of numbers.

for… The of loop has some significant advantages over the above approaches.

for (let value of myArray) {
  console.log(value);
}
Copy the code
  • With withfor... inSame concise syntax, but nofor... inThose flaws.
  • Different from theforEachMethod, it can be withbreak,continueandreturnUse together.
  • Provides a unified operation interface for traversing all data structures.