Whats happening under the hood here - iterators

Hey campers,

let person = {
  fname: 'Chandler',
  lname: 'Bing' 
};

person[Symbol.iterator] = function() {
  let properties = Object.keys(person);
  let count = 0;
  let isDone = false;
  let next = () => {
    if (count >= properties.length)
      isDone = true;
    return { done: isDone,
             value: this[properties[count++]]}
  }
  return {next}
}

console.log(person[Symbol.iterator]().next())   // {done: false, value: "Chandler"}
console.log(person[Symbol.iterator]().next())   // {done: false, value: "Chandler"}
console.log(person[Symbol.iterator]().next())   // {done: false, value: "Chandler"}

this doesn’t work, the next method is supposed to iterate over person

if the bottom is changed this works however

var it = person[Symbol.iterator]()

console.log(it.next())    //  {done: false, value: "Chandler"}
console.log(it.next())    //  {done: false, value: "Bing"}
console.log(it.next())    //  {done: true, value: undefined}

shouldn’t these be doing the exact same thing?

Not sure the name of this pattern / technique but…
in the 1st example you are calling the function person[Symbol.iterator]() 3 times and also next() 3 times.
where as…
in the 2nd example you are calling the function person[Symbol.iterator]() 1 time & next() 3 times.

So the first function person[Symbol.iterator]() is resetting the values each time.
(presumably because it sets count to zero).
Is this a closure example?

I understand it now I believe, the returned object has a closure over the function (and its scope) so the count variable is incremented whenever the function next is invoked.

it was an example of how to make an iterator for an object so that the object can be used I a for…of loop. (https://www.youtube.com/watch?v=0kHJgw6Li_4)

thank you for the help

1 Like