本文共 3164 字,大约阅读时间需要 10 分钟。
顺序访问一个集合(基本为数组形式)
使用者无需知道集合的内部结构(封装)
jquery each
jquery each
jquery each
传统 UML 类图
简化后的 UML 类图
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) }}// 测试let arr = [1,2,3,4,5,6]let container = new Container(arr) // 兼容所有有序的数据类型let iterator = container.getIterator()while(iterator.hasNext()) { console.log(iterator.next())}
// 如何能写出一个方法来遍历这三种对象呢?function each(data) { var $data = $(data) // 生成迭代器 $data.each(function (key, p) { console.log(key, p) })}// 测试代码each(arr)each(nodeList)each($p)
ES6 Iterator 为何存在?
Array Map Set String TypedArray arguments NodeList
统一
的遍历接口来遍历所有数据类型
注意,object 不是有序集合,可以用 Map 代替
)ES6 Iterator 是什么?
[Symbol.iterator]
属性属性值是函数,执行函数返回一个迭代器
next
方法可顺序迭代
子元素Array.prototype[Symbol.iterator]
来测试Array.prototype[Symbol.iterator]f values() { [native code] }Array.prototype[Symbol.iterator]()Array Iterator { }Array.prototype[Symbol.iterator]().next(){ value: undefined, done: true} // done为true就是遍历完了
ES6 Iterator 示例
function each(data) { // 生成遍历器 let iterator = data[Symbol.iterator]() // console.log(iterator.next()) // 有数据时返回 {value: 1, done: false} // console.log(iterator.next()) // 没有数据时返回 {value: undefined, done: true} let item = { done: false} while (!item.done) { item = 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)each(arr)each(nodeList)each(m)
// `Symbol.iterator` 并不是人人都知道// 也不是每个人都需要封装一个 each 方法// 因此有了 `for...of` 语法function each(data) { for (let item of data) { console.log(item) }}each(arr)each(nodeList)each(m)
Generator 函数的使用
只要返回的数据符合 Iterator 接口的要求
可使用 Iterator 语法,这就是迭代器模式
function* helloWorldGenerator() { yield 'hello'; yield 'world'; return 'ending';}var hw = helloWorldGenerator();hw[Symbol.iterator]f [Symbol.iterator]() { [native code] }// 可以看到, Generator 函数返回的结果,也实现了 Iterator 接口
function each(data) { // 生成遍历器 let iterator = data[Symbol.iterator]() // console.log(iterator.next()) // console.log(iterator.next()) // console.log(iterator.next()) // console.log(iterator.next()) let item = { done: false} while(!item.done) { item = iterator.next() if (!item.done) { console.log(item.value) } } // 带有遍历器特性的对象:data[Symbol.iterator] 有值 for (let item of data) { console.log(item) }}let arr = [1,2,3,4]let nodeList = document.getElementsByTagName('p')let m = new Map()m.set('a', 100)m.set('b', 100)each(arr)each(nodeList)each(m)
迭代器对象和目标对象分离
迭代器将使用者与目标对象隔离开
符合开放封闭原则
转载地址:http://rcqwi.baihongyu.com/