Murad Sofiyev
Murad Sofiyev

Reputation: 791

Generator & Iterators - Iterable [MDN Documentation]

When I read about iterators and generator in MDN. I read some paragraph in there and I don't understand what exactly this mean? Anyone can help me what is this paragraph mean exactly?

It may be possible to iterate over an iterable more than once, or only once. It is up to the programmer to know which is the case. Iterables which can iterate only once (e.g. Generators) customarily return this from their @@iterator method, where those which can be iterated many times must return a new iterator on each invocation of @@iterator.

Upvotes: 1

Views: 204

Answers (3)

Nima Bastani
Nima Bastani

Reputation: 305

First of all

There is no @@iterator function, you have to use Symbol.iterator to implement iteration .

Now as you see the article discusses generators and iterable at the same time, that's because generators are iterable, and implement iteration behavior for a custom object could get describe with generators. Let's take a look at the MDN example :

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

for (let value of myIterable) { 
    console.log(value); 
}
// 1
// 2
// 3

It creates iteration overobject with exact 3 itrates.

Writing the same iterable without using generators could explain it more about

return this from their @@iterator method

let range = {
  from: 1,
  to: 3,

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

  next() {
    if (this.current <= this.to) {
      return { done: false, value: this.current++ };
    } else {
      return { done: true };
    }
  }
};

for (let num of range) {
  console.log(num); // 1, 2, 3
}

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386560

It means, you could create a generator as you want. For example this eternity is returning the elements forever.

Be carefull, if you use something like [...eternity(array)].

function* eternity(array) {
    while (true) yield* array;
}

var array = [1, 2, 3],
    gen = eternity(array);

console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);

Upvotes: 1

Bergi
Bergi

Reputation: 664307

Have a look at this example:

function iterateTwice(iterable) {
    for (const x of iterable) console.log(1, x);
    for (const x of iterable) console.log(2, x);
}

console.log("array");
const array = ['a', 'b', 'c'];
iterateTwice(array);

console.log("generator");
function* makeGenerator() {
    yield 'a'; yield 'b'; yield 'c';
}
const generator = makeGenerator();
iterateTwice(generator);

This is because array[Symbol.iterator]() returns a new iterator every time that iterates the array from start to end, while generator[Symbol.iterator]() returns the same iterator object[1] every time. The first for … of iteration did exhaust it, the second loop will see and ended iterator that doesn't produce any items.

1: actually itself, generator === generator[Symbol.iterator]().

Upvotes: 1

Related Questions