JavaScript Iterables

Objects that can be iterated over with for...of

πŸ”„ What are Iterables?

Iterables are objects that implement the iterable protocol, meaning they can be looped over with for...of. They have a Symbol.iterator method that returns an iterator.


// Built-in iterables
const array = [1, 2, 3];        // Array is iterable
const string = "Hello";         // String is iterable
const set = new Set([1, 2, 3]); // Set is iterable

// All can be used with for...of
for (const item of array) {
    console.log(item);
}
                                    

Output:

1
2
3

Built-in Iterables

πŸ“‹

Arrays

Most common iterable

const arr = [1, 2, 3];
for (const num of arr) {
    console.log(num);
}
πŸ“

Strings

Character by character

const str = "Hi";
for (const char of str) {
    console.log(char);
}
πŸ—‚οΈ

Sets

Unique values collection

const set = new Set([1, 2]);
for (const val of set) {
    console.log(val);
}
πŸ—ΊοΈ

Maps

Key-value pairs

const map = new Map([['a', 1]]);
for (const [k, v] of map) {
    console.log(k, v);
}

πŸ”Ή Testing for Iterables

You can check if an object is iterable:

function isIterable(obj) {
    return obj != null && typeof obj[Symbol.iterator] === 'function';
}

// Test different objects
console.log(isIterable([1, 2, 3]));        // true
console.log(isIterable("Hello"));          // true
console.log(isIterable(new Set()));        // true
console.log(isIterable(new Map()));        // true
console.log(isIterable({a: 1}));           // false
console.log(isIterable(123));              // false

Output:

true
true
true
true
false
false

πŸ”Ή Creating Custom Iterables

You can make your own objects iterable by implementing Symbol.iterator:

// Custom iterable object
const countdown = {
    start: 5,
    end: 1,
    
    // Make it iterable
    [Symbol.iterator]() {
        let current = this.start;
        const end = this.end;
        
        return {
            next() {
                if (current >= end) {
                    return { value: current--, done: false };
                } else {
                    return { done: true };
                }
            }
        };
    }
};

// Now we can use for...of
for (const num of countdown) {
    console.log(num);
}

Output:

5
4
3
2
1

πŸ”Ή Iterable Methods

Many JavaScript methods work with iterables:

const numbers = [1, 2, 3, 4, 5];

// Array.from() - creates array from iterable
const doubled = Array.from(numbers, x => x * 2);
console.log(doubled);

// Spread operator - spreads iterable
const moreNumbers = [...numbers, 6, 7];
console.log(moreNumbers);

// Set constructor - accepts iterable
const uniqueNumbers = new Set(numbers);
console.log(uniqueNumbers);

// Math.max with spread
const max = Math.max(...numbers);
console.log(`Max: ${max}`);

Output:

[2, 4, 6, 8, 10]
[1, 2, 3, 4, 5, 6, 7]
Set(5) {1, 2, 3, 4, 5}
Max: 5

πŸ”Ή Practical Example: Range Function

Create a useful range iterable like Python's range():

function range(start, end, step = 1) {
    return {
        [Symbol.iterator]() {
            let current = start;
            
            return {
                next() {
                    if (current < end) {
                        const value = current;
                        current += step;
                        return { value, done: false };
                    }
                    return { done: true };
                }
            };
        }
    };
}

// Use the range function
console.log("Numbers 1 to 5:");
for (const num of range(1, 6)) {
    console.log(num);
}

console.log("Even numbers 0 to 10:");
for (const num of range(0, 11, 2)) {
    console.log(num);
}

Output:

Numbers 1 to 5:
1
2
3
4
5
Even numbers 0 to 10:
0
2
4
6
8
10

🧠 Test Your Knowledge

Which of these is NOT a built-in iterable?