tags:

views:

114

answers:

3

One of the new mechanisms available in JavaScript 1.7 is yield, useful for generators and iterators.

This is currently supported in Mozilla browsers only (that I'm aware of). What are some of the ways to simulate this behavior in browsers where it is not available?

+1  A: 

Without some sort of compiler or preprocessor… No.

The closest you can come is something like this:

function doStuff() {
    var result = { };
    function firstStuf() { ...; result.next = secondStuff; return 42; };
    function secondStuf() { ...; result.next = thirdStuff; return 16; };
    function thirdStuf() { ...; result.next = null; return 7; };
    result.next = firstStuff;
    return result;
}

But, well… That's pretty crappy, and really isn't much of a substitute.

David Wolever
+7  A: 

Well you could always write an outer function that initializes variables in a closure and then returns an object that does whatever work you want.

function fakeGenerator(x) {
  var i = 0;
  return {
    next: function() {
      return i < x ? (i += 1) : x;
    }
  };
}

Now you can write:

var gen = fakeGenerator(10);

and then call gen.next() over and over again. It'd be tricky to simulate the "finally" behavior of the "close()" method on real generators, but you might be able to get somewhere close.

Pointy
+2  A: 

Similar to Pointy's answer, but with a hasNext method:

MyList.prototype.iterator = function() { //MyList is the class you want to add an iterator to

    var index=0;
    var thisRef = this;

    return {
        hasNext: function() {
            return index < thisRef._internalList.length;
        },

        next: function() {
            return thisRef._internalList[index++];
        }
    };
};

The hasNext method let's you loop like:

var iter = myList.iterator() //myList is a populated instance of MyList
while (iter.hasNext())
{
    var current = iter.next();
    //do something with current
}
Robert Gowland
Thanks Robert, +1 for the addition of hasNext.
sworoc