PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Eight Weeks of Prototype: Week 6, Writing JavaScript Classes with Prototype

Creating Custom Enumerables

In the third article of this series I discussed enumerables in Prototype, including arrays and hashes. As mentioned in that article, it is possible to create your own enumerable types. If you use PHP, you may be familiar with the Iterator interface. This is in effect the same thing, but for JavaScript instead.

While an array enumerable is used for looping over each element in an array, when creating your own enumerable you decide what constitutes each value in the enumeration.

To do so, you must extend the Enumerable class and then create a method in your class called _enum(). This method accepts a single argument, which is the iterator function that is to be called for each element.

Listing 18 shows an example of creating a custom enumerable, which I have called People. This class is used to hold a collection of Person objects (refer to Listing 16). After adding several Person objects, we loop over the People instance and show each Person on the page. Note that we are also making using of the toString() method discussed in the previous section.

Listing 18 Creating a custom enumerable object (listing-18.html)
<html>
    <head>
        <title>Creating a custom enumerable object</title>
        <script type="text/javascript" src="/js/prototype.js"></script>
        <script type="text/javascript" src="/js/Person.js"></script>
    </head>
    <body>
        <div id="foo"></div>
 
        <script type="text/javascript">
            var People = Class.create(Enumerable, {
 
                people : [],
 
                add : function(person)
                {
                    this.people.push(person)
                },
 
                _each : function(iterator)
                {
                    for (var i = 0, length = this.people.size(); i < length; i++)
                        iterator(this.people[i]);
                }
            });
 
            var people = new People();
 
            people.add(new Person('Quentin Zervaas'));
            people.add(new Person('Joe Bloggs'));
 
            people.each(function(person, i) {
                var num = i + 1;
                $('foo').insert(num + '. ' + person + '<br />');
            });
        </script>
    </body>
</html>

Realistically in this code the enumeration is simply looping over an array anyway, but the point is that the code calling the class doesn't care about the internal implementation; it simply knows that when it loops over the instance of People it's going to receive an instance of Person inside the iterator.

In This Article