Design pattern – Iterator pattern

The iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing the internal representation of object 5.

The iterator pattern separates the process of iterating from the business logic. After using the iterator pattern, each element of an object can be accessed sequentially, even without caring about its internal construction.

Examples include Javascript forEach, map, some, etc.

Iterators can be divided into the following two types:

  • Inner iterator
  • External iterator

Inner iterator

The iteration rules are defined internally and it takes over the entire iteration process completely, with only one initial call required externally.

  • Such as:
function each(ary, callback) {
    for (let i = 0; i < ary.length; i++){
        callback.call(ary[i], i, ary[i]);
    }
}
each([1.2.3].(i, n) = > alert([i, n]));
Copy the code

Summary: The inner iterator invocation is simple, but its scope of application is relatively narrow.

External iterator

You must explicitly request an iteration of the next element.

External iterators add some complexity to the calls, but they also increase the flexibility of the iterators, allowing us to manually control the iteration process or sequence.

var Iterator = function( obj ){
    var current = 0;
    var next = function(){
        current += 1;
    };
    var isDone = function(){
        return current >= obj.length;
    };
    var getCurrItem = function(){
        return obj[ current ];
    };
    return {
        next: next,
        isDone: isDone,
        getCurrItem: getCurrItem
    }
};
Copy the code

Conclusion: Although external iterators are called in a relatively complex way, they are more widely applicable and can meet more varied needs. There is no better internal iterator than external iterator in actual production, and the choice of which to use depends on the requirements scenario.

Iterating over array-like objects and literals

The iterator pattern can iterate not only over arrays, but also over some array-like objects.

An inner or outer iterator can be iterated over as long as the iterated aggregate object has the length attribute and can be accessed with subscript.

Arguments, {‘0’: ‘a’, ‘1’: ‘b’}

// Iterators support traversal of class arrays and objects
function each(obj, callback) {
    var value, i = 0, length = obj.length, isArray = isArraylike( obj );
    if ( isArray ) {
        for(; i < length; i++ ) { value = callback.call( obj[ i ], i, obj[ i ] );if ( value === false ) {
                break; }}}else {
        // Iterate over the object
        for ( i in obj ) {
            value = callback.call( obj[ i ], i, obj[ i ] );
            if ( value === false ) {
                break; }}}return obj;
};
Copy the code

Inverse-order iterators

A sequence of numbers traversed from end to end.

Abort iterator

During traversal, iterations can be terminated if certain conditions are met.

function each(ary, callback){
    for (let i = 0; i < ary.length; i++){
        // Callback returns false, prematurely terminating the iteration
        if (callback(i, ary[i]) === false) {break; }}};Copy the code

Examples of the iterator pattern

  • The nodejsexpressFramework of middleware ideas, processing requests usednext()The method is the iterator pattern.
  • ECMAScript 6Iterator(Traverser) andGeneratorUsed in asynchronous programmingnext()

reference

JavaScript design patterns and development practices