JavaScript gets two new protocols in ES6, Iterators and Iterables. In plain terms, you can think of protocols as conventions. As long as you follow a determined convention in the language, you get a side-effect. The iterable protocol allows you to define the behavior when JavaScript objects are being iterated.
The code below is an iterable object in ES6.
var foo = {
[Symbol.iterator]: () => ({
items: ['p', 'o', 'n', 'y', 'f', 'o', 'o'],
next: function next () {
return {
done: this.items.length === 0,
value: this.items.shift()
}
}
})
}
Here is a quick snap-inĀ of iterators:
- Iterator and iterable protocol define how to iterate over any object, not just arrays and array-likes
- A well-known
Symbol
is used to assign an iterator to any object var foo = { [Symbol.iterator]: iterable}
, orfoo[Symbol.iterator] = iterable
- The
iterable
is a method that returns aniterator
object that has anext
method - The
next
method returns objects with two properties,value
anddone
- The
value
property indicates the current value in the sequence being iterated - The
done
property indicates whether there are any more items to iterate
- The
- Objects that have a
[Symbol.iterator]
value are iterable, because they subscribe to the iterable protocol - Some built-ins like
Array
,String
, orarguments
— andNodeList
in browsers — are iterable by default in ES6 - Iterable objects can be looped over with
for..of
, such asfor (let el of document.querySelectorAll('a'))
- Iterable objects can be synthesized using the spread operator, like
[...document.querySelectorAll('a')]
- You can also use
Array.from(document.querySelectorAll('a'))
to synthesize an iterable sequence into an array - Iterators are lazy, and those that produce an infinite sequence still can lead to valid programs
- Be careful not to attempt to synthesize an infinite sequence with
...
orArray.from
as that will cause an infinite loop