[JavaScript – ES2015] Iterators & for..of

Iterator is a well known concept for any .NET developers. Iterator allows you to access a collection one item at a time. JavaScript’s for..in loop is not for a collection. It is to access properties in an object. A new loop syntax for..of is introduced to iterate a collection.

 

1. Iterator API

Iterator is very simple. It has the “next()” method that returns an object with “done” and “value” property.

Array’s “values()” method returns an iterator.

let numbers = [1, 2, 3, 4, 5];
let iterator = numbers.values();
let next = iterator.next();
while (!next.done) {
  console.log(next.value);
  next = iterator.next();
}

 

2. for..of

ES2015 introduced a new loop (for..of) to make use of iterators.

let numbers = [1, 2, 3, 4, 5];
for (let n of numbers) {
  console.log(n);
}

Note that the loop is just iterate “numbers” not “numbers.values“. How does for..of find the iterator?

 

3. Magic Method [Symbol.iterator]

The for..of loops looks for the Symbol.iterator method to get an iterator. Arrays implement this method too. You can use this magic method instead of the “values()“.

let numbers = [1, 2, 3, 4, 5];
let iterator = numbers[Symbol.iterator]();
let next = iterator.next();
while (!next.done) {
  console.log(next.value);
  next = iterator.next();
}

 

4. Custom Iterator

By implementing the [Symbol.iterator] method, you can iterate your custom collection object through for..of loop.

The [Symbol.iterator] method will return an object with the “next()” method, which returns an object { done, value }.

class NumberCollection {
  constructor() {
    this._numbers = [];
  }
  add(...nums) {
    nums.forEach(n => {
      this._numbers.push(n);
    });
  }
  [Symbol.iterator]() {
    return new ArrayIterator(this._numbers);
  }
} 

class ArrayIterator {
  constructor(arr) {
    this._array = arr;
    this._index = 0;
  }
  next() {
    let moreData = this._index < this._array.length;
    return {
      done: !moreData,
      value: moreData ? this._array[this._index++] : undefined
    };
  }
}

let numbers = new NumberCollection();
numbers.add(30, 20, 10);
numbers.add(5);
for (let n of numbers) {
  console.log(n);
}

You can create iterator more easily using Generators, which will be discussed in another post.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s