Iterator

Introduction

  • The iterator protocol defines a standard way to produce a sequence of values and potentially a return value when all values have been generated.

  • It is mainly compose by next , done , value and return

  • Next: go to the next step

  • Value: obtain the value

  • Done: the flag for labelling finishing reason

  • Return: the final value

// 1st Method 
function makeRangeIterator(start = 0, end = Infinity, step = 1) {
  let nextIndex = start;
  let iterationCount = 0;

  const rangeIterator = {
    next() {
      let result;
      if (nextIndex < end) {
        result = { value: nextIndex, done: false };
        nextIndex += step;
        iterationCount++;
        return result;
      }
      return { value: iterationCount, done: true };
    },
  };
  return rangeIterator;
}

// 2nd Method (By Generator Function)
function* makeRangeIterator(start = 0, end = Infinity, step = 1) {
  let iterationCount = 0;
  for (let i = start; i < end; i += step) {
    iterationCount++;
    yield i;
  }
  return iterationCount;
}

const iter = makeRangeIterator(1, 10, 2);

// 3rd Method (By declaring symbol iterator)
const iter = {
  *[Symbol.iterator]() {
    yield 1;
    yield 2;
    yield 3;
    yield 5;
    yield 7;
    yield 9;
  },
};

console.log(iter[Symbol.iterator]() === iter); // true

// 1st Looping Sequence Method
let result = iter.next();
while (!result.done) {
  console.log(result.value); // 1 3 5 7 9
  result = iter.next();
}
// 2nd Looping Sequence Method
for (const itItem of iter) {
  console.log(itItem); // 1 3 5 7 9
}
  • Generator function does not execute its body immediately and return an object, the function can be paused and resumed easily

  • Each yield statement is just like a break point to pause, the logic above the yield statement will be triggered if the next of the object is called to resume

Inheritance

  • You can create new generate function based on the existing function

function* generatorFn() {
  yield 1;
  yield 2;
}

function* newGeneratorFn(){
  yield "start";
  for (test of test()){
    yield test;
  }
  yield "end";
}

for (const item of newGeneratorFn()){
  console.log(item);
}

// Result
// start 
// 1
// 2
// end

Built-in Iterable Object

  • An object is iterable if it defines its iteration behavior, such as what values are looped over in a for...of construct.

  • In order to be iterable, an object must implement the [Symbol.iterator]() method.

  • String, Array, TypedArray, Map and Set are all built-in iterables, because their prototype objects all have a Symbol.iterator method.

for (const value of ["a", "b", "c"]) {
  console.log(value);
}
// "a"
// "b"
// "c"

[..."abc"];
// ["a", "b", "c"]

function* gen() {
  yield* ["a", "b", "c"];
}

gen().next();
// { value: "a", done: false }

[a, b, c] = new Set(["a", "b", "c"]);
a;
// "a"

Last updated

Was this helpful?