javascript设计模式之迭代器模式
作者:妖怪不慌不张
这篇文章主要为大家介绍了javascript迭代器模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
迭代器模式介绍
- 顺序访问一个集合
顺序:如数组、类数组称为顺序,而非对象,能从0,1,2…通过index访问的值
- 使用者无需知道集合的内部结构
示例
如果要对这三个变量进行遍历,需要写三个遍历方法
<p>each1</p> <p>each2</p> <p>each3</p> ... <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script> <script> var arr = [1,2,3] var nodeList = document.getElementsByTagName('p') var $p = $('p') // 如果要对这三个变量进行遍历,需要写三个遍历方法 // 1 arr.forEach(function(item){ console.log(item) }) // 2 var i;length = nodeList.length for(i = 0;i < length;i ++) { console.log(nodeList(i)) } // 3 $p.each(function(key, p){ console.log(key,p) }) </script>
如果写成一个遍历方法,拿jquery的$.each举例,则这种方法称为迭代器模式
// 如果写成一个遍历方法,拿jquery的$.each举例,则这种方法称为迭代器模式 var arr = [1,2,3] var nodeList = document.getElementsByTagName('p') var $p = $('p') function each(data){ var $data = data $data.each(function(key, val){ console.log(key, val) }) } each(arr) each(nodeList) each($p)
迭代器模式UML类图
UML类图: 用图的方式表示各个类所有的属性及相互之间的引用、继承关系
迭代器模式原生代码演示
class Iterator { constructor(conatiner) { this.list = conatiner.list this.index = 0 } next() { if (this.hasNext()) { return this.list[this.index++] } return null } hasNext() { if (this.index >= this.list.length) { return false } return true } } class Container { constructor(list) { this.list = list } getIterator() { return new Iterator(this) } } // 测试代码 let container = new Container([1, 2, 3, 4, 5]) let iterator = container.getIterator() while(iterator.hasNext()) { console.log(iterator.next()) }
迭代器模式的场景
- jquery each
- ES6 Iterator
ES6 语法中,有序集合的数据类型已经有很多,例如
- Array
- Map
- Set
- String
- Arguments
- NodeList
- 以上数据类型都有[Symbol.iterator]属性,Symbol.iterator理解成唯一的key即可,属性值是一个函数,执行函数返回一个迭代器,这个迭代器就有next方法可顺序迭代子元素
- 通过Array.prototype[Symbol.iterator]来测试迭代器
- object不是有序集合,可以用Map来代替
ES6 Iterator示例
let arr = [1, 2, 3, 4] let nodeList = document.getElementsByTagName('p') let m = new Map() m.set('a', 100) m.set('b', 200) function each(data) { // 生成遍历器 let iterator = data[Symbol.iterator]() let item = {done: false} while (!item.done) { item = iterator.next() if (!item.done) { console.log(item.value) } } } each(arr) each(nodeList) each(m)
由于Symbol.iterator属性并不是人所知,同时并是每次用到它是都需要封装一个each方法,因此有了es6新语法for…of语法,以上代码可以这样写
function each(data) { for (let item of data) { console.log(item) } } each(arr) each(nodeList) each(m)
扩展
ES6 Iterator与Generator Iterator的价值不限于上述的几种类型遍历还有Generator函数的使用即返回的数据只要符合Iterator接口的要求(存在Symbol.iterator属性),就可以使用Iterator语法,即迭代器模式
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!