Free Online Code Editor
Make objects iterable with custom iterators.
// Basic iterator
const iterable = {
[Symbol.iterator]() {
let step = 0;
return {
next() {
step++;
if (step <= 3) {
return { value: step, done: false };
}
return { done: true };
}
};
}
};
for (const val of iterable) {
console.log(val); // 1, 2, 3
}
// Custom range iterator
class Range {
constructor(start, end, step = 1) {
this.start = start;
this.end = end;
this.step = step;
}
[Symbol.iterator]() {
let current = this.start;
const end = this.end;
const step = this.step;
return {
next() {
if (current <= end) {
const value = current;
current += step;
return { value, done: false };
}
return { done: true };
}
};
}
}
const range = new Range(1, 10, 2);
console.log([...range]); // [1, 3, 5, 7, 9]
// Iterable object
class LinkedList {
constructor() {
this.head = null;
}
add(value) {
const node = { value, next: null };
if (!this.head) {
this.head = node;
} else {
let current = this.head;
while (current.next) {
current = current.next;
}
current.next = node;
}
}
[Symbol.iterator]() {
let current = this.head;
return {
next() {
if (current) {
const value = current.value;
current = current.next;
return { value, done: false };
}
return { done: true };
}
};
}
}
const list = new LinkedList();
list.add(1);
list.add(2);
list.add(3);
for (const val of list) {
console.log(val); // 1, 2, 3
}
// Bidirectional iterator
class Counter {
constructor(start, end) {
this.start = start;
this.end = end;
}
[Symbol.iterator]() {
let current = this.start;
const end = this.end;
let direction = 1;
return {
next() {
if (current <= end && direction === 1) {
const value = current;
current++;
return { value, done: false };
}
return { done: true };
},
return() {
console.log("Iterator cleaned up");
return { done: true };
}
};
}
}
const counter = new Counter(1, 3);
for (const val of counter) {
console.log(val);
}
// Spread operator works with iterables
const arr = [...new Range(1, 5)];
console.log(arr); // [1, 2, 3, 4, 5]
// Destructuring works too
const [first, second, ...rest] = new Range(1, 5);
console.log(first, second, rest);Implement [Symbol.iterator]() to make objects iterable. Return object with next() method. next() returns {value, done}. Works with for...of, spread, destructuring.