zoukankan      html  css  js  c++  java
  • JavaScript设计模式

    迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
    迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素
    许多浏览器都支持 Javascript  Array.prototype.forEach
    迭代器可以分为 内部迭代器 和 外部迭代器

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

    二、自实现一个迭代器
    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 });
    三、内部迭代器

      上边的 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]);
    
    
    
     四、外部迭代器
      外部迭代器必须显式地请求迭代下一个元素
      外部迭代器增加了一些调用的复杂度,但相对的也增强了迭代器的灵活性,我们可以手工控制迭代的过程或者顺序
      示例: 重写 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
    
    
    
     五、中止迭代器
      重写 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
    
    
    
     六、迭代器应用示例
      目的:根据不同的浏览器获取相应的上传组件对象
        
        将不同的上传对象封装到各自的函数里; 如果函数可用,则返回该对象,否则返回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
    
    
    
    七、总结
    迭代模式相对简单,简单到很多时候我们不认为它是一种设计模式
    阅读参考书籍 - << JavaScript 设计模式与开发实践 >>
  • 相关阅读:
    java调用restful webservice(转)
    精心挑选的12款优秀 jQuery Ajax 分页插件和教程
    android shape的使用
    android 获取资源文件 r.drawable中的图片转换为drawable、bitmap
    jquery+ajax分页
    ImageButton自定义按钮的按下效果的高效实现方法(非一般)
    ActionBarSherlock SlidingMenu整合,解决SlidingMenu example的getSupportActionBar()方法不能用问题
    sdk manager更新失败,显示Download interrupted: read timed out,应该如何解决?
    Android SDK 下载速度慢解决方法
    android 让图片充满整个屏幕
  • 原文地址:https://www.cnblogs.com/Medeor/p/5017879.html
Copyright © 2011-2022 走看看