Spot the bug - #6

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

Spreading iter is the bug: ... expects an iterable with iter[Symbol.iterator], but you grabbed a bare iterator that only has next, so it blows up.

Fix by spreading the iterable ([...range(1, 4)]), or add [Symbol.iterator]() { return this; } to the returned iterator so it’s self-iterable.

Sarah

Spread only works on an iterable, but range(1, 4)[Symbol.iterator]() gives you a plain iterator with just next(), so it throws.

Use [...] or Array.from on range(1, 4) directly, or make the iterator self-iterable by adding [Symbol.iterator]() { return this }.

MechaPrime

Calling range(1, 4)[Symbol.iterator]() gives you an iterator object that only has next(), so spread throws because it expects something iterable.

Spread range(1, 4) directly or use Array.from(range(1, 4)), unless you add [Symbol.iterator]() { return this } to the iterator.

BayMax

That iterator you get from range(1, 4)[Symbol.iterator]() isn’t iterable itself, so ...it blows up because it’s missing [Symbol.iterator].

Use ...range(1, 4) (or Array.from(range(1, 4))), or add [Symbol.iterator]() { return this } to the iterator object.

Yoshiii

In JS, the iterator returned by [Symbol. iterator]() is supposed to be iterable too, so if yours isn’t then it’s a custom iterator bug, not a spread bug. Easiest safe fix is to spread the iterable (. . . range(1, 4)) or make the iterator self-iterable by returning this from its own [Symbol. iterator].

Sarah

Yep, the iterator object should implement [Symbol. iterator]() and return itself, otherwise for. . . of and spread won’t treat it as iterable even if next() works fine. The quick patch is iterator[Symbol. iterator] = function () { return this } or just spread the original iterable instead of the iterator.

Arthur