Question

I'm trying to understand how an enumerator for a JavaScript object can be written. I came across a certain piece of Sharepoint code where items of a SP List were being obtained on the client side, and code similar to the one below was being performed on a Sharepoint object.

var enumerator = list.getEnumerator();
while(enumerator.moveNext()) {
    var currentItem = enumerator.getCurrent();
    // actions on currentItem
}

If I could write a custom object that could be iterated upon using an enumerator as above, how would it look? This is my attempt, but it doesn't work:

var list = {
    items: ["A", "B", "C", "D", "E"],
    counter: -1,
    enumerator: {
        moveNext: function() {
            counter++; // outer object's variable not accessible
            if(counter >= items.length)
                return false;
            else
                return true;
        },
        getCurrent: function() {
            return items[counter]; // outer object's variable not accessible
        }
    },
    getEnumerator: function() { 
        return this.enumerator(); 
    }
}

var enumerator = list.getEnumerator();
while(enumerator.moveNext()) {
    var currentItem = enumerator.getCurrent();
    alert(currentItem);
}

Can you help me understand how getEnumerator() could be written as a function prototype that is applicable to any enumerable object?

Was it helpful?

Solution 3

Thanks to pointers from @xdazz and @Juan Mendes, I was able to work out the enumerator function prototype:

Array.prototype extension:

Array.prototype.getEnumerator = Array.prototype.getEnumerator ||
function() {
    var items = this;
    var counter = -1;
    var enumerator = {
        moveNext: function() {
            counter++; 
            return (counter < items.length);
        },
        getCurrent: function() {
            return items[counter]; 
        }
    }
    return enumerator;
};

Usage:

var list = ["A", "B", "C", "D", "E"];

var enumerator = list.getEnumerator(); // makes any array enumerable
while(enumerator.moveNext()) {
    var currentItem = enumerator.getCurrent();
    alert(currentItem);
}

JSFIDDLE DEMO

OTHER TIPS

Try below:

var list = function() {
    // these local variables could be accessed by inner functions.
    var items = ["A", "B", "C", "D", "E"],
        counter =  -1;
    return {
        enumerator: {
            moveNext: function() {
                counter++; 
                return counter < items.length;
            },
            getCurrent: function() {
                return items[counter]; 
            }
        },
        getEnumerator: function() { 
            // here should not be return this.enumerator() but just this.enumerator
            return this.enumerator; 
        }
    };
};

var enumerator = list().getEnumerator();
while(enumerator.moveNext()) {
    var currentItem = enumerator.getCurrent();
    alert(currentItem);
}

THE JSFIDDLE DEMO.

You can access the variables using list.

var list = {
    items: ["A", "B", "C", "D", "E"],
    counter: -1,
    enumerator: {
        moveNext: function() {
            list.counter++; // outer object's variable not accessible
            if(list.counter >= list.items.length)
                return false;
            else
                return true;
        },
        getCurrent: function() {
            return list.items[list.counter]; // outer object's variable not accessible
        }
    },
    getEnumerator: function() { 
        return list.enumerator; 
    }
}

Or you can make a function to create instances of it

function makeList(items) {
    var list = {
        items: items
        counter: -1,
        enumerator: {
            moveNext: function() {
                list.counter++; // outer object's variable not accessible
                if(list.counter >= list.items.length)
                    return false;
                else
                    return true;
            },
            getCurrent: function() {
                return list.items[list.counter];
            }
    },
    getEnumerator: function() { 
        return list.enumerator; 
    }
    return list;
}


var enumerator = makeList(["A", "B", "C", "D", "E"]).getEnumerator();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top