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