1. The background

ES6 uses C++, Java, C# and Python to introduce the for… Of loop as a unified way to traverse all data structures.

A data structure that deploys the Symbol. Iterator property is considered to have an iterator interface and can be used for… The of loop iterates through its members. That is to say, for… Inside the of loop, the Symbol. Iterator method of the data structure is called.

That is, Iterator is a traversal interface.

2. The data type of iterator has been implemented

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • The Arguments object for the function
  • The NodeList object

Take Array as an example:

const arr = ['a'.'b'.'c'.'d']
for (const value of arr) {
    console.log(value) // a b c d 
}
Copy the code

3. Implementation principle of Iterator

To quote the official expression:

The conclusion is that done is true in the returned data object. // {done: true, value: undefined}

4. How to create an Iterator traversal interface for the Object type

4.1 Scheme 1: Generator Encapsulation

As you can see from chapter 3, the underlying function is the Generator function, which is wrapped in a Generator

jsconst obj = { a: 1, b: 2, c: 3 }

function* entries(obj) {
  for (let key of Object.keys(obj)) {
    yield [key, obj[key]];
  }
}

for (let [key, value] of entries(obj)) {
  console.log(key, '->', value);
}
// a -> 1
// b -> 2
// c -> 3
Copy the code

4.2 Scheme 2: Borrowing an array Iterator

Array objects can be iterable, but only if the key value is the index of the Array. This kind of object is extreme and is not a general practice. It is only used to expand the idea.

let iterable = {
  0: 'a'.1: 'b'.2: 'c'.length: 3[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
  console.log(item); // 'a', 'b', 'c'
}
Copy the code

4.3 Solution 3: Customize the Iterator scheme

Since we have formulated for… Of gets the value of each rotation by calling the next method again and again

let obj = {
    a:1.b:2[Symbol.iterator](){
        let index = 0;
        return {
            next: () = > {
                let keys = Object.keys(this);
                return index >= keys.length ? {done: true}, {value: this[keys[index++]]}
            }
        }
    }
};
for (let val of obj) {
    console.log(val);/ / 1. 2
}
Copy the code

5. Iterate over the API summary

Take an array object for example

5.1 a for loop

1. The use of the most complete functions, is the most original traversal writing. 2. It is uncomfortable and troublesome to write. So array objects provide forEach and map methods

5.2 the forEach/map

1. Array full variable traversal, API light. 2. The loop cannot exit halfway. The return and break commands do not work

5.3 the for… in

1. API is light and convenient. 2.for… The in loop iterates not only over numeric key names, but also over other keys added manually, even keys on the prototype chain. for… In is originally designed for traversing objects.

5.4 the for… of

1. API is light and convenient. 2. Can be used with continue, break, return, high flexibility 3. This assumes that the Iterator interface is implemented by the traversal type