In this article we are going to see how we can create our iterator and iterable objects. 😎
Usually when we are creating an Array object in JavaScript, we are creating an iterable object that have iterator Symbol (symbol is just data type like string, boolean, etc, for more information check out here), and this symbol object will let us go throw objects inside the array using for of loop. 🤗
Okay, first let's see our simple way of creating iterable objects 🧐
const ourArray = [1, 2, 3, 4, 5];
for (const el of ourArray) {
console.log(el);
}
// out put will be 1 2 3 4 5
Now let's create our own iterator and iterable 🤓
const ourOwnIterable = {
[Symbol.iterator]() {
return {
next: () => {
return {
value: 'This works',
done: false
}
}
}
}
}
That's it, now we have our own iterable, just because Symbol.iterator
will return the object that have next()
function, and that next()
function will return the object that contains value
and done
, and that's obvious what do they do, let's say we use for-of loop to go throw our iteratable object, when ever javascript see the done
is true, it will stop reading the objects and will close the loop.
But if we run this code right now, we will stuck into an infinite loop that will never end 🤢
To fix this and make our iterable object works fine, we need values, and the way to see if, we are done reading values ? first let's add some value to ourOwnIterable
object 😏
const ourOwnIterable = {
value: [1, 2, 3, 4, 5],
index: 0,
[Symbol.iterator]() {
return {
/**
* Our iterator will start here
* @returns {{value: *, done: boolean}}
*/
next: () => {
return {
value: this.value[this.index],
done: false
}
}
}
}
}
Now we have our values ready to be access able, using for-of loop, but still we need to implement some logic to set done
, to true when ever our iterator reach the last value
const ourOwnIterable = {
value: [1, 2, 3, 4, 5],
index: 0,
[Symbol.iterator]() {
return {
/**
* Our iterator will start here
* @returns {{value: *, done: boolean}}
*/
next: () => {
if(this.value.length === this.index) {
return {
value: null,
done: true
}
}
this.index++;
return {
value: this.value[this.index - 1],
done: false
}
}
}
}
}
That's it ! Now, we have our own iterable object that we can iterate throw values 🥱😁
And now we can use for-of loop on ourOwnIterable
object like so
for (const el of ourOwnIterable) {
console.log(el);
}
Thank you for your time 🤝
Hope you enjoy it ❤
Top comments (6)
Can I make it as easy as Python's
def __iter__(self)
andyield
?I know there is
yield
in JavaScript somewhere, but I never used it.Not that much easy.
But we can do something like this
Wow im programming with javascript since like 4 years and i have never used nor seen those generator functions. So definitely thank you for this hint!
Always thought the usage of the asterisks in declarations is limited to pointers in c and c++ 😅
Hi
Nice! But one thing I have to mention: If you use a fat arrow function for
next
there is no need forconst that = this
- always found this "hack" some kind of inelegant 😅😁
Should I edit 🙄
Yes 🙃