ES6 iterator interface Iterator

1. Concept

Iterator is an interface that provides a unified access mechanism for various data structures. Any data structure can complete the traversal operation (that is, process all members of the data structure in turn) as long as the Iterator interface is deployed.

Iterator has three functions: one is to provide a unified and convenient access interface for various data structures; the other is to enable the members of the data structure to be arranged in a certain order; the third is that ES6 has a new traversal method, for. ..of, and the main role of Iterator is to support this operation.

 

2. Whether there is an Iterator interface

In ES6, some data structures natively have the Iterator interface (such as arrays), that is, they can be traversed by for...of loops without any processing, and some do not (such as objects). The reason is that these data structures natively deploy the Symbol.iterator property (see below for details), while others do not.

Any data structure that deploys the Symbol.iterator property is called deploying the traverser interface. Calling this interface will return a iterator object.

In ES6, there are three types of data structures that have the Iterator interface natively: arrays, some array-like objects, and Set and Map structures. All three of them can use the for...of traversal function without us manually adding the Symbol.iterator property. The normal object traversal using for...of will report an error because it does not deploy the interface.

 

3. Deployment interface

If you need to make a collection that doesn't have the for...of traversal feature available, you'll need to deploy it manually. ES6 has many built-in Symbol values, and these are interfaces.

Next, we use the principle of iterator to generate an iterator for the object, so that the object can use for...of

 

var person = {
          name: 'zz',
           age: 18 
       } 
// Add an iterator interface to the person object person[Symbol.iterator] = function(){
// Use the object.keys() method to read the k value in the j object and store it in the array var arr = Object .keys(person); var i = 0 ; return { // next() iteration method in ES6, automatic iteration next(){ if (i < arr.length){ // If done is false, continue to iterate return { / /Return the final result of the iteration, if it is an object, then you need to use destructuring value when for of: { k : arr[i], val: person[arr[i++]] }, done: false } } else { // If done is true, continue to iterate return { value: null, done : true } } } } }
// Destruction to get the returned object, output k value, val value for ( var {key,val} of person){ console.log(key,val); }

 

 

We can see that:

1. By deploying the Symbol.iterator interface for the person object, it implements the for...of function.

2. An object is returned in Symbol.iterator, which contains a next() method that defines the traversal function.

3. The value and done in the next method, value is the key-value pair information returned during the traversal process, and done is a Boolean value indicating whether the traversal is over.

 

Replenish:

1. In addition to the next method, the traverser object can also have a return method and a throw method. If you write your own traverser object generation function, the next method must be deployed, and whether the return method and the throw method are deployed is optional.

  When a destructor exits abnormally early (such as break, continue, or error) during traversal, the return method is called. Second, the return method must return an object.

  As for the throw method, it is used to throw errors. Generator.prototype.throw will not be discussed here. If you are interested, you can search for it.

 

2. Use the ES6 new function Generator function to implement the Symbol.iterator interface, which can achieve more with less effort.

var yieldIterator = {};
yieldIterator[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};

[...yieldIterator] // [1, 2, 3]

Note that yield* is followed by a traversable structure, which invokes the structure's traverser interface.

If you don't know about Generator, you can poke the syntax of ES6 Generator , so I wo  n't say much here.

 

3. As for array-like objects that can be converted into arrays using Array.from, there is a very simple way to deploy iterators, which is to directly use the [Symbol.iterator] interface of the array.

fakeArray.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];

 

4. Scenarios in which the Iterator interface is called by default

1. Destructuring assignment

2. Spread operator (...)

3. The yield* mentioned above

4. Since the traversal of the array will call the traverser interface, any occasion that accepts an array as a parameter will be called by default, such as

  for...of

  Array.from()

  Map(), Set(), WeakMap(), WeakSet()

  Promise.all()

  Promise.race()

5. A string is an array-like object, and it also has an Iterator interface natively

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324693740&siteId=291194637