- Home
- /
- Tutorials
- /
- JavaScript Tutorial
- /
- JavaScript Iterables
JavaScript Generators & Iterators
JavaScript Iterables
An iterable is anything with a Symbol.iterator method, which is what for...of actually looks for.
An iterable is anything with a
Symbol.iteratormethod, which is whatfor ofactually looks for.
Iterable and iterator sound alike but mean different things.
An iterable knows how to produce an iterator; the iterator does the actual work.
Example
Example
javascript
const numbers = [1, 2, 3];
console.log(typeof numbers[Symbol.iterator]);
for (const n of numbers) {
console.log(n);
}for of calls that method behind the scenes.
Iterable Versus Iterator
An iterable has a [Symbol.iterator]() method.
Calling that method returns an iterator.
for of, spread and destructuring all rely on this.
Syntax
Syntax
javascript
for (const value of iterable) {
// one value per turn
}Anything without Symbol.iterator cannot be used here.
What Counts as Iterable
Arrays, strings, Maps and Sets all qualify.
Example
Example
javascript
console.log(typeof [][Symbol.iterator]);
console.log(typeof "text"[Symbol.iterator]);
console.log(typeof new Map()[Symbol.iterator]);
console.log(typeof new Set()[Symbol.iterator]);All four report function.
Plain Objects Are Not Iterable
This is exactly why for of throws on one.
Example
Example
javascript
const settings = { theme: "dark" };
let message;
try {
for (const value of settings) {
message = "looped";
}
} catch (error) {
message = error.name;
}
console.log(message);The output is TypeError.
Spread Needs Iterable Too
Spreading an object into an array fails for the same reason.
Example
Example
javascript
const numbers = [1, 2, 3];
console.log([...numbers].length);
let message;
try {
[...{ a: 1 }];
} catch (error) {
message = error.name;
}
console.log(message);Spreading an array works; spreading a plain object as a list does not.
Destructuring Also Relies on It
Array destructuring is short for calling the iterator repeatedly.
Example
Example
javascript
const colours = ["red", "green", "blue"];
const [first, second] = colours;
console.log(first + " " + second);Object destructuring works differently and does not need this protocol.
Object Spread Is a Different Feature
Spreading a plain object with { ...obj } copies properties, unrelated to iteration.
It is easy to mix the two up, since both use three dots.
Example
Example
javascript
const settings = { theme: "dark" };
const copy = { ...settings };
console.log(copy.theme);This works because object spread has its own separate rule, not the iterable protocol.
Complete Example
Complete Example
html
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Iterables</title>
</head>
<body>
<h1>Iterables</h1>
<p id="out"></p>
<script>
const values = new Set([1, 2, 3]);
const list = [];
for (const value of values) {
list.push(value);
}
document.getElementById("out").textContent =
"From a Set: " + list.join(", ");
</script>
</body>
</html>Try It Yourself
Run the above example in the Try It Editor.
Try a Map:
Loop over new Map([["a", 1]]) and see each entry arrive as a pair.
Important Points
- An iterable has a
Symbol.iteratormethod. - Arrays, strings, Maps and Sets are all iterable.
- Plain objects are not, so
for ofthrows on one. - Spread and destructuring both rely on being iterable.
- Object spread with
{ ...obj }is a separate feature.
Conclusion
Being iterable is what unlocks for of, spread and destructuring.
Plain objects opt out, which is a deliberate design choice, not an oversight.
The next lessons show how to make your own values iterable.
