JavaScript iterator 设计模式
迭代器模式就是按照顺序访问一个对象中元素,而不用暴露该对象的内部组成。迭代器模式就是将这个迭代实现从业务中分离出来。
但实际开发中我们并不将他当成一个设计模式。
前瞻后顾
说起迭代器,想必对ES6有了解的同学应该不会陌生。我们知道,for ... of
遍历的对象必须是迭代器对象,而普通对象则不能,因为普通对象内部没有实现迭代器,而像数组则内部实现了迭代器,所以可以用for ... of
的语法,而对于一般对象在ES5中有专门的处理方法,for ... in
和
Object.keys()
,而 for ... in
可遍历所有的的对象,但是它遍历特殊对象,如数组,也会遍历它的length,这并不是我们需要的,有时还会出现不按顺序的遍历。
在我们日常使用中一般是将普通对象转化为特殊对象然后处理的。
仿jQuery迭代器
这里我只简单的实现数组的遍历,至于如何迭代普通对象,我们下面再做介绍。
var $ = {each: function (arr, fn) {for (var i = 0, len = arr.length; i < len; i++) {fn.call(arr[i], i, arr[i])}}
};$.each([1, 2, 3, 4, 5, 6], function(i, val) {console.log([i, val]);
});
迭代器的分类
迭代器根据实现的位置,我们将它分为内部迭代器和外部迭代器两种。
内部迭代器
内部迭代器对于使用者来说他不用关心迭代器的内部实现,只用关注使用的效果,我们上面仿jQuery的each就是个内部迭代器的实现。
内部迭代器有它的好处但是也有它的不足,比如我们要比较两个数组是否相等,上面的方法就不满足我们的需要,我们就需要写一个新的方法来实现。
var $ = {each: function (arr, fn) {for (var i = 0, len = arr.length; i < len; i++) {fn.call(arr[i], i, arr[i])}}
};var compareArray = function(arr, arr2) {if( arr.length !== arr2.length) {return false;}$.each(arr, function(i, val) {if( val !== arr2[i]) {return false;}});return true;
};compareArray([1, 2], [1, 2, 3]); // false
外部迭代器
外部迭代器必须显式地请求才会迭代下一个元素。
外部迭代器虽然增加了使用上的一些麻烦,但是它的灵活性却正是我们需要的。我们可以人为的控制迭代的过程和顺序。
// 迭代器实现
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];};var len = function() {return obj.length;}return {next: next,isDone: isDone,getCurrItem: getCurrItem,length: len,}
};
// 比较数组
var compareArray = function (iteratorObj, iteratorObj2) {if(iteratorObj.length !== iteratorObj2.length) {return false;}while (!iteratorObj.isDone() && !iteratorObj2.isDone()){if (iteratorObj.getCurrItem() !== iteratorObj2.getCurrItem()){return false;}iteratorObj.next();iteratorObj2.next();}return true;
};var arr = Iterator([1, 2, 3]);
var arr2 = Iterator([1, 2, 3]); compareArray(arr, arr2); // true
这样我们就用ES5实现了迭代器的功能,ES6的实现迭代器相对简单,如果不熟悉的可以参考一下阮一峰老师的 ES6 使用手册
迭代对象
使用ES6迭代器后发现,for ... of
能够遍历的迭代器对象,如: 数组,类数组,Set,Map,arguments等对象它们有一个共同的特性,就是它们都有一个length数组,可以实现对对象用下标进行访问。
因此,要实现对普通对象的的迭代,我们可以参考jQuery的实现如下做:
var isArraylike = function(obj) {return Object.prototype.toString.call(obj) === [object Array];
}
$ = {each: function(obj, fn) {var isArray = isArraylike(obj); // 判断对象是否为数组if (isArray) {for (var i = 0, len = obj.length ; i < len; i++ ) {if (fn.call(obj[i], i, obj[i]) === false) {break;}}} else {for (i in obj) {if (fn.call(obj[i], i, obj[i]) === false) {break;}}}}
};
我们再使用ES6处理一般对象时一般使用两种方法,一种是将普通对象转化为迭代器对象,另一种就是上面这种写法。
设计模式周周讲
JavaScript iterator 设计模式相关推荐
- 7 种 Javascript 常用设计模式学习笔记
7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...
- Javascript乱弹设计模式系列(1) - 观察者模式(Observer)
前言 博客园谈设计模式的文章很多,我也受益匪浅,包括TerryLee.吕震宇等等的.NET设计模式系列文章,强烈推荐.对于我,擅长于前台代码的开发,对于设计模式也有一定的了解,于是我想结合Javasc ...
- javascript各种设计模式
javascript各种设计模式 设计模式之单例模式 设计模式之构造函数模式 设计模式之建造者模式 设计模式之工厂模式 设计模式之代理模式 设计模式之命令模式 设计模式之原型模式 看了这么多模式之后, ...
- JavaScript常见设计模式
Javascript常⻅设计模式 设计模式总的来说是一个抽象的概念,是软件开发人员在开发过程中面临的一般问题的解决方案.这些解决方案是众多软件开发人员经过相当⻓的一段时间的试验和错误总结出来的. 1 ...
- JavaScript的设计模式
目录 JavaScript中常用的设计模式 1. 单例模式(Singleton pattern) 2. 策略模式(Strategy pattern) 3. 代理模式(Proxy pattern) 4. ...
- visual studio 设计器不显示_设计模式 | Iterator设计模式
适应设计模式 1 1.0 前言 此文是日本作者结城浩著作的<图解设计模式>的译作,原文用java程序编写,对熟练掌握C++.对java不熟悉的读者来说,程序读起来相当费劲.因此本文作者将书 ...
- JavaScript 经典设计模式
文章出自个人博客https://knightyun.github.io/2021/01/17/js-design-pattern,转载请申明 设计模式(Design Pattern)是一套被反复使用的 ...
- Javascript的设计模式之从设计到模式(重要设计模式)
一.五大设计原则 S - 单一职责原则(做好一件事) O - 开放封闭原则(可扩展,不修改) L - 李氏置换原则(子类覆盖父类) I - 接口独立原则(单一独立) D - 依赖倒置原则(依赖抽象) ...
- JavaScript常用设计模式
设计模式 设计模式是一种在长时间的经验与错误中总结出来可服用的解决方案. 设计模式主要分为3类: 创建型设计模式:专注于处理对象的创建 Constructor构造器模式,Factory工厂模式,Sin ...
最新文章
- [转]VC6.0无法打开文件和无法向工程添加文件的解决办法
- html5图片加载不了,webView加载html图片遇到的问题解决
- Lambda表达式练习3【应用】
- linux服务器做页面,linux服务器搭建在线预览环境
- [约瑟夫环]n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始... ...
- VB扫雷游戏的设计与开发
- java。用类描述计算机中CPU的速度和硬盘的容量。要求Java应用程序有4个类,名字分别是PC、CPU、HardDisk和Test,其中Test是主类。
- java课程设计通讯录_java课程设计(通讯录管理软件源代码)
- java for循环的写法_java中for循环的6种写法
- Windows系统封装(四)正式封装和测试。
- 2018阿里巴巴秋招java笔试题做题记录
- 小菜叫你玩破解和逆向(1)
- Desmos-可能是迄今为止最好用的免费Web端数学图像绘制工具
- 多个路由器无线桥接,共享网络
- ABAP调用外部webservice 问题
- 一篇文章教会你使用Python网络爬虫下载酷狗音乐
- 正则表达式前瞻(?=)、后顾(?)、负前缀(?!)、负后顾(?!)
- 用python统计文本里的单词出现次数最多的10个
- Element Tiptap Editor - 免费开源的 Vue 富文本编辑器,专门为搭配 Element UI 使用优化,使用很简单
- 立体声、双声道、单声道的区别