Skip to content

Instantly share code, notes, and snippets.

@domenic
Last active December 22, 2015 10:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save domenic/6458147 to your computer and use it in GitHub Desktop.
Save domenic/6458147 to your computer and use it in GitHub Desktop.
Iterators, iterables, generators

Definitions

An iterator is an object with a next method that returns { done, value } tuples.

An iterable is an object which has an internal method, written in the specs as obj[@@iterator](), that returns an iterator. It is not currently specified how to give your own objects such an internal method.

A generator is a specific type of iterator which also has a throw method, and whose next method takes a parameter.

A generator function is the source of a generator; you can send values or exceptions into the body of the function via the returned generator's next and throw methods. They are created with function* syntax.

A generator expression is a shorthand for creating generators, e.g. (for (x of a) for (y of b) x * y).

Interesting Facts

An iterator can also be iterable if it has a @@iterator() internal method. Most iterators in the ES6 spec are also iterable. In particular, all generators are iterable. So you can do

const lazySequence = (for (x of a) for (y of b) x * y);
for (let z in lazySequence) {
  console.log(z);
}

As noted, there is no way specced yet to make an arbitrary object iterable, so in particular arbitrary objects cannot work with for-of yet.

for-of works on iterables, i.e. you do for (let x of iterable) { /* ... */ }. So it works on arrays by looking up their @@iterator() internal method, which is specified to return an iterator that does what you'd expect. Similarly it works on Maps, Sets, etc.

for-in has nothing to do with iterables, or indeed any of the concepts discussed here. It still works on enumerable object properties and will be pretty useless when given an iterable of any sort.

I am not sure why generator expressions create generators instead of simple iterable iterators. In particular I don't know what calling throw or giving a parameter to next would do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment