Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
jQuery Design Patterns

You're reading from   jQuery Design Patterns Write Elegant, Structured and Efficient jQuery

Arrow left icon
Product type Paperback
Published in Feb 2016
Publisher
ISBN-13 9781785888687
Length 246 pages
Edition 1st Edition
Tools
Arrow right icon
Author (1):
Arrow left icon
Thodoris Greasidis Thodoris Greasidis
Author Profile Icon Thodoris Greasidis
Thodoris Greasidis
Arrow right icon
View More author details
Toc

Table of Contents (13) Chapters Close

Preface 1. A Refresher on jQuery and the Composite Pattern FREE CHAPTER 2. The Observer Pattern 3. The Publish/Subscribe Pattern 4. Divide and Conquer with the Module Pattern 5. The Facade Pattern 6. The Builder and Factory Patterns 7. Asynchronous Control Flow Patterns 8. Mock Object Pattern 9. Client-side Templating 10. Plugin and Widget Development Patterns 11. Optimization Patterns Index

The Iterator Pattern

The key concept of the Iterator Pattern is the use of a function with the single responsibility to traverse a collection and provide access to its items. This function is known as the iterator and provides a way to access the items of the collection, without exposing implementation specifics and the underlying data structure used by the collection object.

Iterators provide a level of encapsulation regarding the way the iteration occurs, decoupling the iteration over the items of a collection from the implementation logic of their consumers.

Note

For more information on the Single Responsibility principle, you can visit http://www.oodesign.com/single-responsibility-principle.html.

How the Iterator Pattern is used by jQuery

As we saw earlier in this chapter, the jQuery core $() function returns an Array-like object that wraps a collection of page elements and it also provides an iterator function to traverse it and access each element individually. It actually goes one step further and provides a generic helper method jQuery.each() that can iterate over arrays, Array-like objects, and also object properties.

A more technical description can be found in jQuery API documentation page at http://api.jquery.com/jQuery.each/, where the description of jQuery.each() reads as follows:

A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and Array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties.

The jQuery.each() helper function is used internally in several places of the jQuery source code. One of its uses is iterating over the items of a jQuery object and applying manipulations on each of them, as the Composite Pattern suggests. A simple search for the keyword .each( reveals 56 matches.

Note

As of writing this book, the latest stable version is v2.2.0 and this was used for the above statistics.

We can easily trace its implementation in jQuery's source, either by searching for "each:" (note that there are two occurrences) or using the jQuery Source Viewer and searching for "jQuery.each()" (like we did earlier in this chapter):

each: function( obj, callback ) {
  var length, i = 0;

  if ( isArrayLike( obj ) ) {
    length = obj.length;
    for ( ; i < length; i++ ) {
      if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
        break;
      }
    }
  } else {
    for ( i in obj ) {
      if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
        break;
      }
    }
   }

  return obj;
}

This helper function is also accessible on any jQuery object by using the same prototypical inheritance that we saw earlier for methods such as .append(). You can easily find the code that does exactly this, by searching for "jQuery.fn.each()" in jQuery Source Viewer or directly searching jQuery source code for each: (note that there are two occurrences):

each: function( callback ) {
  return jQuery.each( this, callback );
}

Using the method version of ".each()" enables us to directly iterate over the elements of a jQuery collection object with a more convenient syntax.

The example code that follows showcases how the two flavors of .each() can be used in our code:

// using the helper function on an array
$.each([3, 5, 7], function(index){
    console.log(this + 1);
});
// using the method on a jQuery object
$('.boxContainer .box').each(function(index) {
    console.log('I\'m box #' + (index + 1)); // index is zero-based
});

When executed, the preceding code will log the following on the browser's console:

How the Iterator Pattern is used by jQuery

How it pairs with the Composite Pattern

Since the Composite Pattern encapsulates a collection of items into a single object and the Iterator Pattern can be used to iterate over an abstracted data structure, we can easily characterize these two patterns as complementary.

Where can it be used

The Iterator Pattern can be used in our applications to abstract the way we access items from a data structure. For example, let's suppose we need to retrieve all the items that are greater than 4 from the following tree structure:

var collection = { 
    nodeValue: 7, 
    left: { 
        nodeValue: 4, 
        left: 2, 
        right: { 
            nodeValue: 6, 
            left: 5, 
            right: 9 
        } 
    }, 
    right: { 
        nodeValue: 9, 
        left: 8 
    } 
}; 

Let's now implement our iterator function. Since tree data structures can have nesting, we end up with the following recursive implementation:

function iterateTreeValues(node, callback) { 
    if (node === null || node === undefined) { 
        return; 
    } 

    if (typeof node === 'object') { 
        if ('left' in node) { 
            iterateTreeValues(node.left, callback); 
        } 
        if ('nodeValue' in node) { 
            callback(node.nodeValue); 
        } 
        if ('right' in node) { 
            iterateTreeValues(node.right, callback); 
        } 
    } else { 
        // its a leaf, so the node is the value 
        callback(node); 
    } 
} 

Finally, we end up with an implementation that looks as follows:

var valuesArray = []; 
iterateTreeValues(collection, function(value) { 
    if (value > 4) { 
        valuesArray.push(value); 
    } 
}); 
console.log(valuesArray);

When executed, the preceding code will log the following on the browser's console:

► Array [ 5, 6, 9, 7, 8, 9 ]

We can clearly see that the iterator simplified our code. We no longer bother with the implementation specifics of the data structure used every time we need to access some items that fulfill certain criteria. Our implementation works on top of the generic API that the iterator exposes, and our implementation logic appears in the callback that we provide to the iterator.

This encapsulation allows us to decouple our implementation from the data structure used, given that an iterator with the same API will be available. For instance, in this example, we can easily change the data structure used to a sorted binary tree or a simple array and preserve our implementation logic the same.

You have been reading a chapter from
jQuery Design Patterns
Published in: Feb 2016
Publisher:
ISBN-13: 9781785888687
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image