提供一种方法,顺序访问 集合对象 中的 各个元素,而 不暴露 该对象的内部表示;
适用场景:
- 内容保密:访问 集合对象 的内容,无需暴露内部表示;
- 统一接口:为遍历 不同的 集合结构,提供统一接口;
优点:
- 分离了 集合对象 的 遍历行为;
- 抽象出了 迭代器 负责 集合对象 的遍历,可以让外部的代码 透明的 访问集合内部的数据;
缺点:
- 类的个数成对增加;
- 迭代器模式,将 存储数据,遍历数据 两个职责拆分;
- 如果新添加一个 集合类,需要增加该 集合类 对应的 迭代器类,类的个数成对增加,在一定程度上,增加了系统复杂性;
类图
代码
function createIterator(arr) {
let index = 0;
return {
next() {
return index < arr.length ? { value: arr[index++], done: false } : { value: undefined, done: true };
}
}
}
let it = createIterator([1, 2]);
console.log(it.next()); // { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
console.log(it.next()); // { value: undefined, done: true }
经典场景
Iterator
在 ES6 中 有序 集合数据类型有 Array、Map、Set、String、TypedArray(ArrayBuffer、Int32Array、Uint8Array、Int16Array)、arguments、NodeList(childNodes、document.querySelectorAll)
需要有一个统一的遍历接口来遍历所有的数据类型,他们都有 [Symbol.Iterator] 属性,属性是一个函数,执行函数会返回迭代器
迭代器就有 next 方法顺序返回子元素
let arr = [1, 2, 3];
let it = arr[Symbol.iterator]();
console.log(it.next());// { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
console.log(it.next()); // { value: 3, done: false }
console.log(it.next()); // { value: undefined, done: true }
let map = new Map([
['name', 'ws'],
['age', '28']
]);
let it = map[Symbol.iterator]();
console.log(it.next()); // { value: [ 'name', 'ws' ], done: false }
console.log(it.next()); // { value: [ 'age', '28' ], done: false }
console.log(it.next()); // { value: undefined, done: true }
let set = new Set([1, 2, 3]);
let it = set[Symbol.iterator]();
console.log(it.next());// { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
console.log(it.next()); // { value: 3, done: false }
console.log(it.next()); // { value: undefined, done: true }
let str = '123';
let it = str[Symbol.iterator]();
console.log(it.next());// { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
console.log(it.next()); // { value: 3, done: false }
console.log(it.next()); // { value: undefined, done: true }
const fn = function (a, b, c) {
let it = arguments[Symbol.iterator]();
console.log(it.next()); // { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
console.log(it.next()); // { value: 3, done: false }
console.log(it.next()); // { value: undefined, done: true }
}
fn(1, 2, 3);
yield*
let generator = function* () {
yield 1;
yield* [2, 3, 4]; // yield* 后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口
yield 5;
};
var iterator = generator();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: 4, done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
观察者模式
上一篇