Create our own iterable in JavaScript

Alireza Razinejad - Nov 26 '20 - - Dev Community

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
Enter fullscreen mode Exit fullscreen mode

Now let's create our own iterator and iterable 🤓

const ourOwnIterable = {
    [Symbol.iterator]() {
        return {
            next: () => { 
                return {
                    value: 'This works',
                    done: false
                }
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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
                }
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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
                }
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

Thank you for your time 🤝
Hope you enjoy it ❤

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player