Javascript Iterables and Iterators
Iterables and Iterators in JavaScript¶
- Iterator is an object which implements the iteration protocol.
- We have two iteration protocols
- The iterator protocol
- The iterable protocol
The iterator protocol¶
- The iterator protocol defines a standard way to produce a sequence of values (either finite or infinite), and potentially a return value when all values have been generated.
next()
- A function, with either zero arguments or one argument, that returns object with propertiesdone
andvalue
- done -
boolean
which represents whether next value available or not. - value - Any JavaScript value returned by the iterator.
- Let's see an example, how we can implement it.
const generateFibonacciIterator = (max=Infinity) => {
let n1 = 0;
let n2 = 0;
return {
next: () => {
let nextVal = n2 === 0 ? 1 : n1 + n2;
// update n1, n2
const prevVal = n2;
n2 = nextVal;
n1 = prevVal;
// set {done, value}
let done = false
if (nextVal >= max) {
nextVal = undefined
done = true
}
// return iteration object
return {done, value: nextVal}
}
}
}
// create iterator
const iterator = generateFibonacciIterator(5);
// now use `next()` method to get the value.
console.log(iterator.next());
// output: {done: false, value: 1}
console.log(iterator.next());
// output: {done: false, value: 1}
console.log(iterator.next());
// output: {done: false, value: 2}
console.log(iterator.next());
// output: {done: false, value: 3}
console.log(iterator.next());
// output: {done: true, value: undefined}
Note: we can't use it with the spread
...
operator orfor...of
constructor.
The iterable protocol¶
- The iterable protocol allows JavaScript objects to define or customize their iteration behavior, such as what values are looped over in a
for...of
construct. String
,Array
,TypedArray
,Map
, andSet
are all built-in iterables- Let's see an example, how we can implement it.
const myNumbersIterator = {
begin: 1,
end: 3,
// iterator built-in to work with spread `...` operator
[Symbol.iterator](){
this.current = this.begin;
return this;
},
next(){
if (this.current <= this.end) {
return { done: false, value: this.current++ };
} else {
return { done: true, value: undefined };
}
}
}
- Now, we can use above iterator with
for...of
construct like below.
for(const num of myNumbersIterator){
console.log(num);
}
/**
1
2
3
*/
// spread operator
console.log(myNumbersIterator)
// 1 2 3
Note:
Symbol.iterator
must be implemented to work with constructs likefor...of
,...
, etc.