Iterator and Generator in ES6

Iterator and Generator are commonly used features in ES6. In this post, we will walk through the key features of iterator and generator in depth.

Iterator

In JavaScript, an object can be iterated due to it has an inner-built property/object: iterator (which objects?). So in order to let an ordinary object can be iterator, we can add iterator to this object manually.

// add iterator to user object
let user = {
  name: "sam", totalReplies: 17, isBlocked: false
};

user[Symbol.iterator] = function(){

  let properties = Object.keys(this);
  let count = 0;
  let isDone = false;

  let next = () => {
    if(count >= properties.length){
      isDone = true;
    }

    let value = this[properties[count++]];

    return { done: isDone, value:{value} };
  };
  return { next };
};

// iterate user object
let values = [...user];
console.log(values);

https://gist.github.com/arkilis/3e18e939aa527c41a4c3acbe5bf918e9#file-manualiteraleobject-js

Generator

Generator functions are functions defined with *. They are can be treated as special functions that using keyword yield to return iterator objects.


// Define a generator function
function *nameList(){
    yield "Sam";    // =>  {done: false, value: "Sam"} 
    yield "Tyler";  // =>  {done: false, value: "Tyler"} 
}


//Call generator function
for(let name of nameList()){
    console.log(name);
}

// using spread operator
let names = [...nameList()];
console.log( names );

// using deconstructor
let [first, second] = nameList();
console.log(first, second);

With generator return {done: false, value: "Sam"}, we can shorten the our man-crafted iterable object user as following:

let user = {
  name: "sam", totalReplies: 17, isBlocked: false
};

user[Symbol.iterator] = function *(){

  let properties = Object.keys(this);
  let count = 0;
  let isDone = false;

  for(let p of properties){
    yield this[p];
  }
};

for(let p of user){
  console.log( p );
}

comments powered by Disqus