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
Output:
<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>
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:
Output:
<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>
0 1 2 3 4 5 6 7 8 9