What is the purpose of Symbol.iterator and how do you use it?
Assesses fundamental understanding of JavaScript conventions, runtime behavior, and memory/performance considerations.
Hiring managers look for precision, avoidance of ambiguous jargon, and ability to explain trade-offs under real production conditions.
Symbol.iterator is a well-known symbol that specifies the default iterator for an object, making it iterable with for...of loops and spread operators.
// Built-in iterables use Symbol.iterator
const arr = [1, 2, 3];
const iterator = arr[Symbol.iterator]();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
Creating custom iterables:
class Range {
constructor(start, end) {
this.start = start;
this.end = end;
}
[Symbol.iterator]() {
let current = this.start;
const end = this.end;
return {
next() {
if (current <= end) {
return { value: current++, done: false };
}
return { done: true };
}
};
}
}
const range = new Range(1, 5);
for (const num of range) {
console.log(num); // 1, 2, 3, 4, 5
}
console.log([...range]); // [1, 2, 3, 4, 5]
Using generator function:
class Countdown {
constructor(start) {
this.start = start;
}
*[Symbol.iterator]() {
for (let i = this.start; i >= 0; i--) {
yield i;
}
}
}
const countdown = new Countdown(5);
console.log([...countdown]); // [5, 4, 3, 2, 1, 0]
Practical example - infinite sequence:
const fibonacci = {
[Symbol.iterator]() {
let prev = 0, curr = 1;
return {
next() {
[prev, curr] = [curr, prev + curr];
return { value: prev, done: false };
}
};
}
};
// Get first 10 fibonacci numbers
const fib10 = [];
for (const num of fibonacci) {
fib10.push(num);
if (fib10.length === 10) break;
}
console.log(fib10); // [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
Candidate Response Strategy & Interview Tips
- Start with a concise one-sentence summary: Deliver a direct, confident answer first before expanding into nuances.
- Demonstrate real-world trade-offs: Discuss where this approach excels and when you would avoid it in production systems.
- Discuss complexity & edge cases: Proactively explain time/space complexity or boundary conditions (null values, scale limits).
- Prepare for interviewer follow-ups: Technical hiring panels frequently probe deeper into concurrency, backward compatibility, or alternative libraries.