JavaScript設計模式 - 迭代器模式

迭代器模式是指提供一種方法順序訪問一個聚合對象中的各個元素,而又不須要暴露該對象的內部表示。
迭代器模式能夠把迭代的過程從業務邏輯中分離出來,在使用迭代器模式以後,即便不關心對象的內部構造,也能夠按順序訪問其中的每一個元素
許多瀏覽器都支持 Javascript  Array.prototype.forEach
迭代器能夠分爲 內部迭代器 和 外部迭代器

1、jQuery 中的迭代器
1 $.each( [1,2,3,4], function (i, n) {
2     console.log( "當前下表爲:" + i + " , 當前值爲:" + n );
3 });

 


2、自實現一個迭代器
1 // 本身實現一個數組迭代器
2 var each = function( arry, callback ){
3     for( var i = 0, l = arry.length; i < l; i++){
4         callback.call( arry[i], i, arry[ i ]);
5     }
6 };
7 each([1,2,3,4], function (i, n) {
8     console.log( i + " - " + n ); // 輸出數組下標和值
9 });

 

3、內部迭代器

  上邊的 each 函數屬於內部迭代器, each 函數內部已經定義好了迭代原則,它徹底接手整個迭代過程,外部只須要一次初始調用。
  內部迭代器的優勢也恰好是它的缺點 - 使用方便,迭代交互也僅僅是一次初始調用
  示例: 在不改寫 each 自己的代碼前提,實現判斷兩個數組裏元素的值是否徹底相等
 1 //判斷兩個數組的值是否徹底相等
 2 var compare = function( arry1, arry2){
 3     if( arry1.length !== arry2.length ){
 4         throw new Error( "arry1和arry2不相等" );
 5     }
 6     each( arry1, function( i, n ){
 7         if( n !== arry2[i] ){
 8             throw new Error("arry1和arry2不相等");
 9         }
10     });
11     console.log( "arry1和arry2相等" );
12 };
13 
14 compare( [1,2,3,4], [1,2,3]);
 

 

 4、外部迭代器
  外部迭代器必須顯式地請求迭代下一個元素
  外部迭代器增長了一些調用的複雜度,但相對的也加強了迭代器的靈活性,咱們能夠手工控制迭代的過程或者順序
  示例: 重寫 compare

    外部迭代器:

 1 // 外部迭代器
 2 var Iterator = function (obj) {
 3         var current = 0;
 4 
 5         var next = function(){
 6             current += 1;
 7         };
 8 
 9         var isDone = function(){
10             return current >= obj.length;
11         };
12 
13         var getCurrItem = function(){
14             return obj[ current ];
15         };
16 
17     return {
18         next: next,
19         isDone: isDone,
20         getCurrItem: getCurrItem
21     }
22 }
View Code
 

 

 
    改寫 Compare   
 1 // 改寫 Compare
 2 var compare = function( iterator1, iterator2 ){
 3     while( iterator1.isDone() && iterator2.isDone() ){
 4         if( iterator1.getCurrItem() !== iterator2.getCurrItem() ){
 5             throw new Error( "iterator1 和 iterator2不相等" );
 6         }
 7         iterator1.next();
 8         iterator2.next();
 9     }
10     console.log( "iterator1 和 iterator2相等" );
11 };
12 
13 var iterator1 = Iterator( [1,2,3,4] );
14 var iterator2 = Iterator( [1,2,3,4] );
15 
16 compare(iterator1,iterator2);
View Code
 

 

 5、停止迭代器
  重寫 each 函數實現停止迭代
 1 // 重寫 each 函數實現停止迭代
 2 var each = function( arry, callback ){
 3     for( var i = 0, l = arry.length; i < l; i++ ){
 4         // callback 的執行結果返回false,提早停止迭代
 5         if( callback( i, arry[i] ) === false ){
 6             break;
 7         }
 8     }
 9 };
10 each( [1,2,3,4,5], function ( i, n ) {
11     if( n>3 ){ // n 大於3的時候停止循環
12         return false;
13     }
14     console.log(n); // 輸出 1 2 3
15 });
View Code
 

 

 6、迭代器應用示例
  目的:根據不一樣的瀏覽器獲取相應的上傳組件對象
    
    將不一樣的上傳對象封裝到各自的函數裏; 若是函數可用,則返回該對象,不然返回false,提示迭代器繼續
 1 // 將不一樣的上傳對象封裝到各自的函數裏; 若是函數可用,則返回該對象,不然返回false,提示迭代器繼續
 2 var getActiveUploadObj = function(){
 3     try{
 4         return new ActiceXObject( "TXFTNActiveX.FTNUpload" ); // IE 上傳控件
 5     }catch(e){
 6         return false;
 7     }
 8 };
 9 var getFlashUploadObj = function(){
10     if( supportFlash() ){
11         var str = "<object type='application/x-shockwave-flash'></object>";
12         return $( str).appendTo( $("body") );
13     }
14     return false;
15 };
16 var getFormUpl0adObj = function(){
17     var str = "<input type='file' type='file' class='ui-file' />"; // 表單上傳
18     return $( str).appendTo( $("body") );
19 };
View Code
     //迭代器代碼
 1 //迭代器代碼
 2 var iteratorUploadObj = function(){
 3     for( var i = 0, fn; fn = arguments[ i++ ]; ){
 4         var uploadObj = fn();
 5         if( uploadObj !== false ){
 6             return uploadObj;
 7         }
 8     }
 9 };
10 
11 var uploadObj = iteratorUploadObj( getActiveUploadObj, getFlashUploadObj, getFormUpl0adObj );
View Code
 

 

7、總結
迭代模式相對簡單,簡單到不少時候咱們不認爲它是一種設計模式
閱讀參考書籍 - << JavaScript 設計模式與開發實踐 >>
相關文章
相關標籤/搜索