Understanding Custom Iterator Implementation

I am trying to understand Ecmascript 6 iterators and trying to create a data structure that behaves like native arrays.

for (let i of [1,2,3]) console.log(i);  //Iterate over data set itself

will output 1,2,3

for (let i of [1,2,3].keys()) console.log(i); //Iterate over a custom iterator from a method

displays 0,1,2, and

var a = [1,2,3];
var keys = [...a.keys()];

will contain [0,1,2]as expected.

Thus,

console.log([1,2,3].keys().next());

will output Object {value: 0, done: false}

Now I created a new data type and tried to make it behave the same.

var myDogs = function(dogs) {
 this.dogs = dogs;
 this[Symbol.iterator] = () => {
   let i = -1;
   return {
    next() {
     i++;
     var dog = Object.keys(dogs)[i];
     if (!dog) return {done:true};
     return {value:{ dog, hungry:dogs[dog] }, done:false};
    }
   };
 };
 this.dogsNames = () => {
  return {
   [Symbol.iterator]() {
     let i = -1;
     return {
      next() {
       i++;
       var dog = Object.keys(dogs)[i];
       if (!dog) return {done:true};
       return {value: dog, done:false};
      }
     };
   }
  }
 }
};

var dogs = new myDogs({ buddy: true, hasso: false });

This works as expected (custom iterator - thanks ):

var dogHungryMap = [...dogs];
dogHungryMap == [{ dog: 'buddy', hungry: true }, { dog: 'hasso': hungry: false }]

The iterator dogsNames()works almost as expected. This is normal:

var names = [...dogs.dogsNames()];
names == ["buddy", "hasso"]

But this is not so:

dogs.dogsNames().next()
VM19728:2 Uncaught TypeError: dogs.dogsNames(...).next is not a function(…)

Why and how can I reproduce the behavior of inline arrays?

+4
source share
2 answers

dogNames (, next), (-, Symbol.iterator) ( ). .

, :

var it = [].keys();
it[Symbol.iterator]() === it // true

,

this.dogsNames = () => {
  let i = -1;
  return {

    [Symbol.iterator]() {
      return this;
    },

    next() {
      i++;
      var dog = Object.keys(dogs)[i]; // should probably also be put in the outer function
      if (!dog) return {done:true};
      return {value: dog, done:false};
    },

  };
};
+4

dogsNames() , . , for...of , next() , , :

dogsNames()[Symbol.iterator]().next()

Babel REPL

, next():

var myDogs = function(dogs) {
 this.dogs = dogs;
 let i = -1;
 var iter = {
   next() {
     i++;
     var dog = Object.keys(dogs)[i];
     if (!dog) return {done:true};
     return {value:{ dog, hungry:dogs[dog] }, done:false};
   }
 }
 this[Symbol.iterator] = () => iter;
 this.next = iter.next;
};
var dogList = new myDogs({
  dog1: "no",
  dog2: "yes"
});
for(const x of dogList) console.log(x);
console.log(dogList.next());
console.log(dogList.next());
+5

Source: https://habr.com/ru/post/1624275/


All Articles