迭代器模式
1. 介绍
- 顺序访问一个集合
- 使用者无需知道集合的北部结构(封装)
2. UML 演示
3. 代码演示
class Iterator {
constructor(container) {
this.list = container.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)
}
}
//测试
var arr = [1, 2, 3, 4, 5, 6]
let container = new Container(arr)
let iterator = container.getIterator()
while (iterator.hasNext()) {
console.log(iterator.next())
}
4. 场景
4.1 jQuery each
//一个方法遍历三种对象
function each(data) {
var $data = $(data) //生成迭代器
$data.each(function(key, p) {
console.log(key, p)
})
}
//测试
each(arr)
each(nodeList)
each($p)
4.2 ES6 Iterator
-
array
、map
等数据类型都有[Symbol.iterator]
属性 -
属性值是函数,执行函数返回一个迭代器
-
这个迭代器就有
next
方法可顺序迭代子元素 -
可运行
Array.prototype[Symbol.iterator]
来测试function each(data) { //生成遍历器 let iterator = data[Symbol.iterator]() //有数据时返回{value:1,done:false} //console.log(iterator.next()) //console.log(iterator.next()) //console.log(iterator.next()) //console.log(iterator.next()) //没有数据时返回{value: undefined, done: true} //console.log(iterator.next()) //console.log(iterator.next()) //console.log(iterator.next()) let item = { done: false } while (!item.done) { iterator.next() if (!item.done) { console.log(item.value) } } }
//测试 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) { for (let item of data) { console.log(item) } }
4.3 Generator
- 只要返回的数据符合 Iterator 接口的要求即可使用 Iterator 语法
5. 设计原则
- 迭代器对象和目标对象分离
- 迭代器将使用者与目标对象隔离开
- 符合开放封闭原则