Web App Development

Javascript 1.7- generators with the yield keyword

Javascript 1.7 is specific to Firefox (2.0+). The yield keyword is not part of EcmaScript 5.1.

What are iterators/generators?

An iterator is like a function that returns an array, except that it can return values one by one. That way the function that is calling the iterator can react to the new value before fetching the next one - using the next function.
A generator is a function that generates an iterator, typically using the yield keyword.

Generating a prime number iterator


<script type="text/javascript;version=1.7">
function primeNumbers()
{
var nextPotentialPrime = 2;
while (true)
{
document.write("Checking if " + nextPotentialPrime + " is a prime number.<br>");
if (isPrime(nextPotentialPrime))
{
yield nextPotentialPrime;
}
nextPotentialPrime++;
}
}

// Let's get the first 5 prime numbers
var primeNumberGenerator = primeNumbers(); // generate the iterator
for(var i=0; i<5; i++)
{
document.write(primeNumberGenerator.next() + " is a prime number.<br>")
}

//Just a helper function, not relevant to Javascript generators
function isPrime(num)
{
for (var i = 2; i < num; i++)
{
if (num % i == 0)
{
return false;
}
}
return true;
}
</script>
Output:

Checking if 2 is a prime number.
2 is a prime number.
Checking if 3 is a prime number.
3 is a prime number.
Checking if 4 is a prime number.
Checking if 5 is a prime number.
5 is a prime number.
Checking if 6 is a prime number.
Checking if 7 is a prime number.
7 is a prime number.
Checking if 8 is a prime number.
Checking if 9 is a prime number.
Checking if 10 is a prime number.
Checking if 11 is a prime number.
11 is a prime number.

Make sure to put Javascript 1.7 as the version into the type attribute of the <script> tag and use Firefox. Otherwise you'll get an error:


Error: SyntaxError: missing ; before statement
yield nextPotentialPrime;

This is needed because yield was not a reserved word before Javascript 1.7.

You can see that the function for checking if the number is a prime isn't called until we're actually ready to print it.

Terminating iterators and non-terminating iterators

The example above generates a non-terminating iterator. In theory you can always get a prime number bigger than the last one by calling primeNumberGenerator.next.
A terminating iterator only works a limited number of times. That means you can also use it in a for .. in loop without creating an infinite loop. If you use next and request more values than available a StopIteration exception will be raised.
Here's an example of a terminating iterator:


<script type="text/javascript;version=1.7">
function numbers(count)
{
for (var i=0; i<count; i++)
{
yield i;
}
}
var numberIterator = numbers(10);
for (var number in numberIterator)
{
document.write(number + " ");
}
</script>
Output:

0 1 2 3 4 5 6 7 8 9

Comments


Follow me on Twitter