学习JavaScript设计模式之迭代器模式

前端技术 2023/09/08 JavaScript
  • 迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。

JavaScript中的Array.prototype.forEach

一、jQuery中的迭代器

$.each([1, 2, 3], function(i, n) {
  console.log(\"当前下标为:\"+ i + \" 当前元素为:\"+ n );
});

二、实现自己的迭代器

var each = function(ary, callback) {
  for(var i = 0, l = ary.length; i < l; i++) {
    callback.call(ary[i], i, ary[i]);
  }  
};
each([1, 2, 3], function(i, n) {
  console.log(\"当前下标为:\"+ i + \" 当前元素为:\"+ n );
});

注意:区别于Array.prototype.forEach的参数!!!

[1, 2, 3].forEach(function(n, i, curAry){
  console.log(\"当前下标为:\"+ i + \" 当前元素为:\"+ n + \" 当前数组为:\" + curAry);
})

三、内部迭代器、外部迭代器

(1)内部迭代器:已经定义好了迭代规则,它完全接手整个迭代过程,外部只需一次初始调用。上述自定义each即为内部迭代器!
(2)外部迭代器:必须显示地请求迭代下一个元素。
示例:判断两个数组是否相等

示例一:内部迭代器

// 内部迭代器
var each = function(ary, callback) {
  for(var i = 0, l = ary.length; i < l; i++) {
    callback.call(ary[i], i, ary[i]);
  }  
};
// 比较函数
var compareAry = function(ary1, ary2) {
  if(ary1.length != ary2.length) {
    throw new Error(\"不相等\"); // return console.log(\"不相等\"); 
  }
  // 且住
  each(ary1, function(i, n) {
    if(n !== ary2[i]) {
      // return console.log(\"不相等\"); 
      // return 只能返回到each方法外,后续console.log(\"相等\")会继续执行,所以这里得使用throw
      throw new Error(\"不相等\");
    }
  });
  console.log(\"相等\");
}

compareAry([1, 2, 3], [1, 2, 4]);

示例二:外部迭代器

// 外部迭代器
var Iterator = function(obj) {
  var current = 0,
    next = function() {
      current++;
    },
    isDone = function() {
      return current >= obj.length;  
    },
    getCurrentItem = function() {
      return obj[current];
    };
  return {
    next: next,
    isDone: isDone,
    getCurrentItem: getCurrentItem
  };
};
// 比较函数
var compareAry = function(iterator1, iterator2) {
  while( !iterator1.isDone() && !iterator2.isDone() ){
    if(iterator1.getCurrentItem() !== iterator2.getCurrentItem()) {
      throw new Error(\"不相等\");
    }
    iterator1.next();
    iterator2.next();
  }
  console.log(\"相等\");
}

compareAry(new Iterator([1, 2, 3]), new Iterator([1, 2, 4]));

四、终止迭代器

var each = function(ary, callback) {
  for(var i = 0, l = ary.length; i < l; i++) {
    if(callback.call(ary[i], i, ary[i]) === false) {
      break;
    }
  }
}

each([1, 2, 4, 1], function(i, n) {
  if(n > 3) {
    return false;
  }
  console.log(n);
});

五、应用(落地)

文件上传,根据不同的浏览器获取相应的上传组件对象。
对比《JavaScript设计模式–责任链模式》

var iteratorUploadObj = function() {
  for(var i = 0, fn; fn = arguments[i]; i++) {
    var uploadObj = fn();
    if(uploadObj !== false) {
      return uploadObj;
    }
  }
};

var uploadObj = iteratorUploadObj(getActiveUploadObj, getFlashUploadObj, getFormUploadObj);

function getActiveUploadObj() {
  try{
    return new ActiveObject(\"TXFTNActiveX.FTNUpload\"); // IE上传控件
  }catch(e) {
    return false;
  }
}

function getFlashUploadObj() {
  if(supportFlash().f === 1) {
    var str = \'<object type=\"application/x-shockwave-flash\"></object>\';
    return $(str).appendTo($(\"body\"));
  }
  return false;
}

function getFormUploadObj() {
  var str = \'<input name=\"file\" type=\"file\" class=\"ui-file\" />\';
  return $(str).appendTo($(\"body\"));
}

// 是否支持flash
function supportFlash() {
  var hasFlash = 0; //是否安装了flash
  var flashVersion = 0; //flash版本
  if (document.all) {
    var swf = new ActiveXObject(\'ShockwaveFlash.ShockwaveFlash\');
    if (swf) {
      hasFlash = 1;
      VSwf = swf.GetVariable(\"$version\");
      flashVersion = parseInt(VSwf.split(\" \")[1].split(\",\")[0]);
    }
  } else {
    if (navigator.plugins && navigator.plugins.length > 0) {
    var swf = navigator.plugins[\"Shockwave Flash\"];
      if (swf) {
        hasFlash = 1;
        var words = swf.description.split(\" \");
        for (var i = 0; i < words.length; ++i) {
          if (isNaN(parseInt(words[i]))) continue;
          flashVersion = parseInt(words[i]);
        }
      }
    }
  }
  return { f: hasFlash, v: flashVersion };
}

希望本文所述对大家学习javascript程序设计有所帮助。

本文地址:https://www.stayed.cn/item/22668

转载请注明出处。

本站部分内容来源于网络,如侵犯到您的权益,请 联系我

我的博客

人生若只如初见,何事秋风悲画扇。