anonymouse anonymouse - 3 months ago 9
Javascript Question

Adding a custom iterator to a javascript class

I'm trying to figure out how to add an itertor to a javascript class such that the class could be used in a for...in loop. Following the instructions from Mozilla doesn't produce the results they claim it will.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators
Jsfiddle of given example: http://jsfiddle.net/KQayW/

function Range(low, high){
this.low = low;
this.high = high;
this.current = low;
this.next = function() {
if (this.current > this.range.high)
throw StopIteration;
else
return this.current++;
}
}
function RangeIterator(range){
this.range = range;
this.current = this.range.low;
}
RangeIterator.prototype.next = function(){
if (this.current > this.range.high)
throw StopIteration;
else
return this.current++;
};
Range.prototype.__iterator__ = function(){
return new RangeIterator(this);
};
var range = new Range(3, 5);
for (var i in range)
document.getElementById("test").innerHTML = i+"</br>"; // prints 3, then 4, then 5 in sequence


It doesn't print out the numbers in the range, it prints out "__iterator__"!

Does anyone know how to get this to work?

Answer

The Mozilla document state that the Iterators feature was introduced in JavaScript 1.7. Although Chrome supports some features from 1.7, it isn't fully supported so this does not work. If you test your code in the latest Firefox version though you will see it works.

Although you probably want to append the range value rather than replacing the entire div.

http://jsfiddle.net/KQayW/2/

function Range(low, high){
  this.low = low;
  this.high = high;
  this.current = low;
  this.next = function() {
  if (this.current > this.range.high)
    throw StopIteration;
  else
    return this.current++;
  }
}
function RangeIterator(range){
  this.range = range;
  this.current = this.range.low;
}
RangeIterator.prototype.next = function(){
  if (this.current > this.range.high)
    throw StopIteration;
  else
    return this.current++;
};
Range.prototype.__iterator__ = function(){
  return new RangeIterator(this);
};
var range = new Range(3, 5);
for (var i in range)
  document.getElementById("test").innerHTML += i+"</br>"; // prints 3, then 4, then 5 in sequence
Comments