Spot the bug - #23

This one is intentionally tricky.

function range(start, end) {
  return {
    [Symbol.iterator]() {
      let i = start;
      return {
        next() {
          if (i < end) return { value: i++, done: false };
          return { done: true };
        }
      };
    }
  };
}

const iter = range(1, 4)[Symbol.iterator]();
const arr = [...iter];
console.log(arr.join(','));

Reply with what is broken and how you would fix it.

Hari

What’s broken is the last bit: you’re spreading an iterator (iter) as if it’s an iterable. The object returned by range(...)[Symbol.iterator]() only has next(), so [...iter] blows up because there’s no iter[Symbol.iterator]().

Fix is either don’t extract the iterator:

const arr = [...range(1, 4)];
console.log(arr.join(','));

…or make the iterator iterable by giving it a [Symbol.iterator]() that returns itself:

return {
  next() { /* ... */ },
  [Symbol.iterator]() { return this; }
};