Write an article for the first time, ask big guy to correct if there is a mistake!

The iterator

1. Distinguish between for of and for in

For of is an iterator. The iterable object is an object containing an iterator. Generally, an object does not have an iterator protocol, that is, the @@iterator method. That is, objects that themselves can be iterated over.

For in iterates through enumerable properties. Primitive wrapper types such as Object, Array, and Object prototype properties cannot be enumerated. Whether you can append an enumerable property enumerable: True via the object.defineProperty () method

2. Iteration protocol

The iterable protocol allows JavaScript objects to define or customize their iterative behavior, for example, in a for.. In the of structure, which values can be traversed.

To be an iterable, an object must implement the @@iterator method. This means that the object (or an object in its prototype chain) must have a property with a key of @@iterator that can be accessed through a constant symbol. iterator, such as Object [symbol.iterator].

When an object needs to be iterated over (such as by placing a for… First, its @@iterator method is called with no arguments, and then the iterator returned by this method is used to get the value to iterate over. The @@iterator method must return an iterator. An error is reported if the iterator method is not used such as the extension operator or for of.

3. The generator

The generator object is returned by a generator function and conforms to both the iterable and iterator protocols.

A Generator function always returns a Generator.

Basic usage:

Generator.prototype.next();

Returns a value generated by the yield expression.

Generator.prototype.return();

Returns the given value and terminates the generator.

Generator.prototype.throw();

Throw an error to the generator.

    function * gen(){
        let index = 0;
        while(true){
            yield index++
        }
    }

    var g = gen()
    console.log(g.next())
    console.log(g.next())
    console.log(g.return())
    console.log(g.next())
/*
{ value: 0, done: false }
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: undefined, done: true }
{ value: undefined, done: true }
*/
Copy the code

4. Relationships and differences between iterators, iteration protocols, and generators

A generator is an iterator. An iterator is not necessarily a generator. An iterable contains an iterator protocol @@iterator. Of iterates until done:true.

Definition and implementation of iterators:

An object can be an iterator only if it implements a next() method with the following semantic:

  1. The next() method is a parameterless function

  2. The next() method returns an object containing both done and value properties

  3. Done: false if the iterator can produce the next value in the sequence; true if it can produce the next value in the sequence; value: Any JavaScript value returned by the iterator.

    It follows that an iterator is really just a method that implements a semantic rule for next()

    function myIterator() {
        let index = 0
        return {
           next: function () {
               if(index<5){
                   return {value:index++,done:false}
               }else{
                   return {value:undefined,done:true}
               } 
           }
        };
    }
    var iter = myIterator()
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())

    /*{ value: 0, done: false }
    { value: 1, done: false }
    { value: 2, done: false }
    { value: 3, done: false }
    { value: 4, done: false }
    { value: undefined, done: true }
    { value: undefined, done: true }*/
Copy the code

Iterators are a use of closures that specify rules. Here are iterators that use generators:

    function * myIterator() {
        let index = 0
        while(index<5){
            yield index++
        }
    }
    var iter = myIterator()
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())

/*
    { value: 0, done: false }
    { value: 1, done: false }
    { value: 2, done: false }
    { value: 3, done: false }
    { value: 4, done: false }
    { value: undefined, done: true }
    { value: undefined, done: true }*/
Copy the code

The following is the implementation and application of iteration protocol:

var Person = { name:"xiaoxiao", age:18, * console.log([...Person]) ^ TypeError: Person is not iterable */ -------------------------------------------------------------------------------------- var Person = { name:"xiaoxiao", age:18, sexy:"girl", Person[symbol.iterator] = function(){let index = 0 return{next:function(){if(index<5){  return {value:index++,done:false} }else{ return {value:undefined,done:true} } } } } console.log([...Person]) //[ 0, 1, 2, 3, 4]Copy the code