Iterators
In JavaScript, an iterator is an object that enables accessing collection one by one. Iterators are employed for looping or iterating over various data structures, including arrays, strings, maps, sets, and more.
An iterator in JavaScript is an object that creates a sequence and, maybe, a return value when it reaches its conclusion.
In JavaScript, you must define an object that adheres to the iterator protocol to create an iterator. This protocol mandates the object to include a next() method, which returns an object containing two properties: value, representing the next value in the iteration, and done, indicating if the iteration is finished or not.
The Array iterator is the most frequently used iterator in JavaScript, and it sequentially returns each value in the corresponding array.
Here's an illustration of how to create an iterator for an array:
const arrayIterator = (array) => {
let index = 0;
return {
next: () => {
if (index < array.length) {
return {
value: array[index++],
done: false
};
} else {
return { done: true };
}
}
};
};
const myArray = [1, 2, 3];
const iterator = arrayIterator(myArray);
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()); // { done: true }
In this example, the arrayIterator function accepts an array as input and produces an iterator object. The iterator object possesses a next() method that retrieves the subsequent value in the array until it reaches the end, at which point it returns { done: true }.
You can use iterators with a for...of loop to iterate over the elements easily:
const myArray = [1, 2, 3];
const iterator = arrayIterator(myArray);
for (const element of iterator) {
console.log(element);
}
Output:
1
2
3
It is important to note that the for...of loop automatically invokes the next() method on the iterator and assigns the returned value to the loop variable (element in this case) until the iteration is concluded.
Iterators are extensively utilized in various JavaScript libraries and frameworks as they offer a standardized and convenient approach for iterating over diverse data structures.
Generator Functions
Generators provide a new method for interacting with iterators and functions in JavaScript.
A function's execution can be stopped at any point inside the function and resume running code from a stopped location, By using a generator.
While custom iterators can be valuable, their creation demands meticulous programming to explicitly manage their internal state. A powerful alternative is provided by generator functions, which allow you to define an iterative algorithm by writing a single function that doesn't execute continuously.
Generators are created by defining a generator function using the function* symbol. The resulting objects from these functions are known as generators.
// define a generator function
function* make_generator() {
... .. ...
}
// creating a generator
const generator_obj = make_generator();
Upon invocation, generator functions do not immediately execute their code. Instead, they yield a distinct type of iterator known as a Generator. When the next() method of the generator is called to consume a value, the Generator function runs until it reaches the yield keyword.
The function can be used as many times as needed, and each call results in a new Generator. There can only be one iteration for each Generator.
Example given below. This code behaves identically, but the implementation is considerably easier to write and read.
function* makeRangeIterator(start = 0, end = Infinity, step = 1) {
let Count = 0;
for (let i = start; i < end; i += step) {
Count++;
yield i;
}
return Count;
}
The return(value) method in generators allows you to return a specific value and effectively conclude the generator.